Tolerating Partial Failures (BestEffort)¶
You run a large test cluster for a retail platform: six namespace groups plus a fleet of batch EC2 instances, all hibernated nightly. The problem: something always fails. A stuck PodDisruptionBudget in pricing, a finalizer that never clears in reports. With the default Strict behavior, one stuck namespace aborts the entire cycle — the other five targets stay running, and the cost savings evaporate.
You switch to BestEffort: every target gets its fair chance (including retries), failures are recorded honestly, and the rest of the fleet hibernates anyway. You review the failures over coffee in the morning.
Goal¶
- All targets attempt hibernation every weeknight, regardless of individual failures.
- A failing target retries (3 attempts) before being marked
Failed. - Failures are visible in the plan status the next morning — never silently ignored.
Strict vs BestEffort¶
Strict (default) |
BestEffort |
|
|---|---|---|
| On target failure | Halts immediately — no further targets start | Continues executing remaining targets |
| Plan phase after failure | Error |
Completes the cycle (failures recorded in status) |
| Failed target | Recorded in status.executions |
Recorded in status.executions |
| Retries | Applied per target before declaring failure | Same |
| Best for | Production, ordered dependencies | Large fleets, non-critical environments |
Retries still apply
BestEffort is not "fire once and ignore". Each target still retries up to behavior.retries times before it is marked Failed. You are choosing isolation between targets, not fewer attempts.
Configuration¶
apiVersion: hibernator.ardikabs.com/v1alpha1
kind: HibernatePlan
metadata:
name: fleet-nightly
namespace: hibernator-system
spec:
schedule:
timezone: "America/New_York"
offHours:
- start: "21:00"
end: "06:00"
daysOfWeek: ["MON", "TUE", "WED", "THU", "FRI"]
execution:
strategy:
type: Parallel
maxConcurrency: 5
behavior:
mode: BestEffort
retries: 3
targets:
- name: ns-shop
type: workloadscaler
connectorRef:
kind: K8SCluster
name: fleet-eks
parameters:
namespace:
literals: [shop-web, shop-api]
awaitCompletion:
enabled: true
- name: ns-inventory
type: workloadscaler
connectorRef:
kind: K8SCluster
name: fleet-eks
parameters:
namespace:
literals: [inventory]
awaitCompletion:
enabled: true
- name: ns-pricing
type: workloadscaler
connectorRef:
kind: K8SCluster
name: fleet-eks
parameters:
namespace:
literals: [pricing]
awaitCompletion:
enabled: true
- name: ns-reports
type: workloadscaler
connectorRef:
kind: K8SCluster
name: fleet-eks
parameters:
namespace:
literals: [reports]
includedGroups: [Deployment, StatefulSet]
awaitCompletion:
enabled: true
- name: batch-instances
type: ec2
connectorRef:
kind: CloudProvider
name: aws-staging
parameters:
selector:
tags:
Environment: test
Role: batch
awaitCompletion:
enabled: true
This assumes the aws-staging CloudProvider from Partial Hibernation plus a fleet-eks K8SCluster connector pointing at the test cluster (see Connectors).
How It Executes¶
- 21:00 — all five targets start (bounded by
maxConcurrency: 5). ns-pricinghits the stuck PDB. It retries 3 times, then is markedFailed.- The other four targets are unaffected and complete normally.
- The plan reaches
Hibernated— with the failure recorded. Wakeup at 06:00 proceeds for the completed targets.
Verification¶
The next morning, read the execution ledger:
kubectl get hibernateplan fleet-nightly -n hibernator-system \
-o jsonpath='{range .status.executions[*]}{.target}{"\t"}{.state}{"\t"}{.message}{"\n"}{end}'
ns-shop Completed 8 workload(s) scaled down
ns-inventory Completed 3 workload(s) scaled down
ns-pricing Failed waiting for workload replicas to scale: deadline exceeded
ns-reports Completed 5 workload(s) scaled down
batch-instances Completed 12 instance(s) stopped
kubectl get hibernateplan fleet-nightly -n hibernator-system -o jsonpath='{.status.phase}'
# Hibernated
Now fix the root cause in pricing, then re-run just the cycle — see Error Recovery and the retry-now annotation in Override Actions.
BestEffort is not 'ignore failures'
Failures still land in the ledger and in metrics. Pair this setup with Notifications (Failure events) or a morning status check, or Failed targets will quietly pile up. For unattended production environments, prefer Strict with a DAG.
Variations¶
- BestEffort + DAG — a failed target causes its downstream dependents to be marked
Abortedand skipped, while independent branches continue. See Dependency-Ordered Shutdown. - Tighter concurrency — drop
maxConcurrencyto2to reduce API pressure on the cluster at window start. - Escalate important targets — split the fleet into two plans: a Strict plan for the namespaces that matter and a BestEffort plan for the long tail.
Next Steps¶
- Error Recovery — retry semantics and recovery flows
- Override Actions —
retry-now, restart, and manual overrides - Dependency-Ordered Shutdown — next tier: ordering with DAG