Kubernetes集群架构-垃圾回收
- [Kubernetes 集群架构 - 垃圾回收](#Kubernetes 集群架构 - 垃圾回收)
 - 链接
 
Kubernetes 集群架构 - 垃圾回收
垃圾回收是 Kubernetes 用于清理集群内资源的各种机制的统称。支持清理如下资源:
- 已终止的 Pod
 - 已完成的 Job
 - 没有属主引用的对象
 - 未使用的容器和容器镜像
 - 
动态配置的持久卷,其 StorageClass 回收策略为 Delete\]( [已完成的 Job](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/))
 - 在以下情况下删除的节点:
- 当集群使用云控制器管理器运行于云端时
 - 当集群使用类似于云控制器管理器的插件运行在本地环境中时。
 - 节点租约对象
 
 
属主与依赖
Kubernetes 中的许多对象通过属主引用相互链接。属主引用告诉控制平面对象之间的相互依赖关系。Kubernetes 控制平面和其他 API 客户端基于属主引用在删除对象之前清理相关资源。在大多数情况下,Kubernetes 会自动管理属主引用。
所有权不同于某些资源也使用的标签和选择器机制。例如,考虑一个创建 EndpointSlice 对象的Service。Service 使用标签来允许控制平台确定哪些 EndpointSlice 对象用于该 Service。除了标签之外,被 Service 托管的每个 EndpointSlice 都有一个属主引用。属主引用可以帮助 Kubernetes 中的不同组件避免干预并非由它们控制的对象。
设计上不允许跨命名空间的属主引用。命名空间依赖项可以指定集群范围或命名空间内的属主。命名空间属主必须与依赖项存在于同一命名空间中。否则,属主引用将被视为不存在,并且在验证所有属主都不存在后,依赖项将被删除。
群集范围的依赖项只能指定群集范围的属主。在 v1.20+ 中,如果集群范围的依赖项将命名空间类型指定为属主,则它被视为具有无法解析的属主引用,并且无法进行垃圾回收。
在 v1.20+ 中,如果垃圾回收器检测到无效的跨命名空间的属主引用,或者检测到集群范围的依赖项,其中 属主引用引用了命名空间类型,则会发出一个警告事件,原因为OwnerRefInvalidNamespace和一个无效依赖项的involvedObject。可以通过运行kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace来检查此类事件。
级联删除
Kubernetes 会检查并删除不再具有属主引用的对象,例如删除 ReplicaSet 时留下的 Pod。删除对象时,用户可以控制 Kubernetes 是否自动删除对象的依赖项,这种机制成为级联删除。级联删除有两种类型,如下所示:
- 前台级联删除
 - 后台级联删除
 
还可以使用 Kubernetes 终结器控制垃圾回收如何以及何时删除具有属主引用的资源。
前台级联删除
在前台级联删除中,要删除的属主对象首先进入 deletion in progress 状态。在此状态下,属主对象将发生如下变化:
- Kubernetes API 服务器将对象的 
metadata.deletionTimestamp字段设置为对象被标记为删除的时间。 - Kubernetes API 服务器还将 
metadata.finalizers字段设置为foregroundDeletion。 - 在删除过程完成之前,通过 Kubernetes API 仍然可以看到该对象。
 
在属主对象进入 deletion in progress 状态后,控制器会删除它知道的依赖项。在删除了它知道的所有依赖对象后,控制器会删除属主对象。此时,该对象在 Kubernetes API 中不再可见。
在前台级联删除期间,唯一会阻止属主对象被删除的是那些带有 ownerReference.blockOwnerDeletion=true 字段并且存在于垃圾收集控制器缓存中的依赖对象。 垃圾收集控制器缓存中可能不包含那些无法成功被列举/监视的资源类型的对象, 或在属主对象删除的同时创建的对象。 参阅使用前台级联删除以了解进一步的细节。
后台级联删除
在后台级联删除中,Kubernetes API 服务器会立即删除属主对象,垃圾回收器控制器(自定义或默认)会在后台清理依赖对象。如果存在终结器,则它可以确保在完成所有必要的清理任务之前不会删除对象。默认情况下,Kubernetes 使用后台级联删除,除非手动使用前台删除或选择遗弃依赖对象。
请参阅使用后台级联删除以了解更多信息。
被遗弃的依赖对象
当 Kubernetes 删除属主对象时,留下的依赖项称为孤立对象。默认情况下,Kubernetes 会删除依赖对象。要了解如何覆盖此行为,请参阅删除属主对象和孤立依赖项。
未使用容器和镜像的垃圾回收
kubelet 每 5 分钟对未使用的镜像执行一次垃圾回收,每分钟对未使用的容器执行一次垃圾回收。应该避免使用外部垃圾收集工具,因为它们可能破坏 kubelet 行为并删除应该存在的容器。
要为未使用的容器和镜像垃圾回收配置选项,可以使用一个配置文件,基于 KubeletConfiguration 资源类型来调整与垃圾收集相关的 kubelet 行为。
容器镜像生命周期
Kubernetes 通过其镜像管理器管理所有镜像的生命周期,该管理器是 kubelet 的一部分,与 cAdvisor[1](#1) 合作。kubelet 在做出垃圾回收决策时会考虑以下磁盘使用限制:
HighThresholdPercentLowThresholdPercent
磁盘使用量高于配置的 HighThresholdPercent 值会触发垃圾回收,该回收会根据上次使用镜像的时间按顺序删除镜像,首先删除的是最近未使用的镜像。kubelet 会删除镜像,直到磁盘使用率达到 LowThresholdPercent 值。
未使用容器镜像的垃圾收集
功能状态:Kubernetes v1.30 [beta] (默认启用:true)
作为 Beta 版功能,可以指定本地镜像允许未使用的最长时间,而不管磁盘使用情况如何。可为每个节点的 kubelet 设置。
要配置该设置,需要在 kubelet 配置文件中为 imageMaximumGCAge 字段设置一个值。
该值指定为 Kubernetes 持续时间。有关更多详细信息,请参阅术语表中的 duration。
例如,可以将配置字段设置为 12h45m,即 12 小时 45 分钟。
此功能不会跟踪 kubelet 重启期间的镜像使用情况。如果 kubelet 重新启动,则跟踪的镜像年龄将被重置,从而导致 kubelet 等待完整的
imageMaximumGCAge持续时间,然后才能根据镜像年龄确定镜像的垃圾回收资格。
容器垃圾收集
kubelet 垃圾回收基于以下变量的容器,可以定义这些变量:
MinAge:kubelet 可以对容器进行垃圾回收的最小年龄。通过设置为 0 来禁用。MaxPerPodContainer:每个 Pod 可以拥有的最大死容器数。通过设置为小于 0 来禁用。MaxContainers:集群可以拥有的最大失效容器数。通过设置为小于 0 来禁用。
除了这些变量之外,kubelet 垃圾回收未识别和已删除的容器,通常从最早的容器开始。
当保持每个 Pod 的最大数量的容器(MaxPerPodContainer)会使得全局的已死亡容器个数超出上限 (MaxContainers``)时,MaxPerPodContainer 和 MaxContainers 之间可能会出现冲突。 在这种情况下,kubelet 会调整 MaxPerPodContainer 来解决这一冲突。 最坏的情形是将 MaxPerPodContainer 降格为 1,并驱逐最近未使用的容器。 此外,当隶属于某已被删除的 Pod 的容器的年龄超过 MinAge 时,它们也会被删除。
kubelet 只对它管理的容器进行垃圾回收。
配置垃圾收集
可以通过配置特定于管理这些资源的控制器的选项来优化资源的垃圾回收。以下页面展示如何配置垃圾回收:
链接
- Kubernetes Cluster Architecture Garbage Collection
 - Pod 生命周期
 - 已完成的 Job 的自动清理
 - 持久卷
 - 证书和证书签名请求
 - 属主依赖
 - 标签和选择器机制
 - 使用前台级联删除
 - 使用后台级联删除
 - 删除属主对象和孤立依赖项
 - 使用配置文件配置 Kubelet 参数
 - 术语表
 - 配置 Kubernetes 对象的级联删除
 - 配置已完成 Job 的清理
 
- cAdvisor(Container Advisor)是一款开源的容器资源监控和性能分析工具,能实时收集容器及宿主机的CPU、内存、磁盘I/O和网络等资源使用指标 。 ↩︎