1.执行顺序机制
Init Container是串行执行的。每个Init Container必须在前一个成功完成后才能启动,而普通容器是并行启动的。这种机制在处理复杂依赖时特别有用。
看个例子:一个需要等待Redis就绪的Web应用。
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
initContainers:
- name: wait-redis
image: redis:alpine
command: ['sh', '-c', 'until redis-cli -h redis-svc ping; do sleep 2; done;']
containers:
- name: web
image: nginx:alpine
2. 运行特性
Init Container只运行一次。完成任务就退出,不会重启。普通容器则会一直运行,必要时还会按策略重启。
有个坑要注意:Init Container执行失败会导致Pod重启,已完成的Init Container也会重新执行。所以写代码时要考虑重复执行的情况。
3. 资源分配策略
Init Container的资源分配有个特殊规则:取所有Init Container中的最大值。
spec:
initContainers:
- name: init-cache
resources:
requests:
memory: "512Mi"
- name: init-db
resources:
requests:
memory: "256Mi"
这个配置中,Pod实际申请的内存是512Mi,而不是两个容器的总和。
4. 应用场景
实战中,Init Container主要用在这些地方:
- 前置准备 配置文件生成、数据库初始化、目录权限设置
- 服务检查 确认依赖服务是否就绪,比如数据库连接性检查
- 安全配置 证书分发、密钥初始化
5. 实战经验
- 保持专注:一个Init Container只做一件事
- 要可重试:设计时考虑重复执行的情况
- 加超时限制:防止无限等待卡住整个Pod
- 资源预留:按实际需求设置,避免资源不足
说个实战案例:部署ElasticSearch集群时,需要修改系统参数max_map_count。用Init Container来处理就很优雅:
initContainers:
- name: sysctl
image: busybox
command: ["sysctl", "-w", "vm.max_map_count=262144"]
securityContext:
privileged: true