Hibernate Workloads Across Multiple Namespaces#
A ClusterResourceSupervisor applies one hibernation schedule to a group of namespaces. It is cluster-scoped, so it suits a platform team parking development or test environments outside working hours, rather than a single team managing its own namespace.
For one namespace owned by the team that hibernates it, use a ResourceSupervisor instead.
Prerequisites#
- The Hibernation Operator is installed in the cluster.
- You have cluster-admin permissions.
Step 1: Choose how to select namespaces#
Namespaces come from spec.namespaces, either listed by name, matched by label, or both. The two are combined, so a namespace selected either way is hibernated.
| Field | Selects |
|---|---|
spec.namespaces.names |
A fixed list of namespaces you name explicitly |
spec.namespaces.labelSelector |
Every namespace matching the labels, re-evaluated as namespaces come and go |
Warning
A ClusterResourceSupervisor with no spec.namespaces hibernates nothing. This matters most when using the ArgoCD integration described below, which does not select namespaces on its own.
An empty labelSelector: {} also matches nothing. To select broadly, use a label every target namespace carries rather than an empty selector.
Step 2: Define the ClusterResourceSupervisor#
Selecting by label, so namespaces labelled env=dev are picked up automatically as they are created:
apiVersion: hibernation.stakater.com/v1beta1
kind: ClusterResourceSupervisor
metadata:
name: dev-environments-hibernation
spec:
namespaces:
labelSelector:
matchLabels:
env: dev
schedule:
sleepSchedule: "0 18 * * 1-5" # Weekdays at 18:00 UTC
wakeSchedule: "0 8 * * 1-5" # Weekdays at 08:00 UTC
Selecting a fixed set by name:
apiVersion: hibernation.stakater.com/v1beta1
kind: ClusterResourceSupervisor
metadata:
name: specific-namespaces-hibernation
spec:
namespaces:
names:
- team-a-staging
- team-b-test
- demo-env
schedule:
sleepSchedule: "0 0 * * 0" # Sundays at midnight UTC
wakeSchedule: "0 0 * * 1" # Mondays at midnight UTC
Schedules use five-field Unix cron syntax in UTC. Omitting wakeSchedule leaves the workloads asleep until the resource is edited or deleted.
Step 3: Apply it#
kubectl apply -f cluster-resource-supervisor.yaml
Step 4: Check the status#
kubectl get clusterresourcesupervisor dev-environments-hibernation -o yaml
| Field | Shows |
|---|---|
status.currentStatus |
running, sleeping, or error |
status.watchedNamespaces |
Namespaces currently being managed |
status.ignoreNamespaces |
Selected namespaces that were filtered out |
status.sleepingNamespaces |
Per-namespace detail of the scaled-down workloads |
status.nextReconcileTime |
Next scheduled sleep or wake |
If a namespace you expected is missing from watchedNamespaces, check ignoreNamespaces. Namespaces annotated hibernation.stakater.com/exclude: "true", and the operator's own namespace, are always filtered out.
Keeping ArgoCD from waking workloads#
When applications are managed by ArgoCD, scaling them to zero puts them out of sync with Git, and ArgoCD will scale them back up. The spec.argocd field addresses this by writing a deny sync window onto the named AppProjects, matching the sleep schedule and its computed duration.
apiVersion: hibernation.stakater.com/v1beta1
kind: ClusterResourceSupervisor
metadata:
name: argocd-frontend-hibernation
spec:
namespaces:
labelSelector:
matchLabels:
team: frontend
argocd:
namespace: argocd # Namespace where the AppProjects live
appProjects:
- frontend-team
- mobile-apps
schedule:
sleepSchedule: "0 22 * * *"
wakeSchedule: "0 6 * * *"
Warning
spec.argocd does not select namespaces. It only suppresses ArgoCD syncing for the AppProjects you name, and the namespaces to hibernate still come entirely from spec.namespaces. The example above hibernates the team=frontend namespaces; without that namespaces block it would hibernate nothing while still writing sync windows.
Two further points before enabling this:
- The operator replaces
spec.syncWindowson each named AppProject rather than appending to it. Any sync windows you maintain there by other means are overwritten. - The integration requires the ArgoCD
AppProjectCRD to be present, andargoCD.enabled=trueat install time. If the CRD is absent the operator logs the fact and carries on hibernating.