前言

环境: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命令进入初始化容器。