上一节我们成功创建了自己的第一个pod,但是这背后到底发生了什么,又有什么可以被我们自定义的还不知道。这一节我们一起来看看一个容器从被创建到被销毁经历的生命周期,并详细学习下其中的初始化过程:Init阶段。
我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。
文章目录
容器的生命周期
下面这个图很好的说明了在敲完命令kubectl apply -f pod.yaml
之后经历的过程
- 首先kubectl和api server交互,然后到etcd,再到对应node的kubelet
- 然后kubelet和node上的CRI,也就是docker交互,开始图中得初始化流程
- 首先创建好pod内容器公用得pause网络栈,然后进行一系列得Init C流程
- 初始化工作完成后每个容器都会有自己的start初始化脚本要跑
- 可以设定一个探针,在初始化脚本一段时间后检测容器是否可提供服务,如果可以提供服务显示为running状态。也就是上面得readiness状态
- 同时还有另一个探针,不停检测容器是否有异常,并根据restartPolicy决定是否要重启。也就是上面得Liveness状态
- 最后在销毁容器之前,还可以运行一段结尾的stop脚本
下面我们就用实例对这些流程一个个的深入了解一下。这一节先看看第一个步骤Init C。
Init C
Init C是专门用作初始化的容器,其具有如下两个特点:
- Init容器总是运行到成功退出为止,如果Init容器失败,k8s会不停重启该Pod,直到成功为止
- 每个Init容器必须在上一个Init容器成功完成后才能运行
注意,如果restartPolicy是never的话,Init容器失败不会重新启动。
因为Init是区别于业务容器的单独容器,所以其可以完成如下工作:
- 可以安装某些可以被业务容器使用的工具,这些工具如果封装在业务镜像中会增加业务镜像的冗余
- 对业务容器的代码进行分离为创建和部署两阶段,将创建阶段放入Init容器中
- Init容器属于Linux命名空间,相对业务容器具有更高的文件系统权限,例如Secret权限。敏感文件处理在Init阶段完成使得业务容器安全性更高
- 针对某些有严重顺序依赖的两个Pod来说,可以再需要后启动的Pod的Init中去做判断,一直等到先启动的Pod成功完成,再退出Init,启动后一个Pod
说了这么多,下面来实际上手操作看看。
Init容器实际操作
下面所有操作的源码都被托管在github:
https://github.com/Victor2Code/centos-k8s-init/tree/master/test%20yaml/Pod%20Lifecycle%20-%20Init
下面创建一个带Init容器的yaml配置文件test-init-main.yaml
如下
apiVersion: v1
kind: Pod
metadata:
name: test-init-main
labels:
app: myapp
version: v1