在K8S集群故障处理过程中,你可能遇到过pod的各种状态,Evicted状态代表你的K8S环境遇到了资源驱逐的问题,本节通过对驱逐问题的解决,参数的调整,问题的处理思路,希望给你解决此类问题提供帮助。
pod驱逐问题
pod出现状态为Evicted时,表示出现了驱逐。pod驱逐出现的原因一般为资源不足,内存或磁盘空间不足,kubect describe node 根据集群事件或者系统日志来判断处于哪种驱逐场景。
- 内存驱逐
关键字:MemPressure
操作系统日志,kubelet厂商驱逐pod来回收内存
- 磁盘驱逐
根据pod日志查看也可以。
关键字:DiskPressure
当出现磁盘驱逐的时候,K8S的机制会在磁盘资源不足时删除未使用的容器镜像来释放空间。
处理思路
总体策略:根据分析的原因对应处理即可,找到驱逐pod所在的node节点,分析内存,cpu或者磁盘空间,分别采取不同措施。
首先是释放资源,让pod不再出现驱逐事件,保证业务使用不受影响。
内存场景说明
- 如果是内存出现驱逐,应用是多副本的情况下,可以择时重启导致内存占用高的服务释放资源
- 若没有发现占用内存高的资源,查看buff/cache占用是否过多不释放,可以临时或者加定时任务释放
echo 1 > /proc/sys/vm/drop_caches
或者 sysctl -w vm.drop_caches=1
echo 2 > /proc/sys/vm/drop_caches
或者 sysctl -w vm.drop_caches=2
echo 3 > /proc/sys/vm/drop_caches
或者sysctl -w vm.drop_caches=3
3.如果是正常业务占用,则后续及时扩容内存即可。
4.如果是其他场景,检查操作系统是否为XC系统,需要找厂商进行分析。
- 清理驱逐pod
清理驱逐的pod,避免反复重启积累过多。
kubectl get pod -o wide | grep 'Evicted' | awk '{print $2}' | xargs kubectl delete pod
- 关于驱逐的监控项
在K8S集群中,为了及时监控到驱逐问题,我们可以通过添加Prometheus监控来提前检测。
# 监控内存驱逐
kube_node_status_condition{cnotallow="MemoryPressure",status="true"} ==1
#监控磁盘驱逐
kube_node_status_condition{cnotallow="DiskPressure",status="true"} == 1
驱逐参数配置
解决了问题,我们来研究下驱逐的策略是怎样的。
节点压力驱逐是 kubelet 主动终止 Pod 以回收节点上资源的过程。
kubelet 监控集群节点的内存、磁盘空间和文件系统的 inode 等资源。当这些资源中的一个或者多个达到特定的消耗水平, kubelet 可以主动地使节点上一个或者多个 Pod 失效,以回收资源。
驱逐的默认配置:
memory.available<100Mi
nodefs.available<10%
imagefs.available<15%
nodefs.inodesFree<5%(Linux 节点)
例如,如果一个节点的总内存为 10GiB,并且你希望在可用内存低于 1GiB 时触发驱逐则可以将驱逐条件定义为 memory.available<10% 或 memory.available< 1G(你不能同时使用二者)。
有些情况下,当你的内存或者磁盘足够多时,采用百分比可能会导致在资源充足的情况下,产生驱逐问题,因此我们可以将默认驱逐修改为当剩余资源低于某个阈值时产生驱逐问题。
cat /data/kube/kubelet/kubelet-config.yaml | grep -A 4 evictionHard
evictionHard:
imagefs.available: "1Gi"
memory.available: "200Mi"
nodefs.available: "1Gi"
nodefs.inodesFree: "5%"
重启让配置生效。
sudo systemctl daemon-reload && sudo systemctl restart kubelet
重启完成后检查pod是否正常,业务闲时操作。