前言
环境:centos7.9 docker-ce-20.10.9 kubernetes-version v1.22.6
什么是pod的初始化容器
在pod中,为了能实现在业务容器启动之间做一些检查,k8s 提供了一种叫做初始化容器的机制来实现。
初始化容器是在pod的业务容器启动之前要运行的容器,主要是做一些业务容器的前置工作,它具有两大特征:
1、初始化容器必须运行完成直至结束,若某初始化容器运行失败,那么kubernetes需要重启它直到成功完成;
2、初始化容器必须按照定义的顺序执行,当且仅当前一个初始化容器成功之后,后面的一个初始化容器才能运行;
初始化容器有很多的应用场景,下面列出的是最常见的几个:
1、提供业务容器镜像中不具备的工具程序或自定义代码;
2、初始化容器要先于应用容器串行启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足,比如nginx容器,要求redis、mysql等容器先启动后才能启动nginx容器,这时候就需要做两个初始化容器探测mysql、redis容器是否在运行。
初始化容器案例
模拟下面这个需求来讲解初始化容器的使用:
假设以业务容器来运行nginx,但是要求在运行nginx之前先要能够连接上mysql和redis服务器
为了简化测试,模拟定义2个初始化容器,这2个初始容器主要做的事就是ping mysql服务器的ip地址192.168.118.100和redis服务器的IP地址192.168.118.101
。(这两个ip地址是不存在的)
创建pod-initcontainer.yaml,内容如下:
cat >> pod-initContainer.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: pod-initcontainer
labels:
env: dev
namespace: default
spec:
containers:
- image: nginx:1.7.9
name: nginx-container
ports:
- name: nginx-port
containerPort: 80
initContainers: #创建了2个初始化容器,这2个初始化容器所做的事就是ping mysql和redis数据库服务器的ip地址
- name: test-mysql
image: busybox:latest
command: ['sh', '-c', 'until ping 192.168.118.100 -c 1 ; do echo waiting for mysql...; sleep 2; done;']
- name: test-redis
image: busybox:latest
command: ['sh', '-c', 'until ping 192.168.118.101 -c 1 ; do echo waiting for reids...; sleep 2; done;']
EOF
#由于这两个ip地址是不存在的,所以我们看到pod的状态一致处于Init状态
[root@master ~]# kubectl get pod pod-initcontainer -n default
NAME READY STATUS RESTARTS AGE
pod-initcontainer 0/1 Init:0/2 0 47s
#下面我们使用-w参数持续追踪pod的变化
[root@master ~]# kubectl get pod pod-initcontainer -n default -w
#然后我们再开一个虚拟机,为虚拟机添加mysql和redis的ip地址,继续观察pod的状态变化
[root@mysql ~]# ifconfig ens33:1 192.168.118.100 netmask 255.255.255.0 up #模拟添加mysql的ip,让pod的初始化容器ping的通
[root@mysql ~]# ifconfig ens33:1 192.168.118.101 netmask 255.255.255.0 up #模拟添加redis的ip,让pod的初始化容器ping的通
[root@master ~]# kubectl get pod pod-initcontainer -n default -w
NAME READY STATUS RESTARTS AGE
pod-initcontainer 0/1 Init:0/2 0 47s
pod-initcontainer 0/1 Init:1/2 0 9m55s
pod-initcontainer 0/1 Init:1/2 0 10m
pod-initcontainer 0/1 PodInitializing 0 10m
pod-initcontainer 1/1 Running 0 10m
#由此,我们发现,pod的状态从最初的Init:0/2-->Init:1/2-->PodInitializing-->Running,说明,如果定义了初始化容器,那么初始化容器必须按照定义的顺序串形执行,当且仅当前一个初始化容器成功之后,后面的一个初始化容器才能运行,当全部的初始后容器都执行成功后,业务容器才真正开始运行。
#注意:初始化容器并不是真正意义上的业务容器,所以无法通过kubectl exec命令进入初始化容器。