Housekeeping - Cluster Cleanup Service
Table of Contents
Overview
Housekeeping is an automated cluster maintenance service deployed in the Fako cluster. It runs as a CronJob that periodically cleans up completed and failed pods across all namespaces. This service helps maintain cluster hygiene by removing terminated pods that would otherwise accumulate and consume resources. It’s essential for keeping the cluster clean and preventing resource exhaustion from leftover pod metadata.
Key Features
- Automated Cleanup: Runs every hour to clean terminated pods
- Cluster-Wide: Scans all namespaces for cleanup candidates
- Safe Deletion: Only removes pods in Succeeded or Failed states
- Detailed Logging: Reports what was found and cleaned
- Concurrency Control: Prevents overlapping cleanup runs
- Statistics Tracking: Counts total pods found and deleted
- Force Deletion: Uses grace period 0 for immediate removal
- Job History: Keeps history of last 3 successful/failed runs
Architecture
Components
- CronJob: Scheduled execution every hour
- ServiceAccount: Cluster-wide permissions for pod management
- ClusterRole: Permissions to list and delete pods
- ConfigMap: Cleanup script with logic
- Container: kubectl image with bash script execution
Resource Requirements
- Image:
bitnami/kubectl:1.33 - CPU/Memory: Minimal (kubectl operations)
- Permissions: Cluster-wide pod list/delete
Configuration
Schedule
- CronJob Schedule:
0 * * * *(every hour at minute 0) - Concurrency Policy:
Forbid(no overlapping runs) - TTL After Finish: 3600 seconds (1 hour)
- History Limits: 3 successful, 3 failed jobs
Cleanup Targets
The service removes pods in these states:
- Succeeded: Completed jobs and one-time pods
- Failed: Crashed or errored pods
Usage
Manual Execution
Trigger immediate cleanup:
kubectl create job --from=cronjob/housekeeping manual-cleanup-$(date +%s) -n housekeeping
Monitoring Cleanup
Watch cleanup progress:
# View current job
kubectl logs -n housekeeping -l app=housekeeping -f
# List recent jobs
kubectl get jobs -n housekeeping --sort-by=.metadata.creationTimestamp
Viewing Statistics
Check cleanup history:
# Get logs from last successful job
kubectl logs -n housekeeping \
$(kubectl get pods -n housekeeping -l app=housekeeping --sort-by=.metadata.creationTimestamp -o name | tail -1)
Cleanup Process
1. Namespace Discovery
- Lists all namespaces in cluster
- Iterates through each namespace
2. Pod Identification
- Queries pods with status.phase == “Succeeded”
- Queries pods with status.phase == “Failed”
- Combines results for processing
3. Pod Details
- Retrieves pod age and phase
- Logs pod information before deletion
4. Force Deletion
- Deletes with grace-period=0
- Uses –force flag for immediate removal
- Tracks success/failure of each deletion
5. Statistics
- Counts total pods found
- Counts successfully deleted pods
- Reports summary at completion
Operations
Enable/Disable Cleanup
# Suspend housekeeping
kubectl patch cronjob housekeeping -n housekeeping -p '{"spec":{"suspend":true}}'
# Resume housekeeping
kubectl patch cronjob housekeeping -n housekeeping -p '{"spec":{"suspend":false}}'
Adjust Schedule
# Change to every 30 minutes
kubectl patch cronjob housekeeping -n housekeeping \
-p '{"spec":{"schedule":"*/30 * * * *"}}'
# Change to twice daily
kubectl patch cronjob housekeeping -n housekeeping \
-p '{"spec":{"schedule":"0 2,14 * * *"}}'
Exclude Namespaces
Edit the ConfigMap to exclude specific namespaces:
kubectl edit configmap housekeeping-script -n housekeeping
Add exclusion logic:
# Skip system namespaces
if [[ "$ns" =~ ^(kube-system|kube-public|kube-node-lease)$ ]]; then
continue
fi
Troubleshooting
Job Failures
- Check job status:
kubectl describe job -n housekeeping housekeeping-xxxxx
- View pod logs:
kubectl logs -n housekeeping job/housekeeping-xxxxx
- Common issues:
- Permission denied (RBAC)
- kubectl command failures
- Script syntax errors
Permission Issues
- Verify ServiceAccount:
kubectl get sa housekeeping -n housekeeping
- Check ClusterRole:
kubectl describe clusterrole housekeeping
- Test permissions:
kubectl auth can-i delete pods --all-namespaces \
--as=system:serviceaccount:housekeeping:housekeeping
No Pods Being Cleaned
- Check for completed pods:
kubectl get pods --all-namespaces --field-selector=status.phase=Succeeded
kubectl get pods --all-namespaces --field-selector=status.phase=Failed
- Verify jq installation:
kubectl exec -n housekeeping deployment/housekeeping -- which jq
Security Considerations
RBAC Permissions
- Limited to pod list and delete operations
- No access to secrets or configmaps
- Cannot modify running pods
Namespace Isolation
- Consider excluding sensitive namespaces
- Add namespace labels for filtering
- Implement allowlist/denylist
Audit Trail
- All deletions logged in job output
- Kubernetes audit logs track API calls
- Consider external log aggregation
Best Practices
- Test in staging: Verify behavior before production
- Monitor closely: Check logs after deployment
- Gradual rollout: Start with specific namespaces
- Set alerts: Monitor for failed cleanup jobs
- Regular review: Audit what’s being cleaned
Customization
Pod Age Filtering
Add age-based filtering:
# Only delete pods older than 24 hours
pod_age=$(kubectl get pod "$pod" -n "$namespace" \
-o jsonpath='{.metadata.creationTimestamp}')
if [[ $(date -d "$pod_age" +%s) -lt $(date -d '24 hours ago' +%s) ]]; then
kubectl delete pod "$pod" -n "$namespace"
fi
Label-Based Filtering
Clean only labeled pods:
# Only clean pods with cleanup=true label
labeled_pods=$(kubectl get pods -n "$namespace" \
-l cleanup=true \
--field-selector=status.phase=Succeeded \
-o jsonpath='{.items[*].metadata.name}')
Custom Notifications
Add Slack notifications:
# Send summary to Slack
curl -X POST "$SLACK_WEBHOOK" \
-H 'Content-type: application/json' \
-d "{\"text\":\"Housekeeping: Cleaned $TOTAL_DELETED pods from $namespace_count namespaces\"}"
Monitoring
Key Metrics
- Pods cleaned per run
- Namespaces processed
- Cleanup duration
- Failed deletions
- Job success rate
Prometheus Metrics
Add metrics exporter:
# Add pushgateway container
- name: metrics
image: prom/pushgateway
ports:
- containerPort: 9091
Push metrics from script:
# Push to Prometheus
echo "housekeeping_pods_deleted $TOTAL_DELETED" | \
curl --data-binary @- http://localhost:9091/metrics/job/housekeeping
Grafana Dashboard
Key panels:
- Pods cleaned over time
- Cleanup job duration
- Failed cleanup attempts
- Namespace distribution
Integration Examples
With Monitoring Stack
Alert on cleanup failures:
# PrometheusRule
- alert: HousekeepingFailed
expr: kube_job_status_failed{job_name=~"housekeeping-.*"} > 0
for: 1h
annotations:
summary: "Housekeeping job failed"
With CI/CD
Trigger cleanup after deployments:
# In deployment pipeline
- name: Trigger housekeeping
run: |
kubectl create job --from=cronjob/housekeeping \
post-deploy-cleanup-${{ github.run_id }} \
-n housekeeping
Maintenance
Regular Tasks
Daily:
- Review cleanup logs
- Check for failed jobs
Weekly:
- Analyze cleanup patterns
- Review excluded namespaces
- Check resource usage
Monthly:
- Update kubectl version
- Review RBAC permissions
- Optimize cleanup logic
Performance Tuning
For large clusters:
# Parallel namespace processing
for ns in $namespaces; do
cleanup_namespace "$ns" &
done
wait
Backup Considerations
Before major changes:
# Export current configuration
kubectl get cronjob housekeeping -n housekeeping -o yaml > housekeeping-backup.yaml
kubectl get cm housekeeping-script -n housekeeping -o yaml > script-backup.yaml
Advanced Features
Multi-Resource Cleanup
Extend to clean other resources:
# Clean completed jobs
kubectl delete jobs --all-namespaces \
--field-selector status.successful=1
# Clean old replicasets
kubectl get rs --all-namespaces -o json | \
jq -r '.items[] | select(.spec.replicas == 0) |
"\(.metadata.namespace) \(.metadata.name)"' | \
while read ns rs; do
kubectl delete rs "$rs" -n "$ns"
done
Intelligent Cleanup
Add smart filtering:
# Keep recent failures for debugging
if [[ "$phase" == "Failed" ]]; then
# Keep failures from last 24 hours
if [[ $(date -d "$age" +%s) -gt $(date -d '24 hours ago' +%s) ]]; then
echo " Keeping recent failure for debugging"
continue
fi
fi
Future Improvements
- Add configurable retention policies
- Implement namespace exclusion via labels
- Add support for cleaning other resources
- Create web dashboard for statistics
- Implement dry-run mode
- Add email notifications
- Support custom cleanup rules
- Add PVC cleanup for orphaned volumes
- Implement gradual deletion (rate limiting)
- Add cost savings calculations