[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