垃圾收集
Kubernetes 垃圾收集器(Garbage Collector)是集群中的重要组件,负责清理失去所有者关系的孤儿对象。掌握垃圾收集机制对于高效管理 Kubernetes 资源、避免资源泄漏至关重要。
Owner 和 Dependent 对象关系
核心概念
在 Kubernetes 中,对象之间存在所有权关系:
- Owner 对象:拥有其他对象的资源
- Dependent 对象:被其他对象拥有的资源
常见的所有权关系包括:
Owner 对象 | Dependent 对象 |
---|---|
Deployment | ReplicaSet |
ReplicaSet | Pod |
Service | Endpoints |
Job | Pod |
StatefulSet | Pod |
每个 Dependent 对象都有一个 metadata.ownerReferences
字段,指向其 Owner 对象。
ownerReference 字段结构
ownerReferences:
- apiVersion: apps/v1
kind: ReplicaSet
name: my-repset
uid: d9607e19-f88f-11e6-a518-42010a800195
controller: true
blockOwnerDeletion: true
字段说明:
apiVersion
:Owner 对象的 API 版本kind
:Owner 对象的类型name
:Owner 对象的名称uid
:Owner 对象的唯一标识符controller
:是否为控制器管理的对象blockOwnerDeletion
:是否阻止 Owner 对象删除
自动设置 ownerReference
Kubernetes 在以下场景自动设置 ownerReference
:
控制器管理的对象
- ReplicationController、ReplicaSet、Deployment
- StatefulSet、DaemonSet
- Job、CronJob
服务发现相关
- Service 创建的 Endpoints
- Ingress 相关的资源
存储相关
- PersistentVolumeClaim 和 PersistentVolume 的关系
实践示例
创建一个 ReplicaSet 来观察 ownerReference 的设置:
# my-repset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: my-repset
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: gc-demo
template:
metadata:
labels:
app: gc-demo
spec:
containers:
- name: nginx
image: nginx:1.25
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
部署并查看 ownerReference:
# 创建 ReplicaSet
kubectl apply -f my-repset.yaml
# 查看 Pod 的 ownerReference
kubectl get pods -l app=gc-demo -o yaml | grep -A 8 ownerReferences
# 查看详细信息
kubectl describe pod <pod-name>
级联删除策略
删除 Owner 对象时,可以通过不同的级联删除策略控制 Dependent 对象的处理方式。
Background 级联删除
默认策略,适用于大多数场景。
执行流程:
- 立即删除 Owner 对象
- 垃圾收集器在后台异步删除 Dependent 对象
- Owner 对象从 API 服务器中立即移除
优势:删除速度快,不阻塞操作
适用场景:日常资源清理、快速释放资源
Foreground 级联删除
顺序删除,确保完全清理。
执行流程:
- Owner 对象进入"删除中"状态
- 设置
deletionTimestamp
字段 - 添加
foregroundDeletion
finalizer - 等待所有 Dependent 对象删除完成
- 最后删除 Owner 对象
特点:
- Owner 对象在删除过程中仍可通过 API 访问
- 确保子资源完全清理
- 删除时间较长
适用场景:需要确保完全清理的关键资源
Orphan 策略
孤儿模式,保留子资源。
执行流程:
- 删除 Owner 对象
- 清空 Dependent 对象的
ownerReferences
字段 - Dependent 对象成为孤儿,继续存在
适用场景:
- 需要保留子资源的场景
- 资源迁移和重构
- 手动管理子资源
删除策略实际操作
使用 kubectl 命令
# 默认级联删除(Background 模式)
kubectl delete replicaset my-repset
# 显式指定 Background 模式
kubectl delete replicaset my-repset --cascade=background
# Foreground 模式
kubectl delete replicaset my-repset --cascade=foreground
# Orphan 模式
kubectl delete replicaset my-repset --cascade=orphan
使用 YAML 文件控制
# delete-options.yaml
apiVersion: v1
kind: DeleteOptions
propagationPolicy: Foreground
kubectl delete -f my-repset.yaml --delete-options=./delete-options.yaml
使用 API 直接控制
# 启动代理
kubectl proxy --port=8080 &
# Background 删除
curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Background"}' \
-H "Content-Type: application/json"
# Foreground 删除
curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
-H "Content-Type: application/json"
# Orphan 删除
curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
-H "Content-Type: application/json"
高级特性
blockOwnerDeletion 机制
blockOwnerDeletion
字段控制是否阻止 Owner 对象的删除:
ownerReferences:
- apiVersion: apps/v1
kind: ReplicaSet
name: my-repset
uid: d9607e19-f88f-11e6-a518-42010a800195
controller: true
blockOwnerDeletion: true # 阻止 Owner 删除
- 生效条件:仅在 Foreground 删除模式下生效
- 自动设置:Kubernetes 自动为控制器管理的对象设置
- 权限控制:需要相应的 RBAC 权限
Finalizers 与垃圾收集
Finalizers 是防止对象被删除的机制:
metadata:
finalizers:
- kubernetes.io/pv-protection
- custom-finalizer
查看和管理 finalizers:
# 查看对象的 finalizers
kubectl get pv <pv-name> -o yaml | grep -A 5 finalizers
# 移除 finalizer(谨慎操作)
kubectl patch pv <pv-name> -p '{"metadata":{"finalizers":null}}'
最佳实践
选择合适的删除策略
- 日常运维:使用 Background 删除(默认)
- 生产环境清理:使用 Foreground 删除确保完全清理
- 资源迁移:使用 Orphan 删除保留子资源
- 紧急情况:使用 Background 删除快速释放资源
监控和观察
# 监控垃圾收集器状态
kubectl get events --field-selector reason=SuccessfulDelete
# 查看孤儿对象
kubectl get pods --all-namespaces -o custom-columns=NAME:.metadata.name,NAMESPACE:.metadata.namespace,OWNER:.metadata.ownerReferences[0].name
# 检查长时间未删除的对象
kubectl get all --show-labels | grep deletionTimestamp
权限配置
确保垃圾收集器有足够权限:
# gc-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: system:gc-controller
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["list", "watch", "delete"]
性能优化
- 批量删除:使用标签选择器批量删除相关对象
- 定期清理:定期清理孤儿对象和无用资源
- 监控指标:监控垃圾收集器的性能指标
故障排查
常见问题及解决方案
对象无法删除
# 检查 finalizers kubectl get <resource> <name> -o yaml | grep -A 5 finalizers # 检查 blockOwnerDeletion kubectl get <resource> <name> -o yaml | grep -A 10 ownerReferences
删除时间过长
# 查看删除进度 kubectl get events --field-selector involvedObject.name=<name> # 检查 Dependent 对象状态 kubectl get all -l <label-selector>
孤儿对象累积
# 查找孤儿对象 kubectl get pods -o json | jq '.items[] | select(.metadata.ownerReferences == null)' # 清理孤儿对象 kubectl delete pods -l <label-selector> --cascade=orphan
调试工具
# 查看垃圾收集器日志
kubectl logs -n kube-system kube-controller-manager-<node-name> | grep garbage
# 查看对象删除历史
kubectl get events --sort-by='.lastTimestamp' | grep Delete
# 检查对象依赖关系
kubectl get <resource> <name> -o yaml | yq '.metadata.ownerReferences'
通过理解和正确使用 Kubernetes 垃圾收集机制,可以有效管理集群资源,避免资源泄漏,确保集群的稳定运行。