On-demand node pools in dev/test clusters that could run Spot
What does ZopNight detect here?
Spot VMs run the same machine types at roughly 70% below on-demand list price, with preemption as the trade. ZopNight recommends Spot node pools only for dev/test-classified pools, checks the pool is not already Spot, and derives the fraction from live on-demand and Spot rates when available.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-114 |
| Category | discount |
| Severity | low |
| Metric | none — pure configuration read |
| Source | gke_spot_nodepool.go |
Where it applies
Preemption is the price of 70% off
Spot VMs are the same machines at a baseline of roughly 70% below on-demand, and Google can reclaim them with 30 seconds’ notice. Kubernetes is unusually good at absorbing that: evicted pods reschedule automatically, which is why the node pool, not the individual VM, is the natural Spot unit for dev and test clusters. CI runners, preview environments, and batch workers rarely notice a preemption; a developer waiting on a rescheduled pod for a minute is a fine trade for the discount.
Labels decide eligibility, names help
Classification runs on three signals: a dev/test-shaped pool name, a dev/test-shaped cloud-account name, or a dev/test value in the env-style label the discoverer captures from the pool’s nested labels. The production veto reads the same label axis and wins over everything: a pool labeled env=prod is never offered Spot regardless of its name, because preempting production pods is an incident, not a saving.
Already-Spot pools are skipped
The discoverer records spot=true on pools already running Spot capacity, and the rule
skips them. An earlier revision read a label sink GCP never populates and would happily
re-recommend Spot on a pool already on it, claiming savings that did not exist. The
current gate reads the sink the producer actually writes. When live on-demand and Spot
tier rates are present, the fraction is derived from them; otherwise the documented 70%
baseline applies to the pool’s known cost.
Check a pool’s Spot flag
gcloud container node-pools describe my-pool --cluster my-cluster \ --location us-central1 --format="value(config.spot,config.machineType)"Migration is create-new, drain-old: stand up a Spot pool with the same configuration, cordon and drain the on-demand pool, delete it once workloads settle.
The per-pool pricing caveat
Node pools carry no cost of their own in the calculated path (member VMs are priced individually to avoid double-counting), so on live fleets the per-VM Spot rule usually carries the dollars while this rule contributes the pool-level signal. The eligibility and already-Spot logic above is what fires the moment a pool-level cost basis exists.