How Does Garbage Collection Work in Kubernetes?
Kubernetes garbage collection automatically cleans up resources that are no longer needed, using owner references to cascade deletion from parent to child objects. It supports foreground, background, and orphan deletion strategies.
Detailed Answer
Garbage collection in Kubernetes automatically removes objects that are no longer needed. The most important mechanism is cascading deletion through owner references, but garbage collection also covers terminated Pods, completed Jobs, unused container images, and finished nodes.
Owner References
Most Kubernetes objects form a hierarchy. A Deployment owns ReplicaSets, which own Pods. This ownership is tracked through ownerReferences in object metadata:
apiVersion: v1
kind: Pod
metadata:
name: web-abc123-xyz
ownerReferences:
- apiVersion: apps/v1
kind: ReplicaSet
name: web-abc123
uid: "12345-67890"
controller: true
blockOwnerDeletion: true
When you delete the Deployment, the garbage collector follows the chain: Deployment → ReplicaSet → Pods.
Three Deletion Strategies
1. Background (Default)
kubectl delete deployment web
# Or explicitly:
kubectl delete deployment web --cascade=background
The Deployment is removed from the API server immediately. The garbage collector asynchronously discovers and deletes child ReplicaSets and Pods.
2. Foreground
kubectl delete deployment web --cascade=foreground
The Deployment enters a "deletion in progress" state. Its metadata.deletionTimestamp is set and the foregroundDeletion finalizer is added. The garbage collector deletes all children first, then removes the parent.
This is useful when you need to guarantee children are fully cleaned up before the parent disappears.
3. Orphan
kubectl delete deployment web --cascade=orphan
The Deployment is deleted, but its ReplicaSets and Pods continue running with no owner. This is useful for:
- Migrating resources between owners
- Blue-green deployments where you want old Pods to keep running
- Debugging — keeping Pods alive after deleting their controller
Visualizing Owner References
# See owner references on a Pod
kubectl get pod web-abc123-xyz -o jsonpath='{.metadata.ownerReferences}' | jq .
# Find all Pods owned by a ReplicaSet
kubectl get pods --field-selector metadata.ownerReferences[0].name=web-abc123
# More practically — find orphaned Pods
kubectl get pods --all-namespaces -o json | \
jq '.items[] | select(.metadata.ownerReferences == null) | .metadata.name'
What Gets Garbage Collected
| Resource | Collector | Trigger |
|----------|-----------|---------|
| Child objects (Pods, RS) | GC controller | Parent deleted |
| Terminated Pods | kubelet | Exceeds terminated-pod-gc-threshold |
| Completed Jobs | TTL controller | ttlSecondsAfterFinished expires |
| Container images | kubelet | Disk usage exceeds imageGCHighThresholdPercent |
| Unused containers | kubelet | Container age exceeds minimumGCAge |
TTL Controller for Finished Jobs
The TTL-after-finished controller automatically cleans up completed Jobs:
apiVersion: batch/v1
kind: Job
metadata:
name: data-migration
spec:
ttlSecondsAfterFinished: 3600 # Clean up 1 hour after completion
template:
spec:
containers:
- name: migrate
image: migration-tool:1.0
resources:
requests:
cpu: "100m"
memory: "128Mi"
restartPolicy: Never
Finalizers and Garbage Collection
Finalizers are keys on an object that tell Kubernetes "do not delete this until a controller removes my finalizer." They prevent premature deletion:
metadata:
finalizers:
- kubernetes.io/pv-protection
- foregroundDeletion
When you delete an object with finalizers:
- The
deletionTimestampis set - The object continues to exist
- Controllers process their finalizers and remove them
- The object is deleted when all finalizers are removed
If a finalizer's controller is broken, the object is stuck in Terminating state forever. To unstick it (use with caution):
kubectl patch pod stuck-pod -p '{"metadata":{"finalizers":null}}'
Kubelet Image Garbage Collection
The kubelet periodically cleans up container images to free disk space:
# kubelet configuration
imageGCHighThresholdPercent: 85 # Start GC when disk is 85% full
imageGCLowThresholdPercent: 80 # Stop GC when disk drops to 80%
imageMinimumGCAge: 2m # Don't GC images younger than 2 minutes
Common Issues
- Stuck Terminating namespaces: Usually caused by a finalizer whose controller is not running. Check
kubectl get namespace stuck-ns -o json | jq '.spec.finalizers'. - Orphaned ReplicaSets accumulating: Check
revisionHistoryLimiton Deployments — it defaults to 10. Set it lower in large clusters. - Completed Jobs not cleaned up: Set
ttlSecondsAfterFinishedon Jobs, or use a CronJob to clean them. - PVCs stuck in Terminating: The
kubernetes.io/pvc-protectionfinalizer prevents deletion while a Pod is still mounting the volume.
Why Interviewers Ask This
Interviewers ask this to verify you understand how Kubernetes manages resource lifecycle, prevents orphaned objects, and handles cascading deletes — essential for troubleshooting missing or lingering resources.
Common Follow-Up Questions
Key Takeaways
- Owner references create a parent-child relationship that the garbage collector uses for cascading deletion.
- Background deletion (default) removes the parent immediately and cleans up children asynchronously.
- Orphan deletion intentionally leaves child resources running, useful for blue-green transitions.