Namespace
Does ZopNight manage Namespace?
Namespaces are the unit ZopNight switches off. At window close it deletes KEDA ScaledObjects first, scales Deployments and StatefulSets to 0, evicts DaemonSet pods via a nodeSelector no node matches, suspends CronJobs, and saves and removes HPAs and PDBs as housekeeping, restoring everything at open. Discovery skips kube-system, kube-public, and kube-node-lease, and attaches a pod summary to each namespace.
Rules that fire on Namespace
No active rule family targets Namespace today. Rules that used to are retired, and retired rules publish no pages and fire no findings. Scheduling and permissions coverage are unaffected.
At a glance
| Field | Value |
|---|---|
| Scheduling notes | 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 |
A namespace partitions a cluster into logical environments: dev, staging, per-team spaces. It is also the one Kubernetes resource in this directory that is schedulable: when an environment goes quiet at night, the namespace is the handle ZopNight switches it off by.
The unit an environment switches off at
Individual workloads are the wrong granularity for downtime, because a dev environment is dozens of objects that must stop and start together. Scheduling at the namespace boundary captures all of them in one decision, which is why the namespace record exists in the inventory even though the object itself has no cost: it is the parent that scheduling, eligibility, and attribution all key off.
What stop actually does, object by object
At window close the schedule first deletes the namespace’s KEDA ScaledObjects, saving each manifest, because KEDA is the controller that can scale a workload up from zero. It then scales every Deployment and StatefulSet to 0, evicts every DaemonSet’s pods by temporarily pointing its nodeSelector at a label no node carries (zopnight.io/disabled=true), and suspends every CronJob. The HPAs and PDBs that target each workload are saved and removed too. 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 this is housekeeping rather than a fight. At window open the workloads return to their prior counts, CronJobs that were running before unsuspend, and the saved HPAs, PDBs and ScaledObjects are recreated as they were.
System namespaces stay out of scope
Discovery skips kube-system, kube-public, and kube-node-lease everywhere, and each provider adds its own exclusions, GKE’s managed namespaces such as gmp-system among them. Nothing in those namespaces is ever inventoried as a workload or touched by a schedule; the same gates keep reserved namespaces out of scheduling eligibility.
Pod summaries on the namespace record
Each discovered namespace carries its phase as status (active or terminating) plus labels and an attached pod summary counted at discovery time. That summary is the quick answer to the question that decides scheduling candidacy: is anything actually running in here, and how much of it?
kubectl get namespaces -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,AGE:.metadata.creationTimestampA practical rule of thumb: environments whose namespaces show steady weekday pod counts and empty weekends are the first candidates worth scheduling, and the pod summary makes them visible in 1 pass.