如何在 K8S 的 Pod 内连续执行 Container?这种方法别错过

出于某些目的,有时需要在 Kubernetes 的一个 Pod 中,连续一次运行多个 Container。这种游戏有明确结束预期的运行,即 Kubernetes 的 Job。但是,虽然一个 Job 可以在一个 Pod 内运行多个 Container,然而运行方式是并发的。

一种方法是在业务层处理。比如,通过***享的本地 Volume,使用文件锁的机制,可以实现多个并发的 Container 依次执行。但这需要在业务逻辑中,把并发强行改为同步,增加了开发复杂度。如果能使用 Kubernetes 本身的机制实现,则减免了很大的开发工作量。

以下是另外的三种方案。

经过调查发现,虽然 containers 不能依次运行,但是可以 initContainers 可以。它是在 containers 运行前,执行的初始化操作,依次结束运行并且无异常后,正式的 containers 才会运行。利用这一点,可以实现多个任务的依次执行,把前面的任务写到 initContainers 、最后一个任务写到 containers 即可。

以下为三个 Containter 依次执行的样例。

运行完毕后,日志如下:

Volcano前身是kube-batch,声称在调度和管理方面,对原生Job进行了优化。但是在核心逻辑上,还是一样的,不能支持指定 Container 顺序执行。

状态转移图如下:

stateDiagram [ ] → Pending Pending → Aborted Pending → Running Aborted → Pending Running → Aborted Running → Completed Running → Terminated Completed → [ *** ] Terminated → []

在实际测试中,暂时没有发现在当前业务场景下,比原生Job有什么优势。以下是实测配置。

上面与原生相比,虽然多了 tasks 这是一层概念,但是在功能上并无帮助。

运行完毕后,日志如下:

另外,Volcano 文档缺失严重,与 kube-batch 也不兼容。目前看来有很多不清楚的问题。

argo是更合适按顺序、依赖关系执行的。但是经评估,它有一个重大缺陷,不适合当前场景。

argo的每个Task都是独立的Pod,不同Pod未必在同一台机器上。而Volume则必须使用NFS之类的网络存储位置,性能不符合某些需要密集本地IO的场景。

argo 是形式上最合适的,可以避免使用 initContainers 这种邪道。但是独立 Pod 因为问题导致它不适合这个场景。

目前看来,原生的 Job 最合适。

选用Volcano还需要更深入的了解。