Init Container
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Init Container相关的知识,希望对你有一定的参考价值。
Init Container的应用场景
当我们在运用一个服务之前,通常会做一些初始化的工作,而这些工作一般只需要运行一次,成功后就不再运行。为此kubernetes 引入了Init Container,用于在启动应用容器之前启动一个或多个“初始化”容器,完成应用容器的所需的预制条件。
Init Containers与常规的容器非常类似,但是它一些独有的特征:
- 他们仅运行一次,成功后就会退出。
- 每个容器必须在成功执行完成后,系统才能继续执行下一个容器。
- 如果Init Container运行失败,kubernetes 将会重复重启Pod,直到Init Container 成功运行,但是如果 Pod的重启策略(restartPolicy)设置为Never,则Pod不会重启。
- Init Container支持普通应用Container的所有参数,包括资源限制,挂载卷,安全设置等。但是Init Container 在资源的申请和限制上略有不同,同时,由于Init Container必须在Pod ready之前完成并退出,所以它不支持 readiness 探针。
Init Container 通常有如下应用方式:
- 处于安全的考虑,可以将自定义的代码和工具使用Init Container运行,而不必添加到 应用 容器的镜像中。
- 应用程序映像的构建和部署者角色可以彼此独立,无需共同构建单个应用程序映像
- 使用不同的Linux命名空间,可以使它们具有来自应用容器的不同文件系统权限。 因此,Init Container可以获得应用程序容器无法访问的Secrets。
- Init Container在任何应用程序容器启动之前运行完毕,而应用程序容器通常是并行运行的,因此初始容器提供了一种简单的方法来阻止或延迟应用程序容器的启动,直到满足一些前提条件。
具体的应用场景示例:
- 如使用shell 命令,等待服务被创建:for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
- 如使用downward API将自身Pod信息注册到远程服务器上:curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d ‘instance=$()&ip=$()’
- 在启动应用之前,等待一段时间:sleep 60
- 从git仓库拉取配置或代码到指定的挂载卷中
- 使用模板工具动态的生成配置,并给配置文件添加合适的参数。如使用Jinja模板将POD IP添加到应用容器的配置中。
定义Init Container
这里定义一个nginx,在nginx容器启动前更改默认起始页面内容:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
initContainers:
- name: init-myservice
image: busybox
command: [‘sh‘, ‘-c‘, ‘echo "this init-container test page" > /html/index.html‘]
volumeMounts:
- name: index-dir
mountPath: "/html"
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: index-dir
mountPath: /usr/share/nginx/html
volumes:
- name: index-dir
emptyDir: {}
创建容器后,可以看到,先执行初始化操作:
# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/1 0 12s
# 显示正在初始化:
# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 PodInitializing 0 22s
# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
myapp-pod 1/1 Running 0 38s 10.2.74.5 10.0.0.3
#日志信息:
# kubectl describe pod
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 29s default-scheduler Successfully assigned myapp-pod to 10.0.0.3
Normal SuccessfulMountVolume 29s kubelet, 10.0.0.3 MountVolume.SetUp succeeded for volume "index-dir"
Normal SuccessfulMountVolume 29s kubelet, 10.0.0.3 MountVolume.SetUp succeeded for volume "default-token-hmvnc"
Normal Pulling 28s kubelet, 10.0.0.3 pulling image "busybox"
Normal Pulled 16s kubelet, 10.0.0.3 Successfully pulled image "busybox"
Normal Created 16s kubelet, 10.0.0.3 Created container
Normal Started 16s kubelet, 10.0.0.3 Started container
Normal Pulling 15s kubelet, 10.0.0.3 pulling image "nginx"
Normal Pulled 1s kubelet, 10.0.0.3 Successfully pulled image "nginx"
Normal Created 1s kubelet, 10.0.0.3 Created container
Normal Started 1s kubelet, 10.0.0.3 Started container
注意事项
Pod中的每个应用程序和Init Container的名称必须是唯一的; 任何Container与另一个Container共享一个名称都会引发验证错误。
在Pod重新启动时, init Container 将会重新运行,那么所执行的初始化操作也会再次执行,这就要求Init Container的操作是可以重复执行的。例如上面的示例中,在对挂载目录中文件的添加前,可以先判断文件是否已经存在的处理,来防止出错。
常见的Pod重启场景如下:
- init container的镜像被更新时, init Container将会重新运行,导致Pod重启。仅更新应用容器的镜像,只会使得应用容器被重启。
- Pod的 pause镜像更新时, Pod将会重启。
- 若Pod 中的所有应用容器都终止了,并且restartPolicy=always, 则Pod将会重启。
以上是关于Init Container的主要内容,如果未能解决你的问题,请参考以下文章