在动态且复杂的 Kubernetes 编排系统中,资源的创建与销毁是家常便饭。如果缺乏有效的自动清理机制,废弃的资源(或称“数字垃圾”)会迅速堆积,侵蚀集群的存储与性能,甚至引发服务中断。而 Kubernetes 的垃圾收集(Garbage Collection, GC)机制,正是维护集群整洁与健康的“幕后功臣”。
本文将深入剖析 Kubernetes 垃圾收集的两个核心部分:对象级联删除和容器/镜像生命周期管理,揭示其自动化清理的精妙设计。
一、对象级联删除:基于属主-依赖关系的智能清理
Kubernetes 中的对象并非孤立存在,它们通过属主引用(Owner Reference)形成了紧密的依赖网络。例如,一个 Deployment 是其所创建 ReplicaSet 的属主,而 ReplicaSet 又是其管理下 Pod 的属主。这种层级关系正是自动化清理得以实现的基础。
1. 属主与依赖(Owners and Dependents)
- 核心概念:当一个对象 A 创建了对象 B,A 就成为 B 的属主(Owner),B 则成为 A 的依赖(Dependent)。这种关系通过 B 对象
metadata.ownerReferences 字段中的指针来记录。
- 设计约束:为了保证名字空间的隔离性,Kubernetes 不允许跨名字空间的属主引用。名字空间内的依赖对象只能指向同一名字空间内的属主或集群作用域的属主。
2. 级联删除(Cascading Deletion)
当你删除一个拥有依赖对象的属主时,Kubernetes 提供了两种主要策略来处理其依赖项:

- 遗弃依赖 (Orphaned Dependents): 用户也可以选择在删除属主时不删除其依赖对象,这些被留下的对象称为“孤儿”。它们的
ownerReferences 会被清除,成为一个独立的、无属主的对象。
二、容器与镜像的垃圾收集:守护节点磁盘空间
除了 API 对象,运行在节点上的容器和镜像也是消耗磁盘空间的大户。节点代理 kubelet 组件内置了专门的垃圾收集器来管理它们的生命周期。
1. 容器垃圾收集
kubelet 每分钟都会检查并清理未使用的容器,主要依据以下可配置的策略:
MinAge: 容器必须至少存活超过此时间才能被考虑回收。这防止了刚退出的容器被立即清理,便于调试。
MaxPerPodContainer: 每个 Pod 最多保留的已终止容器数量(用于查看日志和状态)。超出的部分会被删除。
MaxContainers: 节点上全局允许存在的已终止容器总数上限。
当 MaxPerPodContainer 和 MaxContainers 发生冲突时(例如,保留每个 Pod 的最大容器数会导致总数超标),kubelet 会动态降低 MaxPerPodContainer 的有效值,优先保证全局上限不被突破。
2. 镜像垃圾收集
kubelet 每五分钟执行一次镜像垃圾收集,以防止磁盘被无用的镜像占满。其策略基于磁盘使用率和镜像年龄:
- 基于磁盘压力的回收:
HighThresholdPercent (默认 85%): 当磁盘使用率超过此阈值时,触发垃圾收集。
LowThresholdPercent (默认 80%): 垃圾收集会持续删除镜像,直到磁盘使用率降至该阈值以下。
- 删除顺序: 优先删除最近最少使用(LRU) 的镜像。
- 基于年龄的回收:
imageMaximumGCAge: 即使磁盘空间充足,任何超过此年龄且未被任何容器使用的镜像也会被删除。
- 注意: 此计时器在
kubelet 重启后会重置。
三、其他关键资源的垃圾收集
Kubernetes 的垃圾收集机制覆盖面很广,还包括以下资源的自动清理:
- 已完成的 Job: 通过
TTLSecondsAfterFinished 字段,可以自动清理已完成(成功或失败)的 Job 及其关联的 Pod。
- 动态制备的 PV: 当
PersistentVolume 的 persistentVolumeReclaimPolicy 设置为 Delete 时,删除对应的 PersistentVolumeClaim (PVC) 会触发底层存储卷(如云硬盘)的自动删除。
- 过期的 CSR:
CertificateSigningRequest 在被批准、拒绝或长时间未处理后会被自动清理。
- 失效的节点: 当
kubelet 停止发送心跳,节点控制器会将 Node 对象标记为 Unknown,并在超时后将其删除。同时,与该节点相关的 Lease 对象也会被清理。
四、总结
Kubernetes 的垃圾收集是一个多层次、全方位的自动化系统。它通过属主-依赖模型实现了对象间优雅的级联删除,通过 kubelet 内置的回收器守护着节点的磁盘健康,并通过各种专用控制器清理特定类型的临时资源。
深入理解这套机制,对于集群运维至关重要:
- 它能帮助我们预测资源清理的行为,避免因意外删除造成数据丢失。
- 它指导我们合理配置
kubelet 的 GC 参数,从而优化节点性能与资源利用率。
- 它让我们能够构建出更加健壮、具备自维持能力的云原生应用环境。
正是这些贯穿始终的自动化清理能力,共同铸就了 Kubernetes 作为现代基础设施平台的可靠性基石。希望本文能帮助你更好地驾驭集群的资源生命周期,如果你想探讨更多云原生运维实践,欢迎来云栈社区交流。
|