Kubernetes的initContainer的多功能性

我们有很多不同的方法来配置在Kubernetes上运行的容器,例如:

环境变量
Config maps
跨多个Pod共享的卷
参数已传递给预执行pod
等等
这些替代方案符合特定的环境和特定的要求。

例如,它们都不允许您在容器启动之前克隆Git存储库。但是可能在镜像内部改变一些特征。但是,这将引入耦合,并破坏单一责任原则。即使该原理最初来自OOP,对于容器也很有意义。镜像应该只做一件事,并且做得很好。就像在OOP中一样,相反的情况会引入复杂性和脆弱性,并影响镜像的可维护性。

实际运行命令的其他选项包括:

容器生命周期钩
Kubernetes提供了生命周期钩子,回调函数,它们允许在Pod初始化(和销毁)期间执行代码。这种方法的主要问题是钩子和Pod都是并行启动的:当Pod启动时,启动钩可能不会完成,从而使后者处于未知状态。

Jobs and CronJobs
Kubernetes允许运行“批处理”容器的镜像。与本应与之交互的应用程序(例如webapps)相反,批处理容器无需手动输入即可运行完毕。批处理只能运行一次-Job,也可以定期运行-CronJob。

可以设计一个具有工作窗格和常规窗格的架构,并通过共享卷进行交互。不幸的是,两个pods将同时启动。与前面的情况一样,不能保证在启动应用程序之前完成工作。

但是,有一个功能可以确保在Pod启动之前可以成功执行命令-initContainer:

init容器命令需要在Pod甚至可以启动之前成功执行。 如果命令失败,则将重新启动pod-并重新执行命令,以便容器在初始化后可以100%依赖状态。 可以在容器上定义多个initContainer。 在这种情况下,它们将按顺序执行。

initContainer的示例用例包括:

将服务的外部URL注册到第三方服务器
使用Git存储库初始化共享卷
从第三方提供程序获取数据以在运行时创建动态配置文件
混合并匹配上述内容,以便从Git存储库获得动态配置
使用运行时相关性初始化共享卷(请参阅应用于Docker的继承结构)
等等
本质上,initContainer允许在运行时自定义不可变镜像的执行。

例如,这是YAML,用于通过Git存储库初始化共享卷:

创建configmap命名为cfg,key:version ,value:v1.0.0

建一个名为config-volume的空卷
引用alpine / git:1.0.4容器作为init容器
将共享卷的/ config文件夹挂载到此init容器中
引用配置映射以获取版本值
克隆ajavageek / foo-config Git存储库,然后将存储库内容复制到/ config文件夹中的共享卷中。 该命令将重复执行,直到成功执行为止。
引用ajavageek / foo:1.0容器作为标准容器
将共享卷的/ config文件夹安装到此标准容器中。 根据合同,它可以依赖/ config文件夹来包含所需的数据。
初始化容器的功能对于在Kubernetes窗格中运行初始化代码非常有用:它应该成为每个人的知识手册的一部分。

原文:https://blog.frankel.ch/versatility-kubernetes-initcontainer/