Skip to main content

Namespace-Level Scheduling in Kubernetes: How It Works

Instead of stopping a whole cluster, a namespace schedule parks just the workloads in one namespace and brings them back later. Here is exactly what changes on stop and on start.

Namespace-level scheduling is the practice of stopping and restarting the workloads inside a single Kubernetes namespace on a timetable, while the cluster and its other namespaces keep running. Kubernetes namespaces provide a mechanism for isolating groups of resources within a single cluster, which is why teams use them for dev, qa or per-feature environments. A namespace schedule turns that isolation into a cost control: the qa namespace sleeps at night, the platform namespaces do not.

What “stop” means for each kind of object

A namespace has no power switch, so stopping one means changing the objects in it:

  • Deployments and StatefulSets are scaled to zero replicas. Their Pods terminate, but the object definitions, Services, ConfigMaps, Secrets and PersistentVolumeClaims stay in place.
  • CronJobs are suspended. Kubernetes supports this natively: with .spec.suspend set to true the controller stops creating new Jobs, and Jobs that already started are not affected.
  • HorizontalPodAutoscalers need attention. Kubernetes documents that if a target’s desired replica count is set to 0 while the HPA’s minimum is greater than 0, the HPA stops adjusting the target until the replica count or the minimum is changed again. A stop-and-start routine has to put the replica counts and autoscaler settings back exactly as they were.
  • PodDisruptionBudgets limit voluntary disruptions such as node drains; they do not stop a Deployment from being deleted or scaled. They can still interfere with draining the nodes you are trying to free, so a scheduler has to decide what to do with them.

Starting reverses the list: replica counts return to their saved values, CronJobs resume, and autoscaling takes over again.

How ZopNight implements it

ZopNight’s namespace start/stop scales every Deployment and StatefulSet in the namespace to 0 and suspends every CronJob, saving the prior replica counts along with the namespace’s HPAs and PDBs; HPAs and PDBs are removed on stop and restored on start, together with the replicas. DaemonSets are emptied by pointing them at a node selector no node matches, and KEDA ScaledObjects are removed; both are restored on start. One implementation serves EKS, GKE and AKS namespaces, with only cloud authentication differing. System namespaces are refused: anything matching kube-*, zopnight-*, istio-*, helm-*, gke-managed-*, gmp-*, gatekeeper-* or aks-*, plus default, is skipped in the UI and refused before any Kubernetes call is made. That covers the four namespaces every cluster starts with (default, kube-node-lease, kube-public, kube-system).

When it saves money, and when it does not

Scaling Pods to zero frees their resource requests; whether the bill falls depends on how the cluster is priced:

  • Standard node-based clusters (EKS with EC2 nodes, GKE Standard, AKS) bill for nodes. On GKE Standard, nodes are billed as Compute Engine instances until they are deleted. The saving only appears when the cluster autoscaler or a node pool schedule removes the nodes that the namespace’s Pods were using.
  • Pod-billed compute saves directly. GKE Autopilot’s general-purpose workloads are charged for the CPU, memory and ephemeral storage that running Pods request, and AWS Fargate charges from image download until the Pod terminates. A Pod that no longer exists costs nothing on these platforms.

Per-cluster charges are unaffected either way: EKS charges per cluster per hour for standard Kubernetes version support, GKE applies a flat cluster management fee per cluster per hour, and AKS has no management fee on the Free tier but charges $0.10 per cluster per hour on the Standard tier, which adds an uptime SLA.

Practical checklist

  1. Put each schedulable environment in its own namespace; do not mix qa workloads into default.
  2. Check that the cluster autoscaler can remove nodes once the namespace empties, or schedule the matching node pool.
  3. Confirm stateful workloads come back cleanly after replicas return; the PersistentVolumeClaims persist while replicas are at zero.

To decide between this and stopping the whole cluster, read namespace vs cluster scheduling. Broader patterns for shared and dedicated clusters are in Kubernetes scheduling strategies, and cluster-level options are on the EKS cluster schedule page.

faq

Questions we get a lot.

If yours isn't here, email us and we'll answer directly.

Can ZopNight schedule kube-system or default?

No. Namespaces matching kube-*, zopnight-*, istio-*, helm-*, gke-managed-*, gmp-*, gatekeeper-* or aks-*, and the default namespace, are skipped in the UI and rejected server-side before any cluster call.

Is data in the namespace lost when it is stopped?

Scaling to zero removes Pods, not PersistentVolumeClaims, so volume data persists. Anything held only in a Pod's memory or in an emptyDir volume is gone when the Pod terminates.

Stop watching the waste.
Start cutting it.

See. Find. Fix. Automatic.

Connect your first cloud account in under 5 minutes. See your first remediation in under 7. No credit card required.

CDCR connect detect classify remediate
full audit every action traceable
read-only default access
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·