Kubernetes中的Pod生命周期详解

Kubernetes中的Pod生命周期详解

Pod生命周期详解

Pod 是 kubernetes 系统的基础单元,是由用户创建或部署的最小组件,也是 kubernetes 系统上运行容器化应用的资源对象。Kubernetes 集群中其他资源对象都是为 pod 这个资源对象做支撑来实现 kubernetes 管理应用服务的目的。Kubernetes 集群组件主要包括主节点组件API Server、Controller Manager、Scheduler 以及子节点组件 kubelet、container Runtime(如docker)、kube-proxy 等。从与集群各组件交互角度讲述 pod 的创建、运行、销毁等生命周期,Pod 生命周期中的几种不同状态包括pending、running、succeeded、failed、Unknown。

  • 与API Server交互
API Server提供了集群与外部交互的接口,通过kubectl命令或者其他API客户端提交pod spec给API Server作为pod创建的起始。Pod与API Server交互的主要流程如下:
1.API Server在接收到创建pod的请求之后,会根据用户提交的参数值来创建一个运行时的pod对象。
2.根据API Server请求的上下文的元数据来验证两者的namespace是否匹配,如果不匹配则创建失败。
3.Namespace匹配成功之后,会向pod对象注入一些系统数据,如果pod未提供pod的名字,则API Server会将pod的 uid作为pod的名字。
4.API Server接下来会检查pod对象的必需字段是否为空,如果为空,创建失败。
5.上述准备工作完成之后会将在etcd中持久化这个对象,将异步调用返回结果封装成restful.response,完成结果反馈。至此API Server创建过程完成,剩下的由scheduler和kubelet来完成,此时pod处于pending状态。
  • 与scheduler交互
当提交创建pod的请求与API Server的交互完成之后,接下来由scheduler进行工作,该组件主要是完成pod的调度来决定pod具体运行在集群的哪个节点上。注意,此处声明一点,API Server完成任务之后,将信息写入到etcd中,此时 scheduler通过watch机制监听到写入到etcd的信息然后再进行工作。Scheduler读取到写入到etcd中的pod信息,然后基于一系列规则从集群中挑选一个合适的节点来运行它,调度时主要通过三步来确定pod运行节点:
1.节点预选:基于一系列预选规则对每个节点进行检查,将不符合的节点过滤掉从而完成节点预选。
2.节点优选:对预选出的节点进行优先级排序,以便选出最适合运行pod对象的节点。
3.从优先级结果中挑选出优先级最高的节点来运行pod对象,当此类节点多个时则随机选择一个。
当 scheduler通过一系列策略选定pod运行节点之后将结果信息更新至API Server,由API Server更新至etcd中,并由API Server反映调度结果,接下来由kubelet在所选定的节点上启动pod。
  • Kubelet组件启动pod
kubelet组件的作用不单单是创建 pod,另外还包括节点管理、cAdvisor资源监控管理、容器健康检查等功能。 
kubelet通过API Server监听etcd目录,同步pod列表。如果发现有新的pod绑定到本节点,则按照pod清单要求创建 pod,如果是发现pod被更新,则做出相应更改。读取到pod的信息之后,如果是创建和修改pod的任务,则做如下处理:
1.为该pod创建一个数据目录
2.从API Server读取该pod清单
3.为该pod挂载外部卷
4.下载pod所需的Secret
5.检查已经运行在节点中pod,如果该pod没有容器或者Pause容器没有启动,则先停止pod里所有的容器进程。
6.使用pause镜像为每个pod创建一个容器,该容器用于接管Pod中所有其他容器的网络。
7.为pod中的每个容器做如下处理:1.为容器计算一个 hash值,然后用容器的名字去查询对于docker容器的hash值。若查找到容器,且两者的hash值不同,则停止docker中容器中进程,并停止与之关联的pause容器,若相同,则不做处理。若容器被终止了,且容器没有指定的重启策略,则不做任何处理调用docker client下载容器镜像,并启动容器。
  • 创建service
随后,我们通过Kubectl提交一个新的映射到该Pod的Service的创建请求
1.ControllerManager会通过Label标签查询到相关联的Pod实例,然后生成Service的Endpoints信息,并通过APIServer写入到etcd中,
2.接下来,所有Node上运行的Proxy进程通过APIServer查询并监听Service对象与其对应的Endpoints信息,建立一个软件方式的负载均衡器来实现Service访问到后端Pod的流量转发功能。
  • Pod终止过程
终止过程主要分为如下几个步骤:
1. 用户发出删除pod命令
2. Pod对象随着时间的推移更新,在宽限期(默认情况下30秒),pod被视为“dead”状态
3. 将pod标记为“Terminating”状态
4. 第三步同时运行,监控到pod对象为“Terminating”状态的同时启动pod关闭过程
5. 第三步同时进行,endpoints控制器监控到pod对象关闭,将pod与service匹配的endpoints列表中删除
6. 如果pod中定义了preStop钩子处理程序,则pod被标记为“Terminating”状态时以同步的方式启动执行;若宽限期结束后,preStop仍未执行结束,第二步会重新执行并额外获得一个2秒的小宽限期
7. Pod内对象的容器收到TERM信号
8. 宽限期结束之后,若存在任何一个运行的进程,pod会收到SIGKILL信号
9. Kubelet请求API Server将此Pod资源宽限期设置为0从而完成删除操作