垃圾回收
垃圾回收是 Kubernetes 用于清理集群资源的各种机制的统称。这允许清理以下资源
- 已终止的 Pod
- 已完成的作业
- 没有所有者引用的对象
- 未使用的容器和容器镜像
- 使用“删除”存储类回收策略的动态配置的持久卷
- 陈旧或已过期的证书签名请求 (CSR)
- 节点 在以下情况下被删除
- 在云中,当集群使用 云控制器管理器 时
- 在本地,当集群使用类似于云控制器管理器的附加组件时
- 节点租约对象
所有者和依赖项
Kubernetes 中的许多对象通过 所有者引用 相互链接。所有者引用告诉控制平面哪些对象依赖于其他对象。Kubernetes 使用所有者引用来为控制平面和其他 API 客户端提供机会,在删除对象之前清理相关资源。在大多数情况下,Kubernetes 会自动管理所有者引用。
所有权不同于某些资源也使用的 标签和选择器 机制。例如,考虑一个 服务,它创建 EndpointSlice
对象。服务使用标签来允许控制平面确定哪些 EndpointSlice
对象用于该服务。除了标签之外,每个代表服务管理的 EndpointSlice
都具有所有者引用。所有者引用有助于 Kubernetes 的不同部分避免干扰它们不控制的对象。
注意
跨命名空间所有者引用在设计上是被禁止的。命名空间依赖项可以指定集群范围或命名空间所有者。命名空间所有者**必须**存在于与依赖项相同的命名空间中。如果不存在,则所有者引用将被视为不存在,并且依赖项将在所有所有者被验证不存在后被删除。
集群范围的依赖项只能指定集群范围的所有者。在 v1.20+ 中,如果集群范围的依赖项将命名空间类型指定为所有者,则它将被视为具有不可解析的所有者引用,并且无法进行垃圾回收。
在 v1.20+ 中,如果垃圾收集器检测到无效的跨命名空间 ownerReference
,或者集群范围的依赖项具有引用命名空间类型的 ownerReference
,则会报告一个带有原因 OwnerRefInvalidNamespace
和 involvedObject
为无效依赖项的警告事件。您可以通过运行 kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace
来检查该类型的事件。
级联删除
Kubernetes 检查并删除不再具有所有者引用的对象,例如当您删除副本集时遗留的 Pod。当您删除对象时,您可以控制 Kubernetes 是否自动删除对象的依赖项,这个过程称为级联删除。级联删除有两种类型,如下所示
- 前台级联删除
- 后台级联删除
您还可以使用 Kubernetes 终结器 来控制垃圾回收删除具有所有者引用的资源的方式和时间。
前台级联删除
在前台级联删除中,您要删除的所有者对象首先进入正在删除状态。在此状态下,将对所有者对象执行以下操作
- Kubernetes API 服务器将对象的
metadata.deletionTimestamp
字段设置为对象被标记为要删除的时间。 - Kubernetes API 服务器还将
metadata.finalizers
字段设置为foregroundDeletion
。 - 该对象将通过 Kubernetes API 保持可见,直到删除过程完成。
所有者对象进入正在删除状态后,控制器会删除依赖项。删除所有依赖项对象后,控制器会删除所有者对象。此时,该对象在 Kubernetes API 中不再可见。
在前台级联删除期间,唯一阻止所有者删除的依赖项是那些具有 ownerReference.blockOwnerDeletion=true
字段的依赖项。请参阅 使用前台级联删除 了解详细信息。
后台级联删除
在后台级联删除中,Kubernetes API 服务器会立即删除所有者对象,而控制器会在后台清理依赖项对象。默认情况下,Kubernetes 使用后台级联删除,除非您手动使用前台删除,或者选择使依赖项对象成为孤儿。
请参阅 使用后台级联删除 了解详细信息。
孤儿依赖项
当 Kubernetes 删除所有者对象时,留下的依赖项称为孤儿对象。默认情况下,Kubernetes 会删除依赖项对象。要了解如何覆盖此行为,请参阅 删除所有者对象并使依赖项成为孤儿。
未使用的容器和镜像的垃圾回收
在 kubelet 每两分钟对未使用的镜像进行一次垃圾回收,每分钟对未使用的容器进行一次垃圾回收。您应该避免使用外部垃圾回收工具,因为这些工具可能会破坏 kubelet 行为并删除应该存在的容器。
要配置未使用的容器和镜像垃圾回收的选项,请使用 配置文件 调整 kubelet,并使用 KubeletConfiguration
资源类型更改与垃圾回收相关的参数。
容器镜像生命周期
Kubernetes 通过其镜像管理器(它是 kubelet 的一部分)与 cadvisor 协作,管理所有镜像的生命周期。kubelet 在进行垃圾回收决策时会考虑以下磁盘使用限制
HighThresholdPercent
LowThresholdPercent
磁盘使用量超过配置的 HighThresholdPercent
值将触发垃圾回收,这将根据上次使用时间按顺序删除镜像,从最旧的镜像开始。kubelet 会删除镜像,直到磁盘使用量达到 LowThresholdPercent
值。
对未使用的容器镜像进行垃圾回收
Kubernetes v1.30 [beta]
作为一项 beta 功能,您可以指定本地镜像可以保持未使用状态的最长时间,而不管磁盘使用量如何。这是一个 kubelet 设置,您需要为每个节点配置它。
要配置此设置,请为 kubelet 启用 ImageMaximumGCAge
功能网关,并为 kubelet 配置文件中的 imageMaximumGCAge
字段设置一个值。
该值指定为 Kubernetes 持续时间;kubelet 配置文件中 imageMaximumGCAge
字段的有效时间单位是
- "ns" 表示纳秒
- "us" 或 "µs" 表示微秒
- "ms" 表示毫秒
- "s" 表示秒
- "m" 表示分钟
- "h" 表示小时
例如,您可以将配置字段设置为 12h45m
,这意味着 12 小时 45 分钟。
注意
此功能不会跟踪 kubelet 重启之间的镜像使用情况。如果 kubelet 重启,跟踪的镜像年龄将重置,导致 kubelet 等待完整的imageMaximumGCAge
持续时间,然后再根据镜像年龄对镜像进行垃圾回收资格。容器垃圾回收
kubelet 根据以下变量对未使用的容器进行垃圾回收,您可以定义这些变量
MinAge
:kubelet 可以对容器进行垃圾回收的最小年龄。通过设置为0
来禁用。MaxPerPodContainer
:每个 Pod 可以拥有的最大死亡容器数量。通过设置为小于0
来禁用。MaxContainers
:集群可以拥有的最大死亡容器数量。通过设置为小于0
来禁用。
除了这些变量之外,kubelet 还会对无法识别的和已删除的容器进行垃圾回收,通常从最旧的容器开始。
MaxPerPodContainer
和 MaxContainers
可能会在保留每个 Pod 的最大容器数量 (MaxPerPodContainer
) 会超出全局允许的死亡容器总数 (MaxContainers
) 的情况下发生冲突。在这种情况下,kubelet 会调整 MaxPerPodContainer
来解决冲突。最坏的情况是将 MaxPerPodContainer
降级为 1
并逐出最旧的容器。此外,一旦被删除的 Pod 拥有的容器的年龄超过 MinAge
,它们就会被删除。
注意
kubelet 仅对它管理的容器进行垃圾回收。配置垃圾回收
您可以通过配置特定于管理这些资源的控制器的选项来调整资源的垃圾回收。以下页面将向您展示如何配置垃圾回收
下一步
- 详细了解 Kubernetes 对象的所有权。
- 详细了解 Kubernetes 终结器。
- 了解 TTL 控制器,它会清理已完成的作业。