我们有很多不同的方法来配置在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。 在这种情况下,它们将按顺序执行。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
apiVersion: v1 kind: Pod metadata: name: pod spec: initContainers: - name: first image: busybox command: ['sh', '-c', 'echo init One'] - name: second image: busybox command: ['sh', '-c', 'echo init Two'] containers: - name: container image: busybox command: ['sh', '-c', 'echo container'] |
initContainer的示例用例包括:
将服务的外部URL注册到第三方服务器
使用Git存储库初始化共享卷
从第三方提供程序获取数据以在运行时创建动态配置文件
混合并匹配上述内容,以便从Git存储库获得动态配置
使用运行时相关性初始化共享卷(请参阅应用于Docker的继承结构)
等等
本质上,initContainer允许在运行时自定义不可变镜像的执行。
例如,这是YAML,用于通过Git存储库初始化共享卷:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
apiVersion: v1 kind: ConfigMap metadata: name: cfg data: version: v1.0.0 --- apiVersion: apps/v1 kind: Pod metadata: name: pod spec: volumes: - name: config-volume emptyDir: {} initContainers: - name: clone image: alpine/git:1.0.4 volumeMounts: - name: config-volume mountPath: /config envFrom: - configMapRef: name: cfg command: ['/bin/sh', '-c'] args: ['git clone --branch $(version) https://github.com/ajavageek/foo-config && mv foo-config/* /config'] containers: - name: foo image: ajavageek/foo:1.0 volumeMounts: - name: config-volume mountPath: /config readOnly: true |
创建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/