因为Pod是Kubernetes管理的最小单元,所以它的具体生命周期是Kubernetes重要的一环,今天详细学习记录一下Pod的整个生命周期。
Pod对象自从其创建开始到终止结束的时间范围称为生命周期。
Pod的生命周期是基于Pod的成功创建,所以为更好的理解Pod的生命周期,这里需要先理解一下Pod的整个创建过程。
一、Pod的创建过程
Pod的创建过程,如下图所示:
- 用户通过Kubectl发送创建Pod的请求,提交至API-server;
- API-server会尝试将Pod信息写入到etcd中,待写入操作完成,API-server会将结果返回至用户;
- 此时API-server会开始反映etcd的状态变化;
- 所有的Kubernetes组件都是用watcher机制来跟踪检查API-server上的变化;
- Scheduler调度器会通过watch探测到API-server的Pod信息,但还未绑定到工作节点;
- Scheduler会选择一个合适的工作点,将信息同步到API-server;
- 调度信息由API-server写入到到etcd中去,而且API-server也开始反映该Pod的调度信息;
- Pod被调度到的工作节点的kubelet会在当前节点尝试调用Docker启动器,并将容器的结果状态返回至API-server;
- API-server将Pod状态信息写入到etcd中;
- 在etcd写入完成之后,API-server会将确认信息返回至kubelet;
当Pod创建成功之后,Pod可能会有多个状态,涉及到Pod生命周期的多个重要行为。
二、Pod的生命周期
它的大致生命周期过程如下图所示:
它主要包含以下几个重要的行为:
- 初始化容器
- 存活性探测
- 就绪型探测
- 生命周期钩子函数
1、初始化容器
初始化容器(init container)即应用程序的主容器启动之前要运行的容器,常用于为主容器执行一些预置操作,它们具有两种典型特征。
- 初始化容器必须运行完成直至结束,若某初始化容器运行失败,那么Kubernetes需要重启它直到成功完成
- 每个初始化容器都必须按定义的顺序串行运行。
初始化容器的典型应用场景有:
- 用于运行特定的工具程序,出于安全等方面的原因,这些程序不适于包含在主容器镜像中。
- 提供主容器镜像中不具备的工具程序或自定义代码。
- 为容器镜像的构建和部署人员提供了分离、独立工作的途径,使得他们不必协同起来制作单个镜像文件。
- 初始化容器和主容器处于不同的文件系统视图中,因此可以分别安全地使用敏感数据,例如Secrets资源。
- 初始化容器要先于应用容器串行启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足。
2、就绪型探测和存活性探测
在说容器探测之前,先说一下Kubernetes的探测方式,K8s包含三大类探测方式:
- ExecAction:在容器中执行一个命令,并根据其返回的状态码进行诊断的操作称为Exec探测,状态码为0表示成功,否则即为不健康状态。
- TCPSocketAction:通过与容器的某TCP端口尝试建立连接进行诊断,端口能够成功打开即为正常,否则为不健康状态。
- HTTPGetAction:通过向容器IP地址的某指定端口的指定path发起HTTP GET请求进行诊断,响应码为2xx或3xx时即为成功,否则为失败。
任何一种探测方式都可能存在三种结果:“Success”(成功)、“Failure”(失败)或“Unknown”(未知),只有第一种结果表示成功通过检测。
kubelet可在活动容器上执行两种类型的检测:存活性检测(livenessProbe)和就绪性检测(readinessProbe)
3、生命周期钩子函数
从上图可以看出钩子函数也是Pod生命周期中的一个事件。
Kubernetes为容器提供了两种生命周期钩子。
- Start:于容器初始化创建完成之后立即运行的钩子处理器(handler),不过Kubernetes无法确保它一定会于容器中的ENTRYPOINT之前运行。
- Stop:于容器终止操作之前立即运行的钩子处理器,它以同步的方式调用,因此在其完成之前会阻塞删除容器的操作的调用。
Pod对象代表了Kubernetes集群节点上运行的进程,当它本身没有价值时,就需要Kubernetes去优雅的终止它,那么Kubernetes是如何终止Pod呢?
三、Pod的终止过程
Pod终止删除过程是通过用户来提交删除申请,之后Kubernetes来做整个Pod的删除操作。
当用户提交删除请求之后,系统就会进行强制删除操作的宽限期倒计时,并将TERM信息发送给Pod对象的每个容器中的主进程。宽限期倒计时结束后,这些进程将收到强制终止的KILL信号,Pod对象随即也将由API Server删除。如果在等待进程终止的过程中,kubelet或容器管理器发生了重启,那么终止操作会重新获得一个满额的删除宽限期并重新执行删除操作。
整个删除过程,如下图所示:
- 用户发送删除Pod对象的命令。
- API服务器中的Pod对象会随着时间的推移而更新,在宽限期内(默认为30秒),Pod被视为“dead”。
- 将Pod标记为“Terminating”状态。
- (与第3步同时运行)kubelet在监控到Pod对象转为“Terminating”状态的同时启动Pod关闭过程。
- (与第3步同时运行)端点控制器监控到Pod对象的关闭行为时将其从所有匹配到此端点的Service资源的端点列表中移除。
- 如果当前Pod对象定义了preStop钩子处理器,则在其标记为“terminating”后即会以同步的方式启动执行;如若宽限期结束后,preStop仍未执行结束,则第2步会被重新执行并额外获取一个时长为2秒的小宽限期。
- Pod对象中的容器进程收到TERM信号。
- 宽限期结束后,若存在任何一个仍在运行的进程,那么Pod对象即会收到SIGKILL信号。
- Kubelet请求API Server将此Pod资源的宽限期设置为0从而完成删除操作,它变得对用户不再可见。
总结:
Pod会处于多种不同的状态,并执行一些操作;
其中,创建主容器(main container)为必需的操作,其他可选的操作还包括运行初始化容器(init container)、容器启动后钩子(post start hook)、容器的存活性探测(liveness probe)、就绪性探测(readiness probe)以及容器终止前钩子(pre stop hook)等,这些操作是否执行则取决于Pod的定义。