共计 2055 个字符,预计需要花费 6 分钟才能阅读完成。
在 kubernetes 集群中,pod 的创建是一切的开始,本文介绍一下我所了解的 pod 的生命周期。
k8s 中 kube-apiserver 是对外提供访问的唯一借口,此组件提供了认证 / 授权 / 准入控制功能,其中准入控制包括了 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook 两种实现类型,其中 istio 等功能基于此实现,暂且不把准入控制计算到 pod 的生命周期中。
pod 对象从其创建开始至其终止推出的时间范围成为生命周期。这其中包括创建主容器,初始化容器,容器启动后钩子,容器存活性探测,以及容器停止前钩子,其中其中主容器是必须的。
首先介绍一下 pod 生命周期的几种状态:
Pending:创建 pod 的资源对象已经存入 etcd 但是 pod 尚未被调度。
Running:pod 已经被 kubelet 创建完成
Secceeded:pod 都已经终止成功并且不会被重启
Failed:所有容器都已经终止,但是至少又一个容器终止失败,即容器返回了非 0 状态或已经被系统终止
Unknown:api server 无法正常获取到 pod 对象的状态信息。
pod 创建的过程:
1> 用户通过 API Server 或其他 API 客户端提交 pod Spec 给 API Server
2>API Server 将 pod 的信息存入到 etcd 中,待写入操作完成后,API Server 返回确认信息至客户端
3>API Server 将信息写入到 etcd 中之后,其中 informer 机制开始起作用,通过 watch 机制将 pod 状态的变化反映到缓存中。(informer 相关内容可以参考以下链接:https://www.jianshu.com/p/1e2…
4>kube-scheduler 的 watch 机制察觉到 pod 对象创建但是并未绑定到任何工作节点,kube-scheduler 开始根据 predicates 以及 priorities 算法来计算 pod 的最佳运行节点,然后将 pod 的调度结果反映到 API Server 中(具体调度过程可以参考之前文章)。
5>pod 调度完成之后,由 kubelet 来创建 pod 并将容器状态返回至 API Server 存入到 etcd 中。
6> 写入成功之后并将结果反映到相应的 kubelet。
上面是创建 pod 的几个重要步骤:
pod 生命周期的几个重要行为:
1. 初始化容器,初始化容器的两个特征:
1)初始化容器必须运行完成才会创建主容器
2)初始化容器按照定义的顺序串行运行
2. 生命周期钩子:
pod 的生命周期钩子分为以下两种:
1)postStart:容器创建完成之后执行的钩子处理程序,但是无法保证它一定会于容器中的 endpoint 之前运行
2)preStop:容器终止之前立即运行的钩子处理器,它以同步的方式调用,完成之前阻止删除容器操作。
3. 容器探测:
容器探测分为就绪性探测和存活性探测
1)就绪性探测:用于判断容器是否就绪并可对外提供服务
2)存活性探测:用于探测容器是否处于运行状态,一旦处于非运行状态,杀死容器根据容器重启策略判断是否将其重启,为定义探测的默认状态是 success
上述两种探测支持三种处理方式:
1)ExecAction:在容器中执行一个命令,根据命令返回状态码进行诊断
2)TCPSocketAction:通过与容器的某个 TCP 端口尝试建立连接来判断将康状况
3)HTTPAction:通过 http 调用的方式来判断健康状态
上述健康检测涉及到 pod 的重启策略,pod 中的几种重启策略:
1)Always:pod 对象终止就进行重启
2)OnFailure:尽在 pod 出现错误时方才将其重启
3)Never:从不重启
pod 的终止过程:
1)用户发送删除命令
2)API 服务器中国内地饿破洞对象随着时间的推移而更新,在宽限期内(30 秒)pod 被视为“dead”
3)将 pod 标记为“Terminating”状态
4)与第三步同步,kubelet 监听到 pod 对象转为“Terminating”状态的同时开启 pod 关闭过程
5)与第三步同步,断点控制器(endpoint controller)监控到 pod 对象关闭时将其从所有匹配到此端点的 server 的端点列表中移除
6)如果当前 pod 对象定义了 preStop 钩子处理器,则在标记为“Terminating”后开始同步执行,若宽限期结束,仍未执行完毕,则获得一个 2 秒的宽限期,继续执行
7)pod 对象中的容器进程收到 TERM 信号
8)宽限期结束后,若存在任何一个仍在运行的线程,发送 SIGKILL 信号
9) 删除 pod,对用户不可见
默认情况下,都会又一个 30 秒的宽限期,不过可以在 kubectl 命令中使用 –grace-period=<second> 来定义时间长短,但此命令必须制定 –force 参数。
注:上述过程中很多地方用到了 watch 机制,涉及到 client-go 中的 informer,建议查看以下该机制,参考链接:https://www.jianshu.com/p/1e2…
上面是就是创建 pod 的大致流程。