From 0abde17dbf8840a51fab9d55f321ade8f77d8489 Mon Sep 17 00:00:00 2001 From: RifeWang Date: Tue, 29 Oct 2024 00:25:56 +0800 Subject: [PATCH] k8s image gc --- content/posts/kubernetes/k8s-image-gc.md | 45 ++++++++++++++++++++++++ content/resume/resume.md | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 content/posts/kubernetes/k8s-image-gc.md diff --git a/content/posts/kubernetes/k8s-image-gc.md b/content/posts/kubernetes/k8s-image-gc.md new file mode 100644 index 0000000..823d417 --- /dev/null +++ b/content/posts/kubernetes/k8s-image-gc.md @@ -0,0 +1,45 @@ ++++ +draft = false +date = 2024-10-28T23:10:53+08:00 +title = "Kubernetes Node 节点上的镜像管理" +description = "Kubernetes Node 节点上的镜像管理" +slug = "" +authors = [] +tags = ["Kubernetes"] +categories = ["Kubernetes"] +externalLink = "" +series = [] +disableComments = true ++++ + +本文将详细介绍 Kubernetes 如何管理节点上的镜像。 + +## 拉取镜像 + +![](https://raw.githubusercontent.com/RifeWang/images/master/k8s/kubelet/kubelet-image-gc.drawio.png) + +`Kubelet` 通过 gRPC 协议与 `CRI` 组件(如 `containerd`、`cri-o`)进行交互。在创建新 Pod 时,`kubelet` 调用 gRPC 的 `ImageService.PullImage` 方法,由 `CRI` 组件将镜像下载到节点上。镜像在磁盘上的组织和管理由 `CRI` 组件负责,不同的 CRI 组件存在差异。 + +`Containerd` 的配置文件默认为 `/etc/containerd/config.toml`,其中的配置项 `root=/var/lib/containerd/` 指定了存储路径(这是一个根目录,内部会再细分子目录)。 + +`Cri-o` 存储相关的配置文件则是 `/etc/containers/storage.conf`,其中的配置项 `root=/var/lib/containers/storage` 指定存储路径,另外存在一个配置项 `imagestore` 可以单独指定镜像的存储位置。 + +## Image GC + +![](https://raw.githubusercontent.com/RifeWang/images/master/k8s/kubelet/kubelet-image-gc.drawio.png) + +`Kubelet` 通过垃圾回收策略来管理镜像的删除,相关的配置项包括: +- `imageMinimumGCAge`:默认值为 2 分钟,表示镜像的最小存在时间,避免在垃圾回收时删除过于新的镜像。 +- `imageMaximumGCAge`:默认值为 0 秒(表示不开启此特性),表示镜像的最大存在时间(此特性在 v1.30 中引入)。如果镜像自上次使用以来的时间超过此值,该镜像将被删除。 +- `imageGCHighThresholdPercent`:默认值是 85,当磁盘的使用率大于等于 85%,触发镜像的垃圾回收。 +- `imageGCLowThresholdPercent`:默认值是 80,镜像垃圾回收过程中,一旦磁盘使用率小于等于 80%,则停止删除镜像。 + +`Kubelet` 每隔 5 分钟(这个值在代码中写死了),不停的循环以下对镜像的 GC 过程: +1. `imagesInEvictionOrder`:kubelet 向 CRI 发起 `ImageService.ListImages`、`RuntimeService.ListPodSandbox`、`RuntimeService.ListContainers` 三个 gRPC 请求,以获取该节点上所有镜像的使用信息,并按上次使用时间排序。 +2. `freeOldImages`:如果镜像从上一次使用至今的时间间隔超过了 `imageMaximumGCAge`,kubelet 会向 CRI 发起 `ImageService.RemoveImage` 请求,删除这些镜像。 +3. `ImageFsStats`:kubelet 发 CRI 发起 `ImageService.ImageFsInfo` 请求(cri-o 依赖于 cadvisor),以获取磁盘使用情况。 +4. `freeSpace`:当磁盘使用率大于等于 `imageGCHighThresholdPercent` 高水位线时,触发镜像的删除行为,镜像会按照时间顺序从最久未被使用开始,一个接一个被删除,每删除完一个镜像都会判断一次磁盘使用率是否小于等于 `imageGCLowThresholdPercent` 低水位线,一旦降至低水位线,则停止删除镜像。 + +## 总结 + +在 node 节点上,镜像由 `CRI` 组件(如 `containerd`、`cri-o`)管理。kubelet 每 5 分钟进行一次镜像的垃圾回收。如果配置了 `imageMaximumGCAge` 镜像的最大存在时间,则不管磁盘使用率是否达到高水位线,都会删除符合条件的镜像。之后,镜像的删除将依据 `imageGCHighThresholdPercent`、`imageGCLowThresholdPercent` 高低水位线的配置来触发,具体删除操作由 CRI 组件执行,而 kubelet 仅负责发起 gRPC 调用。 \ No newline at end of file diff --git a/content/resume/resume.md b/content/resume/resume.md index a4c90b9..a82708e 100644 --- a/content/resume/resume.md +++ b/content/resume/resume.md @@ -42,11 +42,11 @@ disableComments = true 个人职责: - Team Leader,实施 Scrum 敏捷开发,协调团队成员工作,组织产品的上线发版。 +- 优化研发流程,组织 code review,关注团队成员的发展,结合公司发展方向组织对团队成员的技术培训。 - 架构设计和演化,包含技术选型、制定架构演进方案、组织技术评审、追踪并确保技术落地。 - 日常编码,实现业务需求,包括接口设计、数据库建模、缓存、消息队列、对象存储、serverless 集成,以及医学影像处理系统和自研算法集成。 - 构建可观测性系统,采集日志、追踪、指标,搭建数据报表与可视化数据分析大屏。 - 系统优化,深入整体架构、业务流、数据流、各组件等多角度优化系统,保障系统的高性能、可扩展、高质量。 -- 关注团队成员的发展,结合公司发展方向组织对团队成员的技术培训。 - 实施 DevOps 和云原生,负责 Kubernetes 基础设施、Argo-workflows 任务编排引擎、及其它云原生工具。