k8s故障排查之主机资源不足-磁盘篇

前言

前面有讲过因为主机内存资源不足导致主机及pod均NotReady的状态,今天分享一个因为主机磁盘资源不足导致pod Evicted的故障。

故障现象

收到告警,有大量pod处于Evicted状态。

故障排查

查看告警后发现有问题的pod,均是调度到了同一台主机后出现的Evicted异常: alt 登陆容器,查看pod状态,发现存在pod处于Evicted状态,但是已经有pod迁移到了其他主机,且状态运行正常。 查看Evicted状态的pod,发现提示DiskPressure: alt 查看主机状态发现主机运行正常: alt 登陆主机,查看主机监控,发现cpu使用率,内存使用率,负载正常,但是磁盘使用率处于84%: alt alt alt 查看kubelet配置:

cat /etc/kubernetes/kubelet/kubelet-config.json  
---
...
  "evictionHard": {
    "memory.available": "100Mi",
    "nodefs.available": "10%",
    "nodefs.inodesFree": "5%"
  }
...

查看kubelet启动进程:

[root@ip-10-153-13-121 ~]# ps -ef| grep kube
root      3226     1  2 Nov03 ?        13:56:53 /usr/bin/kubelet --cloud-provider aws --config /etc/kubernetes/kubelet/kubelet-config.json --kubeconfig /var/lib/kubelet/kubeconfig --container-runtime remote --container-runtime-endpoint unix:///run/containerd/containerd.sock --node-ip=10.153.13.121 --pod-infra-container-image=602401143452.dkr.ecr.ap-southeast-1.amazonaws.com/eks/pause:3.5 --v=2 --node-labels=karpenter.sh/capacity-type=on-demand,karpenter.sh/provisioner-name=default  
root      3683  3385  0 Nov03 ?        00:08:24 kube-proxy --v=2 --config=/var/lib/kube-proxy-config/config  
nfsnobo+  3880  3471  0 Nov03 ?        03:08:12 /bin/node_exporter --web.listen-address=127.0.0.1:9100 --path.sysfs=/host/sys --path.rootfs=/host/root --no-collector.wifi --no-collector.hwmon --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|run/k3s/containerd/.+|var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/) --collector.netclass.ignored-devices=^(veth.*|[a-f0-9]{15})$ --collector.netdev.device-exclude=^(veth.*|[a-f0-9]{15})$  
65532     4099  3471  0 Nov03 ?        00:11:15 /usr/local/bin/kube-rbac-proxy --logtostderr --secure-listen-address=[10.153.13.121]:9100 --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 --upstream=http://127.0.0.1:9100/  
root      8943  5189  0 12:23 pts/0    00:00:00 grep --color=auto kube  

经过排查,kubelet默认并没有显示设置磁盘驱除策略,但是aws默认是有kubelet磁盘超过85%驱除的策略的: alt 通过ssh登陆主机,查看相关配置,排查故障产生的原因:
由于主机磁盘超过85%所以触发了kubelet自动驱除策略,又因为所在集群节点较少,所以新的pod又一次调度到同一个机器内。 因此一直处于pod删除调度的死循环状态,直到触发了karpenter的自动扩容策略,pod调度新的节点后才缓解此问题。

故障处理

在清理主机磁盘时发现此node主机仅跑了两个业务pod,并且业务pod所占用的磁盘并不大,而且主机内也没有delete等进程占用导致磁盘没有清理: alt alt

alt 通过du命令查看主机磁盘状态,发现占用较大的为容器快照: alt 通过查看主机状态发现主机容器引擎为contered: alt 查看主机目前镜像列表,并清除: alt alt

故障原因

  1. node主机磁盘较小,kubelet未修改驱除条件,导致pod在磁盘85%的时候被驱除。
  2. 因为节点较少导致pod驱除后重复调度该节点。
  3. 因为容器引擎采用的是contered,所以主机磁盘和pod磁盘大小无法匹配,且无法通过docker prune去批量清理。

优化及解决方案

  1. 自定义托管节点,修改kubelet驱除条件,将磁盘占比85%驱除的条件修改为磁盘占比95%再进行驱除。
  2. 修改karpenter节点模版增加磁盘大小为200G。
    • 如果不设置,默认karpenter自动创建出来的k8s节点磁盘大小为20G,可以通过修改karpenter的节点模版来改变磁盘大小,从而避免因为磁盘太小而频繁驱除pod的情况。
  3. 调整磁盘监控告警阈值,让磁盘告警阈值低于节点驱除pod的阈值。
    • 能够提前发现磁盘问题,避免pod因为主机磁盘资源不足而不能调度的问题。

作者介绍

  • 廉帅 高级SRE工程师

微鲤技术团队

微鲤技术团队承担了中华万年历、Maybe、蘑菇语音、微鲤游戏高达3亿用户的产品研发工作,并构建了完备的大数据平台、基础研发框架、基础运维设施。践行数据驱动理念,相信技术改变世界。