Build1 distinct publisher2 min readUpdated
Two sane Kubernetes defaults plus one convenient DNS record send a backup job's heartbeat to an ingress VIP, where a NetworkPolicy eats it without a packet of complaint.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
The rule has a latency budget before anything goes wrong: 86400 seconds is 24 hours, and `for: 15m` adds a quarter hour, so the earliest this dead man's switch can page anyone is 24 hours 15 minutes after the last good push [1]. That is the intended cost of the pattern [4].
The published symptom and the published rule do not quite fit together. If Pushgateway is holding a timestamp that stopped advancing days ago [1], then `time()` minus that timestamp is far past 86400 and BackupTooOld should have fired [4]. Permanent silence only makes sense for a series that never existed at all: the new `ai-jobs` namespace that is not in Pushgateway's ingress allow-list [15] never lands a first push, so there is no sample for the expression to compare against [4]. A staleness alert covers jobs that used to work. It does not cover a job that has never once reported, which is exactly the state a fresh namespace starts in.
The DNS half is arithmetic. Four dots in `pushgateway.monitoring.svc.cluster.local`, a threshold of five, so the resolver treats the fully qualified name as relative and walks the search list first [7][8][2]. The search list in a default ClusterFirst pod has four entries, the last one inherited from the node [5][6], which puts the absolute name fifth in line, not fourth: without the wildcard you pay four wasted lookups per push, one more than the write-up counts [3][12]. With `*.lab.example.com` in place, the fourth query gets an answer, the answer is the ingress controller's LoadBalancer VIP, and the fifth query never happens [10]. The heartbeat is now addressed to Traefik on port 9091 [11].
Then the policy layer removes the evidence. The VIP is outside the pod and service CIDRs, so an egress policy scoped to in-cluster traffic drops the packet on the way out of the pod [14]. Most CNI configurations send no RST and no ICMP error for a NetworkPolicy deny, so curl hangs rather than fails [16], and the command as published carries `-s` and no timeout flag [3], which means nothing bounds the wait and nothing is written to the job log. The CronJob exits 0 [1].
Each layer would have been a five-minute fix in isolation; the stacking is what makes it durable [18]. And the choice of victim matters more than the mechanism. The same resolver behaviour breaking TLS validation produces a certificate error somebody sees; here the only casualty is the reporting path, which has no user-facing symptom by construction [17].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
A CronJob exits 0, Pushgateway shows a heartbeat metric that has not updated in days, Prometheus fires nothing, and every dashboard is green while the guarantee the heartbeat existed to provide has stopped being true.
The batch heartbeat pattern: Prometheus cannot scrape a pod that lived for forty seconds, so the job pushes a timestamp to Pushgateway when it finishes, Prometheus scrapes Pushgateway on its normal cycle, and an alert fires if the timestamp goes stale.
The push is the last line of the backup script: echo "backup_last_success_timestamp $(date +%s)" piped to curl -s --data-binary @- "http://pushgateway.monitoring.svc.cluster.local:9091/metrics/job/nightly-backup".
The alert rule is BackupTooOld, expr: time() - backup_last_success_timestamp > 86400, for: 15m, severity warning.
A pod with the default dnsPolicy ClusterFirst gets resolv.conf with search ai-jobs.svc.cluster.local svc.cluster.local cluster.local lab.example.com, nameserver 10.96.0.10, options ndots:5.
The kubelet appends the node's own search domains after the cluster ones, so if nodes carry an internal domain such as lab.example.com, every pod inherits it.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Mechanism well specified, incident unverified
The causal chain is spelled out with reproducible configuration detail - the resolv.conf, the ordered query list, the alert expression, the NetworkPolicy semantics - and each step rests on documented default behavior in Kubernetes DNS and CNI enforcement. But the evidence is one first-person write-up from a single publisher, with no logs, packet captures, query traces, or independent corroboration, and it contains an unresolved arithmetic inconsistency in its own wasted-lookup count.
No adoption signal supplied
The source is an explanatory failure-mode write-up. It contains no releases, deployments, benchmarks, disclosed usage figures, pricing or license changes, and no evidence of how widely this configuration combination occurs beyond the author's characterization of a wildcard record as a common homelab setup. Nothing in the supplied material supports an adoption measurement.
Slightly overstated framing, sound mechanism
The headline framing ('dead switch', 'four layers, zero signals') is dramatic and the piece generalizes a single narrated incident into a systemic gotcha without frequency data or reproduction artifacts, and one of its own counts does not reconcile. The overstatement is mild, though: each mechanical claim is grounded in default component behavior and the article is candid that any single layer alone would be trivial to fix.
Low commercial stake, some self-promotion
No vendor, sponsor, funding, or product being sold appears in the source; the components discussed are open-source infrastructure the author is operating rather than selling. The visible incentive is audience-building on a developer publishing platform, including cross-links to the author's own prior posts on the same DNS mechanism and on Calico default-deny, which rewards dramatic framing but not a particular purchasing decision.
Confident on mechanism, thin on corroboration
Confidence is moderate: the technical reasoning is internally checkable and consistent with documented defaults for ClusterFirst DNS, ndots handling, and NetworkPolicy drops, which supports the core conclusion. It is held down by a one-source cluster, an absent adoption dimension, a truncated remediation section, and one unresolved internal contradiction.
build
One alert, two causes, four green dashboards: the day the stack agreed and was wrong1 distinct publisher
build
Five pods green, GPU at 99 percent, queue up 70x: the Kubernetes dashboard is the wrong instrument1 distinct publisher
build
Rate limit your MCP servers, because a retrying agent turns one error into a billing incident1 distinct publisher
build
Your meter now runs on someone else's machine: signed receipts, fsync, and failing open1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 21, 2026