kubernetes机器image意外被删除

问题介绍

公司测试环境更新迭代测试,机器为单节点,镜像有点大,单是镜像包就100多G,解压后大概三四百G,新来员工未考虑到磁盘空间的问题(默认1T),导致空间不足,解压完成后发现,k8s环境镜像除了k8s核心组件pod(apiserver/scheduler/controller),其余的全部被驱逐(Evicted),重启pod发现没有镜像,docker image ls发现除了上述核心组件镜像外全部丢失。

原因分析

磁盘使用空间高于85%后,集群会在该节点打上污点node.kubernetes.io/disk-pressure:NoSchedule,并触发k8s节点驱逐pod策略,pod被驱逐后,当前节点pod处于停止状态,同时image处于未使用状态,因此删除image,导致image被删除。参考如下

  • 驱逐Node级别资源
    • 配置了 imagefs 阈值时
      • 达到 nodefs 阈值:删除已停止的 Pod
      • 达到 imagefs 阈值:删除未使用的镜像
    • 未配置 imagefs 阈值时
      • 达到 nodefs阈值时,按照删除已停止的 Pod 和删除未使用镜像的顺序清理资源
  • 驱逐用户 Pod
    • 驱逐顺序为:BestEffort、Burstable、Guaranteed
    • 配置了 imagefs 阈值时
      • 达到 nodefs 阈值,基于 nodefs 用量驱逐(local volume + logs)
      • 达到 imagefs 阈值,基于 imagefs 用量驱逐(容器可写层)
    • 未配置 imagefs 阈值时
      • 达到 nodefs阈值时,按照总磁盘使用驱逐(local volume + logs + 容器可写层)

  • image-gc-high-threshold:磁盘使用率上限,有效范围[0-100],默认85
  • image-gc-low-threshold:磁盘使用率下限,有效范围[0-100],默认80
  • minimum-image-ttl-duration:镜像最短应该生存的年龄,默认为2分钟

整改方案

如上可以看到,k8s有默认从参数配置,但是这个默认的参数针对某些环境可能不是特别的友好,如我当前测试环境为单节点。查阅资料都是需要调整kubelet的启动参数,根据我的环境调整参数如下:

  1. 调整磁盘使用率上限到95%,下限调整为94%,从而最大化保留数,调整驱逐策略
  2. 调整到达阈值后触发清理的等待时间,好在告警后第一时间处理
  3. 扩容当前磁盘,可通过LVM
[root@k8s-master ~]# cat  /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf     
###如下可以看到,启动文件一共引用了多个位置的环境变量文件。只需在任一配置文件配置即可,此处使用`/var/lib/kubelet/kubeadm-flags.env`
###/etc/sysconfig/kubelet
###/var/lib/kubelet/kubeadm-flags.env

# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS
[root@k8s-master  ~]# vim /var/lib/kubelet/kubeadm-flags.env

KUBELET_KUBEADM_ARGS="--network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2 --eviction-soft=memory.available<500Mi,nodefs.available<5%,nodefs.inodesFree<6%  --eviction-soft-grace-period=memory.available=300s,nodefs.available=300s,nodefs.inodesFree=300s  --eviction-minimum-reclaim=memory.available=0Mi,nodefs.available=500Mi,imagefs.available=2Gi"
#增加的如下三条
--eviction-soft=memory.available<500Mi,nodefs.available<5%,nodefs.inodesFree<6%       #清理阈值的集合,如果达到一个清理周期将触发一次容器清理
--eviction-soft-grace-period=memory.available=300s,nodefs.available=300s,nodefs.inodesFree=300s      #清理周期的集合,在触发一个容器清理之前一个软清理阈值需要保持多久
--eviction-minimum-reclaim=memory.available=0Mi,nodefs.available=500Mi,imagefs.available=2Gi       #资源回收最小值的集合,即 kubelet 压力较大时 ,执行 pod 清理回收的资源最小值
#重启即可
systemctl daemon-reload 
systemctl restart kubelet

kubelet_status
参数成功

补图:

该日志为kubelet日志,可看到kubelet在删除镜像回收磁盘空间

NOTE:磁盘扩容此处省略,可参考后面链接
磁盘扩容:
https://blog.csdn.net/eagle89/article/details/82978116
https://blog.csdn.net/bai1964847519/article/details/100113956
http://blog.itpub.net/15498/viewspace-2136692/

参考文献:
https://www.cnblogs.com/leozhanggg/p/13671131.html
https://kubernetes.io/zh/docs/tasks/administer-cluster/out-of-resource/
https://www.cnblogs.com/yaohong/p/13245723.html#auto-id-3

Logo

开源、云原生的融合云平台

更多推荐