ZopDay’s Kubernetes Service Cards Show Why a Pod Isn’t Running
A card that only tells you a service is running still leaves the actual question unanswered: running well, or running on borrowed time. ZopDay’s project canvas used to show a single status per service, so checking CPU or memory meant opening each one individually. Every card now carries a usage band directly on the canvas: replica count, CPU and memory against their configured limits, uptime, and restart count. A service that isn’t currently running says why instead of just going quiet, showing a reason like Scaled to zero or Not running · OOMKilled.
Reusing Data Already on the Wire
Nothing about this feature required a new endpoint. The usage band is assembled entirely from data ZopDay was already fetching for other purposes: one call scoped to a whole cluster’s pods, fields already present in the pod list response like configured CPU and memory limits and restart counts, and a separate VM-scoped metrics call for services that run on a VM rather than a cluster.
Joining data the system already collects, instead of standing up a dedicated endpoint for this one card, means the usage band inherits whatever correctness the underlying data already had rather than introducing a second, possibly inconsistent copy of the same facts.
Forty Cards, One Cache Entry
The query keys behind this data are scoped to a cluster or a VM as a whole, never to an individual service. A canvas showing 40 services that all happen to live in the same cluster shares exactly one cache entry for that cluster’s metrics rather than issuing 40 near-identical queries a few milliseconds apart. The canvas polls that shared cache every 60 seconds. The existing per-service drawer, a separate and older surface, keeps its own faster 10-second poll, since a person who has opened one specific service’s detail view is deliberately watching it more closely than someone scanning an entire canvas at once.
That distinction in scoping is the difference between a feature that scales cleanly with canvas size and one that quietly multiplies its own request volume by however many cards happen to be on screen.
Deciding Where Not to Show It
Where the usage band actually appears is decided once per environment, inside the canvas page itself, rather than card by card. ZopCloud’s shared clusters are excluded from it entirely. So are VMs with no metrics backend attached, and that second exclusion is deliberate rather than an oversight: fetching live stats from a VM with no backend means falling back to a direct docker exec call, which can take anywhere from 20 to 60 seconds to return per card. Multiplying that across even a modest canvas would make the whole page feel broken rather than merely slow.
That same tradeoff, a metrics backend or a slow fallback with no middle option, is the same design this team shipped for ZopDay’s VM Observability tab: a VM either has a connected backend and gets live data, or it doesn’t and the feature simply doesn’t try to fake it.
Honest About What It Doesn’t Know
Several small display decisions here exist specifically to avoid a value that looks precise but means something misleading.
| Ambiguous case | What’s actually shown |
|---|---|
| A replica with no configured resource cap | The text “no limit set,” not a blank field or a zero |
| A service with zero running pods | An explicit reason line, not an empty band |
| Uptime across multiple replicas | The oldest replica’s uptime, not the newest |
| A generic “failed” status | Doesn’t blank the rest of the band’s real values |
The logic that decides how a container’s state gets labeled, whether it reads as running, scaled to zero, or failed for a specific reason, was pulled into one shared module used by both the VM-hosted and Kubernetes-hosted surfaces, rather than left duplicated separately in each. A rule fixed once now applies everywhere it’s used, instead of needing to be fixed twice and inevitably drifting apart.
What This Doesn’t Cover Yet
CPU and memory figures are GKE-only in this release, because the underlying pod-metrics fetch depends on a GCP service account that other cloud providers don’t yet have an equivalent path for. The release notes also name a limitation that already existed before this change rather than leaving it to be discovered: the pod-metrics endpoint this feature reads from lists every namespace in a cluster, a behavior this new, far more visible canvas card makes considerably easier to notice than the older, quieter surface ever did. Stating a known gap plainly, in the same release that makes it more visible, is worth more to a reader than a canvas that looks finished but silently only works for one provider.
