Pod 里面可以有一个或者多个容器,部署应用的容器可以称为主容器,在创建Pod时候,Pod 中可以有一个或多个先于主容器启动的Init容器,这个
init容器就可以成为初始化容器,初始化容器一旦执行完,它从启动开始到初始化代码执行完就退出了,它不会一直存在,所以在主容器启动之前执行
初始化,初始化容器可以有多个,多个初始化容器是要串行执行的,先执行初始化容器1,在执行初始化容器2等,等初始化容器执行完初始化就退出了
,然后再执行主容器,主容器一退出,pod就结束了,主容器退出的时间点就是pod的结束点,它俩时间轴是一致的;
Init容器就是做初始化工作的容器。可以有一个或多个,如果多个按照定义的顺序依次执行,只有所有的初始化容器执行完后,主容器才启动。由于一
个Pod里的存储卷是共享的,所以Init Container里产生的数据可以被主容器使用到,Init Container可以在多种K8S资源里被使用到,如
Deployment、DaemonSet, StatefulSet、Job等,但都是在Pod启动时,在主容器启动前执行,做初始化工作。
Init容器与普通的容器区别是:
1、Init 容器不支持 Readiness,因为它们必须在Pod就绪之前运行完成
2、每个Init容器必须运行成功,下一个才能够运行
3、如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止,然而,如果Pod对应的restartPolicy值为Never,它不会重新启动。
[root@k8s01 test1]# cat init.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
imagePullPolicy: IfNotPresent
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
imagePullPolicy: IfNotPresent
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
kubectl apply -f init.yaml
[root@k8s01 test1]# kubectl get pods
NAME READY STATUS RESTARTS AGE
app-pod 0/1 Init:0/2 0 6s
[root@k8s01 test1]# cat service.yaml
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
kubectl apply -f service.yaml
[root@k8s01 test1]# kubectl get pods
NAME READY STATUS RESTARTS AGE
app-pod 0/1 PodInitializing 0 73s
[root@k8s01 test1]# kubectl get pods
NAME READY STATUS RESTARTS AGE
app-pod 1/1 Running 0 75s