ComputeClass: Lifecycle, Drift & Updates
Consolidation (Scale-down)
Controlled via spec.autoscalingPolicy.
consolidationDelayMinutes: Floor is 1 minute.consolidationThreshold: CPU utilization % (0 = always candidate).gpuConsolidationThreshold: Accelerator utilization %.- Note: Maintenance windows do not block consolidation. Use PDBs to suppress disruption.
- Blockers: Local storage, 'safe-to-evict: false', and bare pods block scale-down. DaemonSets do NOT block scale-down by default. If empty nodes aren't scaling down, look for other blocking system pods.
- System Pod Segregation: Since non-DaemonSet system pods (e.g., in
kube-systemnamespace) often have tight PDBs or single replicas that block scale-down, always recommend segregating system pods into a dedicated system ComputeClass/node pool (usingsystem-pool-compute-class.yaml). This isolates the system pods and keeps them from blocking the consolidation of Spot/workload nodes.
ActiveMigration (Drift Reconciliation)
Reconciles pods back to higher-priority rules (e.g. moving from fallback On-Demand back to preferred Spot or C3) when capacity becomes obtainable again.
optimizeRulePriority: true: Enables the drift controller.- Drift Reconciliation Loop: Periodically evaluates running pods against the ComputeClass
priorities[]ladder. When higher-priority capacity becomes available (e.g. 5-minute stockout cooldown expires or new Spot capacity is energized), the controller provisions preferred nodes and initiates voluntary evictions to pull workloads up the ladder. - Voluntary Disruption Contract: Active Migration calls the Kubernetes Eviction API and strictly respects
PodDisruptionBudgets(PDBs). Without a PDB, evictions occur as fast as new nodes become ready. - Blockers to Active Migration:
- Tight PDBs (
maxUnavailable: 0orminAvailable: 100%) block eviction entirely. - Non-DaemonSet system pods in
kube-systemwithout PDBs (DaemonSets are stripped viapodutils.FilterRecreatablePodsand do NOT block drain). cluster-autoscaler.kubernetes.io/safe-to-evict: "false"annotation blocks node removal.cluster-autoscaler.kubernetes.io/safe-to-evict: "on-completion"defers active migration until the pod terminates naturally.
- Tight PDBs (
Blue-Green & Canary Rollout Protection Against Active Migration Churn
During phased blue-green or canary deployments (e.g., 10% -> 30% -> 60% -> 100% traffic shifts), activeMigration can cause severe rollout churn by voluntarily evicting newly scheduled Green pods to optimize node placement while the pods are warming up or receiving test traffic.
Why PDBs are Superior to Pod Template Annotations
- Pod Template Annotations (
safe-to-evict: false): Adding or modifyingcluster-autoscaler.kubernetes.io/safe-to-evict: "false"insidespec.template.metadata.annotationsmutates thePodTemplateSpechash. This triggers an immediate rolling restart of the entire Deployment, causing unwanted downtime. - Rollout-Scoped PodDisruptionBudgets (
maxUnavailable: 0): Managing a standalone PDB scoped specifically to the Green version (matchLabels: version: green) operates completely out-of-band via admission control in memory:- Causes zero pod restarts (no modification to Deployment or ReplicaSet spec).
- Blocks voluntary
activeMigrationand node consolidation during the release window. - Can be dynamically relaxed to standard production budgets (e.g.,
maxUnavailable: 25%) viakubectl patchonce cutover reaches 100%.
3-Stage Rollout Lifecycle Pattern
- Stage 1: Deploy Green + Guard PDB
- Apply Green rollout PDB with
maxUnavailable: 0targetingversion: green. - Deploy
my-service-greenDeployment. - Green pods schedule and initialize;
activeMigrationis blocked from evicting them.
- Apply Green rollout PDB with
- Stage 2: Phased Traffic Shift (10% -> 30% -> 60% -> 100%)
- Shift traffic incrementally across validation windows.
- Green pods remain stable on their provisioned nodes without eviction churn.
- Stage 3: Cutover & Relax PDB
- 100% traffic routed to Green; Blue Deployment and Blue PDB decommissioned.
- Patch Green PDB to operational budget (
maxUnavailable: 25%) to re-enable backgroundactiveMigrationnode shape optimization.
PDB Safety and Edge Cases
| Scenario | Behavior Under maxUnavailable: 0 |
Impact / Safety Mechanism |
|---|---|---|
| Pod creation & scale-up | ReplicaSet creates pods via the direct Pod Create API. | No impact: PDBs are not consulted during pod creation. |
| ActiveMigration / Consolidation | Cluster Autoscaler queries Eviction API; eviction rejected (disruptionsAllowed: 0). |
Desired: Pods remain stable on nodes during rollout. |
| Involuntary node loss (Spot preemption / host failure) | Hypervisor reclaims VM (involuntary disruption, bypasses Eviction API). | Self-healing: ReplicaSet detects missing ready replicas and spawns replacements via Pod Create API immediately. |
| Rollout abort / rollback | CI/CD scales replicas to 0 or deletes Green Deployment. | Safe: Pod Delete API bypasses PDBs; pods terminate immediately. |
| Node auto-upgrades | GKE node drain queries Eviction API and pauses until drain timeout. | Low risk: Node upgrades wait for rollout completion. |
# 1. Rollout Guard PDB (Stage 1)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-service-green-pdb
namespace: default
spec:
maxUnavailable: 0
selector:
matchLabels:
app: my-service
version: green
---
# 2. Green Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-service-green
namespace: default
spec:
replicas: 10
selector:
matchLabels:
app: my-service
version: green
template:
metadata:
labels:
app: my-service
version: green
spec:
nodeSelector:
cloud.google.com/compute-class: "general-workloads"
containers:
- name: app
image: gcr.io/my-project/my-service:v2.0.0
resources:
requests:
cpu: "2"
memory: "4Gi"CRITICAL K8S DISTINCTION: PDBs and
safe-to-evict: falseONLY protect against voluntary disruptions (ActiveMigration, scale-down, upgrades). They DO NOT prevent involuntary Spot VM preemptions. Spot nodes can be reclaimed at any time, regardless of PDBs.
Updating a ComputeClass
- No Retroactive Change: Updating a ComputeClass does not change existing nodes.
- New Nodes Only: Only nodes created after the update use the new spec.
- Drift Behavior:
- Without ActiveMigration: Old-spec nodes persist until rescheduled (rollout, drain, preemption).
- With ActiveMigration: Controller drifts pods toward nodes matching the updated (higher-priority) spec.
- Disruption-Sensitive: For training/stateful roles, schedule updates for maintenance windows or drain manually.