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 |