禁用容器镜像垃圾回收并配置磁盘相关容器漂移策略
1. 在无镜像仓库的情况下使用 k8s 的问题
k8s 默认有一个垃圾回收机制,而且容器的临时存储和容器的镜像存储都在/var 目录下,因此只要有/var 目录大于 85%的情况(无论是容器写临时文件还是/var 目录下生成了其它特别大的东西,还是导入容器镜像),k8s 就会把所有的容器赶走,同时会对容器镜像垃圾回收。但是,由于容器已经都被赶走了,垃圾回收会把这些容器镜像删掉,之后如果容器镜像是在节点手动导入而非从镜像仓库拉取,则会导致容器镜像永远丢失,节点/var 目录清理或扩容后,仍旧无法启动容器。因此需要把容器的存储位置单独挂盘,并且禁用容器镜像的垃圾回收。
还是不推荐不搭建一个镜像仓库,因为这种方法一旦容器的目录真的满了,必须人工上去 ctr 命令删除容器
2. 修改 kubelet 配置
在/var/lib/kubelet/config.yaml中,配置 k8s 节点在容器临时文件存储低于 10% 时,赶走所有容器到其它节点,且容器镜像不使用 100 年后才清理:
| evictionHard:
imagefs.available: "10%"
nodefs.available: "5%"
imageGCHighThresholdPercent: 100
imageGCLowThresholdPercent: 99
imageMinimumGCAge: 876000h
|
重启 kublet:
| systemctl restart kubelet.service
|
3. 将 /var/lib/containerd 单独挂载 lv,防止系统日志挤占容器空间
3.1 腾空一个 k8s 节点
| kubectl cordon z10bansk8scp02
kubectl drain z10bansk8scp02 --ignore-daemonsets --delete-emptydir-data
|
3.2 清理数据
停止 kubelet:
| systemctl stop kubelet.service
|
删除所有容器:
| for i in $(ctr -n k8s.io task ls | awk '{print $1}');do ctr -n k8s.io task kill $i;done
for i in $(ctr -n k8s.io container ls | awk '{print $1}');do ctr -n k8s.io container delete $i;done
|
删除容器镜像:
| ctr -n k8s.io image prune --all
|
停止 containerd 并清理 containerd 目录:
| systemctl stop containerd
rm -rf /var/lib/containerd/*
|
将 containerd 镜像目录单独挂载 lv:
| lvcreate -n lv_containerd -L 30G rootvg
mkfs.xfs /dev/rootvg/lv_containerd
echo "/dev/rootvg/lv_containerd /var/lib/containerd xfs defaults 0 0" >> /etc/fstab
mount -a
|
启动 containerd 和 kubelet,并解除隔离状态:
| systemctl restart containerd
systemctl restart kubelet.service
kubectl uncordon z10bansk8scp02
|
3.3 重新导入容器镜像并检查:
| for i in *;do ctr -n k8s.io image import $i --platform linux/amd64;done
ctr -n k8s.io images list | grep -v ^sha256 | awk '{print $1}' | nl
|
4. 参考链接
https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/
https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/
https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/