Skip to content

Instantly share code, notes, and snippets.

@x95castle1
Last active April 4, 2025 20:09
Show Gist options
  • Select an option

  • Save x95castle1/50b7f12515857730b1fc8de025773a55 to your computer and use it in GitHub Desktop.

Select an option

Save x95castle1/50b7f12515857730b1fc8de025773a55 to your computer and use it in GitHub Desktop.
CronJob that will cleanup Workloads that are in a ready state and are older than a period of time.
apiVersion: batch/v1
kind: CronJob
metadata:
name: ready-workload-checker
namespace: tap-install
spec:
schedule: "*/1 * * * *" # Runs every 5 minutes TODO: Adjust this to what you need. Example to run every day at midnight: 0 0 * * *
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
serviceAccountName: workload-checker-sa
containers:
- name: kubectl
image: bitnami/kubectl:latest
imagePullPolicy: IfNotPresent
env:
- name: EXCLUDED_NAMESPACES
value: "kube-system"
- name: ALLOWED_DELETION_SECONDS
value: "600" # This is in seconds. 600 = 10 minutes for example. 604800 would be 7 days.
command:
- /bin/bash
- -c
- |
#!/bin/bash
echo "$(date): Searching for ready workloads across all namespaces..."
echo "------------------------------------------------"
# Create array of excluded namespaces
IFS=',' read -ra EXCLUDED <<< "$EXCLUDED_NAMESPACES"
echo "Excluded namespaces: ${EXCLUDED_NAMESPACES}"
echo "------------------------------------------------"
# Get all namespaces
namespaces=$(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}')
# Initialize results file
results_file="/tmp/ready-workloads-$(date +%Y%m%d-%H%M%S).txt"
echo "Ready Workloads Report - $(date)" > $results_file
echo "================================================" >> $results_file
# Current time in seconds since epoch
current_time=$(date +%s)
# Loop through each namespace
for namespace in $namespaces; do
skip=false
for excluded in "${EXCLUDED[@]}"; do
if [[ "$namespace" == "$excluded" ]]; then
echo "Skipping excluded namespace: $namespace"
skip=true
break
fi
done
# Skip to next iteration if namespace is excluded
if $skip; then
continue
fi
echo ""
echo "Checking namespace: $namespace"
echo "Namespace: $namespace" >> $results_file
# Get all workloads in the namespace
workloads=$(kubectl get workload -n $namespace -o jsonpath='{.items[*].metadata.name}' 2>/dev/null)
# If no workloads found, continue to next namespace
if [ -z "$workloads" ]; then
echo " No workloads found in this namespace"
echo " No workloads found in this namespace" >> $results_file
continue
fi
# Loop through each workload
for workload in $workloads; do
# Check if the workload has Ready condition with status True
ready_status=$(kubectl get workload $workload -n $namespace -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null)
if [ "$ready_status" = "True" ]; then
# Get the lastTransitionTime for the Ready condition
last_transition=$(kubectl get workload $workload -n $namespace -o jsonpath='{.status.conditions[?(@.type=="Ready")].lastTransitionTime}' 2>/dev/null)
if [ ! -z "$last_transition" ]; then
# Convert ISO 8601 date to seconds since epoch
transition_time=$(TZ=UTC date -d "$(echo $last_transition | sed 's/Z$//')" +%s 2>/dev/null)
if [ ! -z "$transition_time" ]; then
# Calculate time difference in seconds
time_diff=$((current_time - transition_time))
if [ $time_diff -gt $ALLOWED_DELETION_SECONDS ]; then
# Format time difference in a human-readable format
minutes=$((time_diff / 60))
hours=$((minutes / 60))
days=$((hours / 24))
if [ $days -gt 0 ]; then
duration="${days}d $((hours % 24))h"
elif [ $hours -gt 0 ]; then
duration="${hours}h $((minutes % 60))m"
else
duration="${minutes}m"
fi
echo " ✅ READY: $workload"
echo " ✅ READY: $workload" >> $results_file
echo " Last Transition: $last_transition"
echo " Last Transition: $last_transition" >> $results_file
echo " ⚠️ Workload '$workload' has maintained Ready state for ${duration} (>10 minutes)"
echo " ⚠️ Workload '$workload' has maintained Ready state for ${duration} (>10 minutes)" >> $results_file
echo " DELETING WORKLOAD $workload "
kubectl delete workload $workload -n $namespace
else
echo " ✅ READY: $workload"
echo " ✅ READY: $workload" >> $results_file
echo " Last Transition: $last_transition"
echo " Last Transition: $last_transition" >> $results_file
fi
else
echo " ✅ READY: $workload"
echo " ✅ READY: $workload" >> $results_file
echo " Last Transition: $last_transition (could not parse date for workload '$workload')"
echo " Last Transition: $last_transition (could not parse date for workload '$workload')" >> $results_file
fi
else
echo " ✅ READY: $workload"
echo " ✅ READY: $workload" >> $results_file
echo " Last Transition: Unknown for workload '$workload'"
echo " Last Transition: Unknown for workload '$workload'" >> $results_file
fi
else
echo " 🛑 NOT READY: $workload in status of $ready_status"
fi
done
echo "" >> $results_file
done
echo ""
echo "Search complete. Results saved to $results_file"
# cat $results_file
restartPolicy: OnFailure
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: workload-checker-sa
namespace: tap-install
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: workload-checker-role
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list"]
- apiGroups: ["carto.run"] # The API group for your workload CRD
resources: ["workloads"]
verbs: ["get", "list", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: workload-checker-binding
subjects:
- kind: ServiceAccount
name: workload-checker-sa
namespace: tap-install
roleRef:
kind: ClusterRole
name: workload-checker-role
apiGroup: rbac.authorization.k8s.io
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment