ClusterResourceSupervisor#
The ClusterResourceSupervisor is a cluster-scoped custom resource that enables centralized hibernation management across multiple namespaces. It is designed for platform administrators who need to enforce cost-saving policies at scaleβwhether by targeting explicit namespaces, using dynamic label selectors, or integrating with ArgoCD AppProjects.
β Scope: Cluster-wide β Permissions: Requires cluster-admin or equivalent β Use Case: Platform-level hibernation for dev/test environments, GitOps portfolios, or tenant groups
Supported Targeting Methods#
You can define one or more of the following targeting strategies. The operator applies hibernation to the union of all matched namespaces.
1. Explicit Namespace List#
List namespaces by name:
spec:
namespaces:
names:
- team-a-dev
- team-b-staging
- demo-env
2. Label Selector (Dynamic)#
Use Kubernetes-standard label selectors to match namespaces dynamically:
spec:
namespaces:
labelSelector:
matchLabels:
env: dev
team: frontend
matchExpressions:
- key: "cost-center"
operator: In
values: ["cc-100", "cc-200"]
π Note:
matchLabelsandmatchExpressionsare AND together.- An empty
labelSelector: {}matches all namespaces.- A missing/
nulllabelSelectormatches none.
3. ArgoCD AppProject Integration (Optional)#
Target all namespaces associated with one or more ArgoCD AppProjects:
spec:
argocd:
namespace: argocd # β Namespace where ArgoCD is installed
appProjects: # β List of AppProject names
- frontend-team
- data-platform
π The operator reads
AppProject.spec.destinationsto discover target namespaces. β No manual namespace listing neededβideal for GitOps environments. β οΈ Prerequisite: ArgoCD integration must be enabled during installation.
Hibernation Scheduling#
Define when workloads should sleep and wake using standard cron expressions (UTC timezone).
Full Cycle: Sleep + Wake#
spec:
schedule:
sleepSchedule: "0 18 * * 1-5" # Weekdays at 6 PM UTC
wakeSchedule: "0 8 * * 1-5" # Weekdays at 8 AM UTC
Permanent Sleep (Manual Wake)#
Omit wakeSchedule to keep workloads asleep until the CR is updated or deleted:
spec:
schedule:
sleepSchedule: "0 0 1 * *" # Sleep on the 1st of every month
# wakeSchedule: omitted β stay asleep
Ignored Namespaces#
Even if a namespace matches your targeting rules, it will be excluded if it has:
- The annotation:
hibernation.stakater.com/exclude: "true"
π This allows teams to opt out of platform-wide hibernation policies.
Status Tracking#
The operator populates rich status fields for observability and debugging:
status:
currentStatus: sleeping # "running", "sleeping", or "error"
nextReconcileTime: "2025-02-01T08:00:00Z"
watchedNamespaces: # Namespaces being managed
- team-a-dev
- frontend-staging
ignoreNamespaces: # Excluded (e.g., via annotation)
- kube-system
sleepingNamespaces: # Detailed state of scaled-down apps
- Namespace: team-a-dev
status: sleeping
sleepingApplications:
- name: web-api
kind: Deployment
replicas: 3 # β Original replica count (restored on wake)
status: sleeping
Use kubectl describe or kubectl get -o yaml to inspect:
kubectl get clusterresourcesupervisor my-policy -o jsonpath='{.status}'
Example: Platform-Wide Dev Hibernation#
apiVersion: hibernation.stakater.com/v1beta1
kind: ClusterResourceSupervisor
metadata:
name: dev-environments-hibernation
spec:
namespaces:
labelSelector:
matchLabels:
env: dev
schedule:
sleepSchedule: "0 18 * * 1-5"
wakeSchedule: "0 8 * * 1-5"
π Applies to all namespaces labeled
env=dev, now and in the future.
Example: ArgoCD + Label Selector Combo#
apiVersion: hibernation.stakater.com/v1beta1
kind: ClusterResourceSupervisor
metadata:
name: hybrid-hibernation
spec:
argocd:
namespace: argocd
appProjects:
- mobile-apps
namespaces:
names:
- legacy-staging
labelSelector:
matchLabels:
temporary: "true"
schedule:
sleepSchedule: "0 20 * * *"
wakeSchedule: "0 8 * * *"
π Hibernates:
- All namespaces in the
mobile-appsAppProject- Plus
legacy-staging- Plus any namespace with label
temporary=true
Key Notes#
- β Not namespace-scoped: Cannot be created inside a namespace.
- β
Safe by default: Only modifies
DeploymentsandStatefulSets. - β
Stateful restoration: Replica counts are stored in
status.sleepingNamespaces. - β
Coexists with
ResourceSupervisor: If a namespace has a localResourceSupervisor, the operator skips it (to avoid conflicts)βunless your operator logic is designed otherwise. (Confirm behavior in your implementation.)
When to Use ClusterResourceSupervisor#
| Scenario | Recommended |
|---|---|
| Hibernating 50+ dev namespaces | β |
| GitOps with ArgoCD AppProjects | β |
| Dynamic namespace selection via labels | β |
| Team self-service in one namespace | β β Use ResourceSupervisor |
API Reference#
Group/Version: hibernation.stakater.com/v1beta1 Β· Kind: ClusterResourceSupervisor Β· Scope: Cluster
Spec#
| Field | Type | Required | Description |
|---|---|---|---|
schedule |
object (Hibernation) |
Yes | Hibernation schedule applied to all matched namespaces. |
schedule.sleepSchedule |
string |
No | Standard 5-field Unix cron expression (UTC) for scaling workloads to zero. |
schedule.wakeSchedule |
string |
No | Standard 5-field Unix cron expression (UTC) for restoring workloads. If omitted, workloads stay asleep. |
namespaces |
object |
No | Targets namespaces by name and/or label selector. |
namespaces.names |
[]string |
No | Explicit list of namespace names to manage. |
namespaces.labelSelector |
object (metav1.LabelSelector) |
No | Standard Kubernetes label selector (matchLabels / matchExpressions). Empty {} matches all namespaces; absent matches none. |
argocd |
object |
No | Target namespaces via ArgoCD AppProjects. Requires ArgoCD integration enabled at install time. |
argocd.appProjects |
[]string |
Yes (within argocd) |
ArgoCD AppProject names whose destination namespaces follow the schedule. |
argocd.namespace |
string |
Yes (within argocd) |
Namespace where the ArgoCD AppProjects reside. |
Status#
| Field | Type | Description |
|---|---|---|
currentStatus |
string (sleeping, running, error) |
Overall state of managed workloads. |
nextReconcileTime |
string (RFC 3339 timestamp) |
Next scheduled sleep/wake reconciliation. |
watchedNamespaces |
[]string |
Namespaces currently managed by this resource. |
ignoreNamespaces |
[]string |
Namespaces excluded from management (e.g. via the exclude annotation). |
sleepingNamespaces |
[]object (SleepingNamespace) |
Per-namespace record of scaled-down workloads, used for accurate restoration. |
sleepingNamespaces[].Namespace |
string |
The namespace containing the sleeping applications. |
sleepingNamespaces[].status |
string (sleeping, running, error) |
Per-namespace error/state indicator. |
sleepingNamespaces[].sleepingApplications |
[]object (SleepingApplication) |
Workloads scaled down in the namespace. |
sleepingNamespaces[].sleepingApplications[].name |
string |
Name of the sleeping application. |
sleepingNamespaces[].sleepingApplications[].kind |
string |
Workload kind. |
sleepingNamespaces[].sleepingApplications[].replicas |
int32 |
Original replica count, preserved for restoration on wake. |