控制 Pod 内容器的启动顺序

用户头像
张晓辉
关注
发布于: 2020 年 05 月 28 日
控制 Pod 内容器的启动顺序

背景



众所周知, Kubernetes Pod 内有两种容器: 初始化容器(init container)和应用容器(app container). 其中初始化容器的执行先于应用容器, 并且初始化容器和应用容器的个数分别为 0~n 和 1~n.



初始化容器会按照顺序执行, 顺序执行的前提是初始化容器始终会运行到完成(completed)状态. 而应用容器恰好相反: 启动顺序随机, 并始终保持运行(running)状态.



问题



工作中有个架构的方案使用到了 sidecar 容器: 将基础组件功能从容器转移到 sidecar 容器中, 其中有个功能是从远程配置中心获取配置并保持实时更新. 保证实时更新没有问题, 但是配置文件需要在 app 启动之前完成初始化.



对于同为"应用容器"类型的 sidecar 容器来说, 由于容器启动顺序随机而无法做到这一点.



当时我们给定的方案是增加一个初始化容器进行配置的初始化, 不可避免的我们需要增加一个额外的容器, 即使是这个容器的生命周期非常短.



追求极致的我们总是对这个额外增加的容器耿耿于怀: 假如能控制应用容器的启动顺序…



新发现



近期在研究 CDF (Continuous Delivery Foundation)下的 Tekton, 其中有个概念是其将流水线(pipeline)中的各个步骤(step)作为应用容器在同一个 Pod 中运行.



我们都知道流水线中的步骤是按照定义的顺序执行的, 那么 Tekton 是如何保证应用容器的执行顺序的?



查看 pod 的 manifest 之后发现了下面的容器配置 (这个容器的作用从 git 仓库克隆代码)



spec:
containers:
- args:
- -wait_file
- /tekton/downward/ready
- -wait_file_content
- -post_file
- /tekton/tools/0
- -termination_path
- /tekton/termination
- -entrypoint
- /ko-app/git-init
- --
- -url
- http://gitlab.nip.io:8088/addozhang/tekton-test
- -revision
- develop
- -path
- /workspace/git-source
command:
- /tekton/tools/entrypoint


克隆代码的命令是:



git-init -url http://gitlab.nip.io:8088/addozhang/tekton-test -revision develop -path /workspace/git-source

但是容器的启动命令是/tekton/tools/entrypoint并带上了一坨的参数(此处略过, 后面分析).



翻看了下文档:



This binary is used to override the entrypoint of a container by wrapping it. In tektoncd/pipeline this is used to make sure Task’s steps are executed in order, or for sidecars.

这个二进制文件被用于通过包装的方式来覆盖容器的入口点. 在 tektoncd/pipeline 中确保任务中的步骤或者 sidecar 被顺序地执行.

  • -entrypoint: 原始的容器启动命令, 作为 entrypoint 的子进程运行. 即上面的 git-init XXXX

  • -post_file: 子进程运行结束后写的文件路径(即上面的/tekton/tools/0). 如果子进程执行失败, 则写一个{{post_file}}.err文件, 而不是{{post_file}}

  • -wait_file: 启动子进程监控的文件路径(即上面的/tekton/downward/ready). 通过监控到的{{watch_file}}或者{{watch_file}}.err文件来决定执行子进程, 还是跳过执行然后写入{{post_file}}.err文件并返回错误码(exitCode >= 0)

  • -wait_file_content: 等待wait_file有实际内容写入, 持续监控wait_file直到有内容写入.



回头看上面容器配置:



  1. 容器的entrypoint启动进程

  2. 监控到/tekton/downward/ready文件的创建, 并等待文件内容的写入

  3. 执行git-init子进程, 从 git 仓库克隆源码

  4. 创建/tekton/tools/0文件



实际应用



这个方案是否能解决我们的问题, 还是有一定的局限性的.



首先需要应用容器的启动命令进行重新的编排, 这个存在一定的挑战. 需要统一应用的启动命令才能做到规模化+自动化.



其次引入可用于监控的文件, 需要额外增加Volume用于跨容器的文件访问. 当然通过增加emptyDirVolume即可.



同时 sidecar 容器需要在完成启动后创建post_file, 应用容器可以使用这个entrypoint进行包装.



如果要突破这个局限, CRD 无非是个优秀的方案. 下一篇, 我们通过一个简单的 CRD 来实现.



发布于: 2020 年 05 月 28 日 阅读数: 81
用户头像

张晓辉

关注

大胆尝试,小心求证 2018.04.09 加入

胡说八道

评论

发布
暂无评论
控制 Pod 内容器的启动顺序