Pod对象的生命周期
Pod对象自从其创建开始到期终止退出的时间范围称其为生命周期。这个过程中Pod对象会处于多种不同的状态,并执行一些操作。其中创建主容器为必需操作,其他可选操作包括初始化容器、容器启动后钩子、容器的存活性探测、就绪性探测。以及容器终止前钩子等。
Pod的相位(状态?
无论以何种方式创建的Pod对象。总是处于其生命进程中,以下几个相位。
- Pending:API Server已经创建了资源对象并存入etcd中,但尚未被调度完成或仍处于镜像下载过程中。
- Running:Pod已经被调度至某个节点,并且所有容器已经被Kubelet创建完成。
- Succeed:Pod中的所有容器已经成功终止,并且不会被重启。
- Failed:所有容器都已经终止,但至少有一个容器终止失败。及容器返回了非零值的退出状态,或已经被系统终止。
- Unknown:无法获取到对象的状态信息,通常是由于通讯问题造成的。即API Server无法与工作节点的Kubelet通信。
Pod的创建过程
- 用户通过Kubelet或者其他API客户端提交Pod spec给API Server
- API Serve尝试将对象的相关信息存入etcd中,执行完成即会返回相关信息
- API Server开始反映etcd中的变化,即可以通过kubectl get或其他命令查看资源
- 所有kubernetes组件均使用”watch”机制跟踪检查API Server上的变动
- kube-scheduler通过”watch”机制检测到API Server创建了新的Pod但尚未绑定至任一节点
- kube-scheduler为Pod对象挑选节点并将结果更新到API Server
- 调度结果由API Server更新至etcd中,同时API Server开始反映此Pod对象调度结果
- 目标工作节点上的Kubelet尝试启动容器并将结果状态返回值API server
- API server将Pod状态信息存入etcd系统中。
- 在etcd确认写入操作成功完成后,API Server将确认信息发送至相关的Kubelet,事件将通过它被接受
Pod生命周期中的重要行为
初始化容器
主容器启动之前要运行的容器,通常为主容器执行一些预置操作,有以下两种典型特征。
- 初始化容器必须运行完成直至结束,若运行失败,那么需要Kubernetes重启他直到成功完成。
- 每个初始化容器都必须按照定义的顺序运行。
如果Pod的spec.restartPolicy为”Never”,则运行失败的容器不会被重启。
初始化容器的典型应用场景有以下几个
- 用于运行特定的工具程序,出于安全等方面的原因,这些程序不是也包含在主容器镜像中。
- 提供主容器镜像中不具备的工具程序或自定义代码。
- 为容器镜像的构建和部署人员提供了分离、独立工作的途径。
- 初始化容器和主容器处于不同的文件系统视图中,因此可以分别安全的使用敏数据如Secrets资源
- 初始化容器要先于主容器串行启动并完成运行,因此可以用于建后主容器的启动,直至其依赖条件得到满足。
下面是一个示例:
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: main
image: ikubernetes/myapp:v1
initContainers:
- name: init
image: busybox
command: ['sh', '-c', 'sleep 10']
生命周期钩子函数
kubernetes为容器提供了两种生命周期钩子。
- postStart:容器创建完成之后立即运行的钩子处理器。不过kubernetes无法确保一定在容器的ENTRYPOINT之前运行
- preStop:容器终止操作之前运行的钩子处理器。以同步的方式调用,因此在其完成之前会阻塞删除容器的操作。
钩子处理器的实现方式有”Exec”和”HTTP”两种,第一种在触发时直接在容器中执行用户指定的命令,后一种在当前容器中向某URL发起HTTP请求。postStart和preStop 在容器的spec.lifecycle嵌套字段中,下面是一个示例:
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: lifecycle-demo
image: ikubernetes/myapp:v1
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/nginx/html/test.html"]
容器探测
其主要作用是用来检测Pod中容器的健康状态。有以下三种处理方式:
- ExecAction:在容器中执行一个命令,并根据其返回的状态码进行诊断,为0即表示成功,否则为不健康状态。
- TCPSocketAction:尝试与容器的某个TCP端口进行连接,成功打开即为正常,否则为不健康状态。
- HTTPGetActione:向容器内指定的path发起HTTP GET请求响应码为2xx或3xx为成功,否则为失败。
检测结果有三种,”Success”、”Failure”、”Unknown”,只有第一种结果表示成功通过检测。
kubelet可以在活动容器上执行两种类型的检测,存活性检测和就绪性检测。
- 存活性检测:用于判断容器是否处于运行状态。一旦检测失败,kubelet将根据restartPolicy的定义决定是否将其重启,未定义存活性检测的容器的默认状态为”success”
- 就绪性检测:由于判断容器是否已经可以对外提供服务
后续会有更详细的关于存活性检测和就绪性检测的内容。
容器的重启策略
kubernetes可以定义三种重启策略
- Aways:只要Pod对象终止就将其充起,此为默认设定。
- OnFailure:请在出现错误时重启。
- Never:从不重启。
注意其作用范围是Pod,即Pod之内的所有容器都会重启。请注意这是重启不是重建,所以其所在节点并不会有所改变。多次重启的时间间隔会逐渐变长,最长为300秒。
Pod的中止过程
下面是一个典型的Pod的终止流程:
- 用户发送删除Pod对象的命令
- API服务器中的Pod对象会随着时间推移更新,在默认的30秒宽限期内Pod被视为dead
- 将Pod标记为”Terminating”
- 和第三步同时运行。Kubelet监控到状态变为”Terminating”的同时启动Pod关闭过程
- 和第三步同时运行。端点控制器监控到关闭行为时,将其从所有匹配到此端点的service资源的端点列表中移出。
- 如果该对象定义了preStop钩子处理器,则再其标记为”Terminating”后即同步执行,若宽限期结束后仍未执行结束,则第二步会被重新执行,并获取一个时长为两秒的额外宽限期。
- Pod对象中的容器收到TERM信号
- 宽限期结束后若仍然存在运行的进程。,Pod对象会收到SIGKILL信号
- Kubelet请求API Server将该资源对象的宽限期设置为零,从而完成删除操作。
默认情况下的删除宽限期都是30秒,可以使用kubectl delete --grace-period=<second>
命令自定义时长,指定为0则表示直接强制删除,此时需要使用--force
选项。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!