有许多不同的方法来配置在Kubernetes上运行的容器:
- 环境变量
- 配置图
- 跨多个Pod共享的卷
- 参数已传递给预定的广告连播
- 等等
这些替代方案符合特定的环境和特定的要求。
例如,它们都不允许您在容器启动之前克隆Git存储库。 可以将特征设计到图像本身中。 但是,这将引入耦合,并破坏单一责任原则 。 即使此原则最初来自OOP ,对于容器也很有意义。 图像应该只做一件事,并且做得很好。 就像在OOP中一样,相反的情况会引入复杂性和脆弱性,并影响图像的可维护性。
实际运行命令的其他选项包括:
-
容器生命周期钩
-
Kubernetes提供了生命周期挂钩和回调,这些回调允许在Pod初始化(和销毁)期间执行代码。 这种方法的主要问题是钩子和吊舱都并行启动:吊舱启动时启动吊钩可能不会完成,从而使吊舱处于未知状态。
乔布斯和CronJobs
-
Kubernetes允许运行“批处理”容器的映像。 与本应与之交互的应用程序(例如webapps)相反,批处理容器无需手动输入即可运行完毕。 -批次的可以只运行一次
Job
,或定期-CronJob
。可以设计一个具有工作窗格和常规窗格的架构,并通过共享卷进行交互。 不幸的是,两个吊舱将同时启动。 与前面的情况一样,不能保证在应用程序启动之前作业将完成。
但是,有一个功能可以确保在pod启动之前将成功执行命令initContainer
:
初始化容器的行为类似于常规容器,除了:
- 他们总是会完成。
- 每一个都必须成功完成,然后才能开始下一个。
https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
按照合同,init容器命令需要在Pod甚至可以启动之前成功执行。 如果命令失败,则将重新启动pod-并重新执行命令,以便容器在初始化后可以100%依赖状态。 可以在容器上定义多个initContainer
。 在这种情况下,它们将按顺序执行。
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
允许在运行时自定义不可变图像的执行 。
例如,以下是用于从Git存储库初始化共享卷的YAML:
apiVersion:v1
kind:ConfigMap (1)
metadata:
name:cfg
data:
version:v1.0.0
---
apiVersion:apps/v1
kind:Pod
metadata:
name:pod
spec:
volumes:
-name:config-volume (2)
emptyDir:{}
initContainers:
-name:clone
image:alpine/git:1.0.4 (3)
volumeMounts:
-name:config-volume
mountPath:/config (4)
envFrom:
-configMapRef:
name:cfg (5)
command:['/bin/sh','-c'] (6)
args:['git clone --branch $(version) https://github.com/ajavageek/foo-config && mv foo-config/* /config']
containers:
-name:foo
image:ajavageek/foo:1.0 (7)
volumeMounts:
-name:config-volume
mountPath:/config (8)
readOnly:true
- 使用密钥
version
和值v1.0.0
创建名为cfg
的配置映射 - 创建一个名为
config-volume
的空config-volume
- 引用
alpine/git:1.0.4
容器作为init容器 - 将共享卷的
/config
文件夹挂载到此init容器中 - 引用配置映射以获取
version
值 - 克隆
ajavageek/foo-config
Git存储库(不要打扰,它不存在),然后将存储库内容复制到/config
文件夹中的共享卷中。 该命令将重复执行,直到成功执行为止。 - 引用
ajavageek/foo:1.0
容器作为标准容器 - 将共享卷的
/config
文件夹安装到此标准容器中。 根据合同,它可以依赖/config
文件夹来包含所需的数据。
初始化容器的功能对于在Kubernetes容器中运行初始化代码非常有用:它应该成为每个人的知识手册的一部分。
翻译自: https://blog.frankel.ch/versatility-kubernetes-initcontainer/