Scheduling Namespace
Can ZopNight schedule Namespace?
Namespace schedules apply a different treatment per controller: Deployments and StatefulSets scale to 0, DaemonSet pods are removed through a nodeSelector no node matches, CronJobs are suspended, and KEDA ScaledObjects, HPAs and PDBs are saved, deleted and recreated on resume. KEDA goes first because it can scale a workload up from zero; the others are restored from the saved state.
How the stop works
| Field | Value |
|---|---|
| Behaviour | deletes KEDA ScaledObjects first, scales all Deployments and StatefulSets to 0, evicts DaemonSet pods via a temporary nodeSelector no node matches, suspends CronJobs, and saves and removes HPAs and PDBs as housekeeping; restored from the saved state on schedule resume |
Example schedules
- 0 8 * * 1-5 — Business Hours Start: Start at 8:00 AM on weekdays
- 0 18 * * 1-5 — Business Hours Stop: Stop at 6:00 PM on weekdays
- 0 22 * * * — Night Shutdown: Stop at 10:00 PM every day
- 0 6 * * 1-5 — Morning Startup: Start at 6:00 AM on weekdays
- 0 20 * * 5 — Weekend Shutdown: Stop at 8:00 PM on Friday
- 0 7 * * 1 — Weekend Startup: Start at 7:00 AM on Monday
Why this schedule is a choreography
A namespace is a bag of controllers that each need their own treatment, so the stop is several coordinated moves rather than one. Deployments and StatefulSets scale to 0 replicas. DaemonSets, which have no replica count, lose their pods because their nodeSelector is pointed at a label no node carries until the start restores it. CronJobs flip to suspended so no new runs launch. KEDA ScaledObjects are deleted first, because KEDA is the controller that can scale a workload up from zero. The HorizontalPodAutoscalers and PodDisruptionBudgets that target each workload are saved and removed too, then recreated from the saved copies at resume. A plain HPA does not act on a workload at 0 replicas, and a PDB only gates evictions, which a scale-down does not use, so removing them is housekeeping rather than a fight: the saved copies make sure the guardrails return unchanged.
What the sweep does not manage
Bare pods with no controller keep running, since nothing owns them and nothing scales them. Jobs already mid-run continue to completion. Operators and CRDs that reconcile their own replica counts can resurrect workloads minutes after the scale-down; a namespace running such an operator needs it included in the schedule’s scope or excluded from the namespace. PersistentVolumeClaims survive untouched, holding both the state and the storage bill.
Zero pods is not automatically zero dollars
Everything here happens inside the cluster, and clouds bill for nodes, not pods. The scaled- down namespace saves real money only when the freed capacity lets nodes disappear, whether through a cluster autoscaler consolidating and removing emptied nodes or a companion schedule on the node pools. On a fixed-size cluster the schedule frees headroom, which has value, but the invoice does not change.
Suspended CronJobs do not queue their runs
A CronJob suspended at 19:00 with 6 scheduled runs overnight does not replay all 6 at resume. When it is unsuspended, Kubernetes starts at most one catch-up Job for the missed window, and none if the CronJob’s startingDeadlineSeconds has already passed. Jobs whose runs matter individually need their schedules moved inside working hours, not merely suspended through them.
Resume rebuilds the guardrails
At start, replicas return to their recorded counts, CronJobs unsuspend, and the deleted HPAs and PDBs are recreated from their saved definitions. The namespace ends the cycle with its autoscaling and disruption protection intact, not permanently stripped.