[Kubernetes] kubelet探活机制及状态管理
文章目录
为了保证服务能够正常提供服务,k8s提供了容器健康检查和就需检查功能,目前支持TCP、Http、和命令三种方式,
这里将不会分析所有的流程,只会看健康检查相关的流程。
在kubelet的在syncLoopIteration
函数中将会根据pod的操作类型进行相关的处理。这里涉及到的操作主要有Add
、Restore
、Remove
。
在Add和Restore中,通过HandlePodAdditions
操作,Remove通过HandlePodRemoves
实现。接下来将详细分析HandlePodAdditions
实现。
|
|
这里重点看kl.probeManager.AddPod
操作。关注manager
结构,
|
|
manager
在NewMainKubelet
中进行实例化,
|
|
其中readinessManager,livenessManager,startupManager都是用来存储检查结果的。
|
|
statusManager
是容器状态管理控制器,
|
|
prober
结构则是通过,kubelet中的runtime
,containerRefManager
,Recoder
实现的。
probeManager
的启动是在start。这个到后面再分析,先看probe实现。
|
|
接着分析kl.probeManager.AddPod
,在这里会分别为pod中的每个container都创建worker
,然后再worker中进行状态检测。
|
|
在Add中主要包括这几个步骤。1. 轮询pod中的每个容器;2. 根据每个容器的startupProbe
,ReadinessProbe
,LivenessProbe
三种检查的配置情况创建对应的worker;3. 执行检测w.run()
。
看其中一种检查类型的配置。
|
|
针对Startup
类型的检测会多一个features.StartupProbe的开关,其他两种则没有。先根据检测类型,存储到workers的key。如果这个pod的这个container已经存在,则会直接返回,否则会为这个container创建一个worker
。
|
|
然后再执行到 w.run()
,doProbe()
,在doProbe()
中主要完成了以下步骤。
- 获取pod的status;
- 如果pod已经是
v1.PodFailed
或者v1.PodSuccesseeded
两种状态,则停止检测; - 从pod status中获取对应的容器状态,然后根据容器状态做相应的处理,如果容器id和获取的不一样,容器状态不是
running
,再做相关处理,然后返回,如果是startup
类型的检测,并且容器已经启动则返回不再检测; - 执行检测
w.probeManager.prober.probe
; - 根据执行结果设置对应的
resultsManager
。 这里具体分析一下检测过程。
|
|
在上面将通过pb.runProbeWithRetries
再进行检测,之后执行runProbe
。
|
|
在runProbe
中将根据检测类型进行具体的检测命令检测,httpGet,TCP检测。根据检测结果在doProbe
函数中会记录相邻几次检测的结果。
这里会先从缓存中获取之前的记录,如果结果不一样会触发更新。然后在将结果组合成Update{id,result,pod.UID}
的方式放入到resultsManager
的update channel。
|
|
从channel中消费结果则在前面刚开始提到的probe_manager的start()。
|
|
我们分析其中一个Readiness
的update操作。
|
|
|
|
接下来分析状态更新部分。通过GeneratePodReadyCondition
和GenerateContainersReadyCondition
两个函数计算pod和container的ReadyCondition状态,然后通过m.updateStatusInternal
更新状态。
|
|
在这里会将更新发送到statusManager
的podStatusChannel
中,然后kubelet的statusManager在启动的时候会一直处理这里面的事件。
|
|
这里是statusManager处理状态更新事件。通过调用syncPod
从etcd中获取现在的pod,然后通过statusutil.PatchPodStatus
来patch新的状态。
文章作者 zForrest
上次更新 2020-06-01 15:31