作者介绍:简历上没有一个精通的运维工程师。
我们上一章介绍了Docker基本情况,目前在规模较大的容器集群基本都是Kubernetes,但是Kubernetes涉及的东西和概念确实是太多了,而且随着版本迭代功能在还增加,笔者有些功能也确实没用过,所以只能按照我自己的理解来讲解。
前面介绍了Pod的创建过程和Pod各个状态,今天我们来讲讲Node的状态。
状态说明
Pod的状态可以有很多,但是Node状态实际上只有2个,一个是正常的Ready,和一个非正常状态NotReady。
在Kubernetes当中NotReady是一个比较常见的问题,引发的原因也有很多,主要涉及到kubelet本身异常,Docker异常(或者是Containerd异常),操作系统异常,以及PLEG等。在 Kubernetes 社区中,PLEG is not healthy 成名已久,只要出现这个报错,就有很大概率造成 Node 状态变成 NotReady,并且是在NotReady和Ready来回切换。那什么是PLEG呢?
PLEG 是 "Pod Lifecycle Event Generator" 的缩写,它是 Kubernetes 中负责监控和报告 Pod 生命周期事件的组件。具体来说,PLEG 的主要职责是监测运行在节点上的容器状态变化,并将这些变化通知给 Kubelet(Kubernetes 节点上的代理)。虽然说上报给Kubelet,实际执行这个逻辑的也是它,最后还是把信息汇总到kube-apiserver。
以下是 PLEG 的一些关键功能:
事件检测:PLEG 会定期检查容器的状态,比如它们是否已经启动、是否正在运行、是否已停止等。
事件生成:当检测到容器状态发生变化时,PLEG 会生成相应的生命周期事件。例如,当一个新容器被创建或现有容器终止时,它会产生对应的事件。
事件同步:这些事件随后会被同步给 kubelet,以便它可以更新其内部状态并采取必要的行动。如重新调度失败的容器或者更新 Pod 状态为 "Ready" 或 "NotReady"。
健康检查支持:PLEG 也参与了对容器执行存活探针(liveness probe)和就绪探针(readiness probe)的支持,确保只有健康的容器被认为是准备好的并且可以接收流量。
提高系统稳定性:通过及时捕获和响应容器状态的变化,PLEG 帮助维护集群中各个 Pod 和容器的稳定性和正确性。
状态异常影响
kubelet节点NotReady对pod的影响根据实际情况而已,影响的范围也有差异。
1.对于无状态Pod,当前节点NotReady,则处于不可调度状态,集群资源缩小,如果服务器资源紧张可能出现部分Pod无法调度,就可能影响业务。如果集群资源比较多,所有Pod都能正常调度,则几乎没什么影响,但是需要及时发现及时修复问题。
2.对于有状态Pod或者只能在当前节点的Pod,则无法调度到其他节点,可能会出现Pending或者Unknown状态。在正常高可用架构涉及下是不会影响的,但是需要尽快修复,因为如果在你修复之前可能另外节点也出现异常,则可能你的高可用失效。
3.单副本无状态Pod,虽然会调度到其他节点,但是这个是有有时间差的。首先一个时间是就kubelet状态最长40秒才会被判断为NoReady,然后还有一个驱逐超时时间5分钟,最慢是是5分40秒才会被调度到其他节点(这些是默认参数可以调整),也就是这个可能会导致业务中断超过5分钟。
生产案例
案例一:这个是曾经在某私有云遇到的生产环境案例,具体原因暂时未知。大概逻辑就是Kubelet无法获取Docker状态,导致节点出现NotReady,但是一会又可以获取正常状态,就会出现Node状态反复跳变。下面是当时解决方法。
# 遍历docker容器状态,验证是否会被卡住
for c in $(docker ps -aq); do echo $c; docker inspect $c 1>/dev/null 2>&1; done
# 如果被卡住,说明对应的容器有问题,一般直接删除容器即可
docker rm -f ${dockerid}
# 如果删除后还复现,则需要重点查看docker状态
案例二:也是某私有云生产案例,当前集群默认不能中断的Pod至少都是2副本,默认都是配置亲和性和反亲和性,但是由于这个集群在部署的时候只有一个节点,所以当时这两个Pod就都在一个节点,最后这个节点崩溃,业务中断了5分钟。