containerd|关于Kubernetes image垃圾镜像容器的回收
背景: 早些时候kubernetes集群的cri还使用docker的时候经历过这样的状况: 集群运行很久后硬盘跑的快满了…,大文件主要集中在:/var/lib/docker/overlay2 下文件有快70G,/var/log/journal/日志也有4-5G。当时的操作是手工的在work节点进行了一下的操作:
- journalctl --vacuum-size=20M #设置journal 日志最大为20M不保留不必要日志。
- docker image prune -a --filter “until=24h” # 清除超过创建时间超过24小时的镜像
- docker container prune --filter “until=24h” #清除掉所有停掉的容器,但24内创建的除外
- docker volume prune --filter “label!=keep” #除lable=keep外的volume外都清理掉(没有引用的volume)
- docker system prune #清理everything:images ,containers,networks一次性清理操作可以通过docker system prune来搞定
当然了类似的还有inotify watch 耗尽 cgroup 泄露。可参照:https://www.bookstack.cn/read/kubernetes-practice-guide/troubleshooting-problems-errors-no-space-left-on-device.md
那么问题来了:我现在的集群是kubernetes1.21集群。cri是containerd 我改如何清理除了系统日志外的 关于cri的资源呢?正常的来说kubelet是有此功能的?反正我tke集群的work节点最近频繁收到了磁盘大于百分之九十的报警了…,强迫症犯了!
文章图片
关于Kubernetes image垃圾镜像容器的回收 关于kubelet: 节点管理
节点通过设置kubelet的启动参数“–register-node”,来决定是否向API Server注册自己,默认为true.[kubelet --help]
Pod管理
【containerd|关于Kubernetes image垃圾镜像容器的回收】kubelet通过API Server Client使用Watch/List的方式监听etcd中/registry/nodes/${当前节点名称}和/registry/pods的 目录,将获取的信息同步到本地缓存中。kubelet监听etcd,执行对Pod的操作,对容器的操作则是通过Docker Client 执行,常见的操作包含:增,删,该,查。
容器健康检查
探针是kubelet对容器执行定期的诊断,主要通过调用容器配置的三类Handler实现,如果存活探测失败,则
kubelet 会杀死容器,并且容器将受到其 重启策略的影响。
资源监控
kubelet通过cAdvisor获取本节点信息及容器的数据。cAdvisor为谷歌开源的容器资源分析工具,默认集成到
kubernetes中。
kubelet-garbage-collection 注:以下内容来自:https://kubernetes.io/zh/docs/concepts/cluster-administration/kubelet-garbage-collection/嗯多看下文档…
?
垃圾回收是 kubelet 的一个有用功能,它将清理未使用的镜像和容器。Kubelet 将每分钟对容器执行一次垃圾回收, 每五分钟对镜像执行一次垃圾回收。 不建议使用外部垃圾收集工具,因为这些工具可能会删除原本期望存在的容器进而破坏 kubelet 的行为。
镜像回收
Kubernetes 借助于 cadvisor 通过 imageManager 来管理所有镜像的生命周期。
镜像垃圾回收策略只考虑两个因素:HighThresholdPercent 和 LowThresholdPercent。 磁盘使用率超过上限
阈值(HighThresholdPercent)将触发垃圾回收。 垃圾回收将删除最近最少使用的镜像,直到磁盘使用率满足下
限阈值(LowThresholdPercent)。
容器回收
容器垃圾回收策略考虑三个用户定义变量。MinAge 是容器可以被执行垃圾回收的最小生命周期 。
MaxPerPodContainer 是每个 pod 内允许存在的死亡容器的最大数量。 MaxContainers 是全部死亡容器的最大数
量。可以分别独立地通过将 MinAge 设置为 0,以及将 MaxPerPodContainer 和 MaxContainers 设置为小于 0 来
禁用这些变量。 Kubelet 将处理无法辨识的、已删除的以及超出前面提到的参数所设置范围的容器。最老的容器通常会先被移除。 MaxPerPodContainer 和 MaxContainer 在某些场景下可能会存在冲突,例如在保证每个 pod 内死亡容器的最大数 量(MaxPerPodContainer)的条件下可能会超过允许存在的全部死亡容器的最大数量(MaxContainer)。 MaxPerPodContainer 在这种情况下会被进行调整:最坏的情况是将 MaxPerPodContainer 降级为 1,并驱逐最老 的容器。 此外,pod 内已经被删除的容器一旦年龄超过 MinAge 就会被清理。
不被 kubelet 管理的容器不受容器垃圾回收的约束。
用户配置
用户可以使用以下 kubelet 参数调整相关阈值来优化镜像垃圾回收:
- image-gc-high-threshold,触发镜像垃圾回收的磁盘使用率百分比。默认值为 85%。
- image-gc-low-threshold,镜像垃圾回收试图释放资源后达到的磁盘使用率百分比。默认值为 80%。
- minimum-container-ttl-duration,完成的容器在被垃圾回收之前的最小年龄,默认是 0 分钟。 这意味着每个完成的容器都会被执行垃圾回收。
- maximum-dead-containers-per-container,每个容器要保留的旧实例的最大数量。默认值为 1。
- maximum-dead-containers,要全局保留的旧容器实例的最大数量。 默认值是 -1,意味着没有全局限制。
参照一下我的tke集群
cat /etc/kubernetes/kubelet
文章图片
看了一眼没有找到kubelet-garbage-collection上面的参数?只有一个–eviction-hard。仔细看一眼文档的弃用部分:
文章图片
嗯 1.21版本启用了–eviction-hard参数,至于nodefs.inodesFree可参照:https://kubernetes.io/zh/docs/tasks/administer-cluster/out-of-resource/
文章图片
自建集群中的配置:
文章图片
嗯配置文件中未作任何设置只有一个imageMinimumGCAge!
可参照:
文章图片
可参照:https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/。中文如下:
文章图片
总结一下: Kubelet 支持 gc 和驱逐机制,可通过 --image-gc-high-threshold、–image-gc-low-threshold、–eviction-hard、–eviction-soft 及 --eviction-minimum-reclaim 等参数进行控制以实现磁盘空间的释放。当配置不正确,或者节点上有其它非 K8S 管理的进程在不断写数据到磁盘,将会占用大量空间时将导致磁盘爆满。tke集群设置的是–eviction-hard=nodefs.available<10%,这个值我可能会修改为20%。因为cvm的报警阀值我都设置的90%。后续个人准备参照tke的–eviction-hard=nodefs.available<10%,nodefs.inodesFree<5%,memory.available<100Mi参数修改一下这三个了…(image-gc-high-threshold默认85%,image-gc-low-threshold默认80%自建的集群应该是 忽略了)。个人的集群还没有报警。关键是tke集群的报警这个值还的调整一下了!
关于tke磁盘爆满的文档: https://cloud.tencent.com/document/product/457/43126#.E5.8F.AF.E8.83.BD.E5.8E.9F.E5.9B.A0
另外kubelet的配置还要深入研究一下! ?
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- 四首关于旅行记忆的外文歌曲
- 醒不来的梦
- 关于自我为中心的一点感想
- 「按键精灵安卓版」关于全分辨率脚本的一些理解(非游戏app)
- 关于Ruby的杂想
- 关于读书的思考
- 关于this的一些问题(1)
- federation--kubernetes集群联邦的实现
- 《声之形》