关于Kubernetes image垃圾镜像容器的回收

简介: 关于Kubernetes image垃圾镜像容器的回收

背景:

早些时候kubernetes集群的cri还使用docker的时候经历过这样的状况: 集群运行很久后硬盘跑的快满了......,大文件主要集中在:/var/lib/docker/overlay2 下文件有快70G,/var/log/journal/日志也有4-5G。当时的操作是手工的在work节点进行了一下的操作:

  1. journalctl --vacuum-size=20M #设置journal 日志最大为20M不保留不必要日志。
  2. docker image prune -a --filter "until=24h" # 清除超过创建时间超过24小时的镜像
  3. docker container prune --filter "until=24h" #清除掉所有停掉的容器,但24内创建的除外
  4. docker volume prune --filter "label!=keep" #除lable=keep外的volume外都清理掉(没有引用的volume)
  5. docker system prune #清理everything:images ,containers,networks一次性清理操作可以通过docker system prune来搞定

注: 以上摘自个人博客2019年的一篇:https://duiniwukenaihe.github.io/2019/11/25/k8s-question2/
当然了类似的还有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节点最近频繁收到了磁盘大于百分之九十的报警了......,强迫症犯了!
image.png

关于Kubernetes image垃圾镜像容器的回收

关于kubelet:

节点管理

节点通过设置kubelet的启动参数“--register-node”,来决定是否向API Server注册自己,默认为true.[kubelet --help]

Pod管理

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

垃圾回收是 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 参数调整相关阈值来优化镜像垃圾回收:

  1. image-gc-high-threshold,触发镜像垃圾回收的磁盘使用率百分比。默认值为 85%。
  2. image-gc-low-threshold,镜像垃圾回收试图释放资源后达到的磁盘使用率百分比。默认值为 80%。

我们还允许用户通过以下 kubelet 参数自定义垃圾收集策略:

  1. minimum-container-ttl-duration,完成的容器在被垃圾回收之前的最小年龄,默认是 0 分钟。 这意味着每个完成的容器都会被执行垃圾回收。
  2. maximum-dead-containers-per-container,每个容器要保留的旧实例的最大数量。默认值为 1。
  3. maximum-dead-containers,要全局保留的旧容器实例的最大数量。 默认值是 -1,意味着没有全局限制。

容器可能会在其效用过期之前被垃圾回收。这些容器可能包含日志和其他对故障诊断有用的数据。 强烈建议为 maximum-dead-containers-per-container 设置一个足够大的值,以便每个预期容器至少保留一个死亡容器。 由于同样的原因,maximum-dead-containers 也建议使用一个足够大的值。

参照一下我的tke集群

cat /etc/kubernetes/kubelet
image.png
看了一眼没有找到kubelet-garbage-collection上面的参数?只有一个--eviction-hard。仔细看一眼文档的弃用部分:
image.png
嗯 1.21版本启用了--eviction-hard参数,至于nodefs.inodesFree可参照:
image.png

自建集群中的配置:

image.png
嗯配置文件中未作任何设置只有一个imageMinimumGCAge!
可参照:
image.png
可参照:https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/。中文如下:
image.png

总结一下:

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

另外ubelet的配置还要深入研究一下!

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
6月前
|
Kubernetes Docker Python
Docker 与 Kubernetes 容器化部署核心技术及企业级应用实践全方案解析
本文详解Docker与Kubernetes容器化技术,涵盖概念原理、环境搭建、镜像构建、应用部署及监控扩展,助你掌握企业级容器化方案,提升应用开发与运维效率。
1027 108
|
4月前
|
NoSQL 算法 Redis
【Docker】(3)学习Docker中 镜像与容器数据卷、映射关系!手把手带你安装 MySql主从同步 和 Redis三主三从集群!并且进行主从切换与扩容操作,还有分析 哈希分区 等知识点!
Union文件系统(UnionFS)是一种**分层、轻量级并且高性能的文件系统**,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem) Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
636 5
|
6月前
|
缓存 Ubuntu Docker
Ubuntu环境下删除Docker镜像与容器、配置静态IP地址教程。
如果遇见问题或者想回滚改动, 可以重启系统.
452 16
|
5月前
|
存储 Kubernetes 网络安全
关于阿里云 Kubernetes 容器服务(ACK)添加镜像仓库的快速说明
本文介绍了在中国大陆地区因网络限制无法正常拉取 Docker 镜像的解决方案。作者所在的阿里云 Kubernetes 集群使用的是较旧版本的 containerd(1.2x),且无法直接通过 SSH 修改节点配置,因此采用了一种无需更改 Kubernetes 配置文件的方法。通过为 `docker.io` 添加 containerd 的镜像源,并使用脚本自动修改 containerd 配置文件中的路径错误(将错误的 `cert.d` 改为 `certs.d`),最终实现了通过多个镜像站点拉取镜像。作者还提供了一个可重复运行的脚本,用于动态配置镜像源。虽然该方案能缓解镜像拉取问题,
628 2
|
5月前
|
Kubernetes Devops Docker
Kubernetes 和 Docker Swarm:现代 DevOps 的理想容器编排工具
本指南深入解析 Kubernetes 与 Docker Swarm 两大主流容器编排工具,涵盖安装、架构、网络、监控等核心维度,助您根据团队能力与业务需求精准选型,把握云原生时代的技术主动权。
418 1
|
6月前
|
Ubuntu 网络安全 PHP
如何使用vscode的Docker插件管理ubuntu 拉取服务器的镜像以及创建容器
本测试镜像旨在记录使用vscode的Docker插件拉取病创建Dockerfile,以及拉取镜像。
|
9月前
|
关系型数据库 MySQL Docker
|
11月前
|
存储 监控 对象存储
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
336 0
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明

相关产品

  • 容器服务Kubernetes版
  • 推荐镜像

    更多