上次说了容器健康检查的两个探针:liveness probe(存活探针)和 readiness probe(可读性探针)这2个探针可以影响到容器的生命周期的,包括之前的钩子函数postStar和preStop。今天说说初始化容器init container。
在kubernetes中,一个pod可以包含多个容器,其中的init container,顾名思义主要负责初始化工作,一个pod也可以包含多个init container。后文统一用【初始化容器】表示 【init container】。初始化容器也是容器,在pod的定义中,如果将【containers】改成【initContainers】,那么这个数组内定义的所有容器就都是初始化容器,定义初始化容器与普通应用容器的语法相同。但是,初始化容器不支持readiness类型探针,这个很容易理解,初始化容器主要负责初始化工作,在它没有运行完成之前pod一定处于未就绪状态(unready),所以readiness类型探针一定会诊断失败,没有意义。一个Pod里面的所有容器是共享数据卷和网络命名空间的,所以Init Container里面产生的数据可以被主容器使用到的。
下图就是pod的生命周期,main是主容器,主容器中有2个钩子函数 post start和pre stop,2个探针liveness 和readiness。init container是独立在主容器之外的。init container也是属于pod范畴之内的。通过这个图很明白的看出来钩子 和 init container的区别。infra容器,又叫Pause容器,在集群环境中去查看下任意一个Pod对应的运行的Docker容器,每一个Pod下面都包含了一个pause-amd64的镜像,这个就是infra镜像,Pod下面的所有容器是共享同一个网络命名空间的,这个镜像就是来做这个事情的,所以每一个Pod当中都会包含一个这个镜像。infra容器就是做共享网络的。
1.刚开始就是初始化容器,可能有多个。2.进入主容器,主容器内部第一个先执行的就是post start hook。3.容器执行的过程中,有些健康检查通过 livenessprobe 和 readiness probe 探针。4.容器结束去调用 pre stop hook
init container主要是做初始化工作的,主要的应用场景是等待其他模块的准备,解决服务之间的依赖问题。例如:main container是个web服务,它必须依赖数据库服务,如果数据库还在服务还没启动,就导致web服务有一段时间连接数据库报错。所以我们就可以在pod(init container)的时候,检测数据库是否准备好,数据库检测正常就退出(init container)。 init container 准备好节点为主服务(main container)提供配置信息。布置场地的作用。
创建一个pod,里面通过命令判断myservice服务 和 mydb 服务是否存在检测,检测没有问题,就main-container的pod就可以启动了。
apiVersion: v1
kind: Pod
metadata:
name: main-pod1
labels:
app: init
spec:
containers:
- name: main-container
image: busybox
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
- name: init-mydb
image: busybox
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
vi init-pod.yaml
#添加上边的脚本
kubectl apply -y init-pod.yaml
init:0/2的初始化需要初始化2个容器。
查看带初始化容器的pod的详情,main-container里面还在waiting
kubectl describe pod main-pod1
通过yaml的方式启动myservice服务 和 mydb 服务,然后查看main-pod1的状态
vi service-svc.yaml
kind: Service
apiVersion: v1
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 6376
---
kind: Service
apiVersion: v1
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 6377
查看带初始化容器的pod的详情
kubectl get pod
kubectl describe pod main-pod1
跟上边的最初的init 0:2已经完全不一样了。
通过初始化容器下载某个html到volumes上,然后在将volumes中的html挂载到主容器上。
vi init-config.yaml
apiVersion: v1
kind: Pod
metadata:
name: init-demo
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: workdir
mountPath: /usr/share/nginx/html
initContainers:
- name: install
image: busybox
command:
- wget
- "-O"
- "/work-dir/index.html"
- http://www.idig8.com
volumeMounts:
- name: workdir
mountPath: "/work-dir"
volumes:
- name: workdir
emptyDir: {}
编译 yaml
kubectl apply -f init-config.yaml
进入容器查看是否是init下载的html
kubectl exec -it init-demo -- /bin/bash
# 进入容器
cd /usr/share/nginx/html
cat html
kubectl logs POD名称 -c 依赖的init-container
kubectl logs main-pod1 -c init-myservice
PS:这次说了pod的生命周期,初始化容器讲了服务依赖和配置文件初始化,下次说说常用的控制器的使用方法。