How Does Garbage Collection Work in Kubernetes?

intermediate|architecturedevopssreplatform engineerCKA
TL;DR

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:

  1. The deletionTimestamp is set
  2. The object continues to exist
  3. Controllers process their finalizers and remove them
  4. 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

  1. Stuck Terminating namespaces: Usually caused by a finalizer whose controller is not running. Check kubectl get namespace stuck-ns -o json | jq '.spec.finalizers'.
  2. Orphaned ReplicaSets accumulating: Check revisionHistoryLimit on Deployments — it defaults to 10. Set it lower in large clusters.
  3. Completed Jobs not cleaned up: Set ttlSecondsAfterFinished on Jobs, or use a CronJob to clean them.
  4. PVCs stuck in Terminating: The kubernetes.io/pvc-protection finalizer 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

What are owner references and how do they work?
Owner references are metadata fields on child objects pointing to their parent. When the parent is deleted, the garbage collector automatically deletes all children with matching owner references.
What is the difference between foreground and background cascading deletion?
In foreground deletion, the parent is not deleted until all children are gone. In background deletion, the parent is deleted immediately and children are cleaned up asynchronously.
How can you delete a parent without deleting its children?
Use orphan deletion: kubectl delete deployment my-app --cascade=orphan. The children (ReplicaSets, Pods) remain running without an owner.

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.

Related Questions

You Might Also Like