feat: drop a NodeInventory whose publishedAt trails the fleet's newest publish by more than --inventory-stale-after - #59
Merged
Conversation
…t the applier delete one A dead node's last NodeInventory stayed a claim candidate, kept its sandboxes listed as running, and drew warm-pool PUTs and envd-proxy probes until its Node object went away. NodeInventory gains publishedAt; kubeinventory.Source omits an inventory whose publishedAt is older than StaleAfter (90 s, three publish intervals) from ListNodes and answers NotFound for it from NodeInventory and NodeCapacity, so every consumer of the source drops the node at once and the watch emits Deleted for its entries, as mesh mode's MaxStale does. An inventory without publishedAt, from a vk-sandbox that predates the field, counts as fresh so an upgrade never empties the fleet. InventoryApplier gains Delete (not-found is success), for vk-sandbox to remove its inventory on a graceful exit. StaticInventorySource.Delete replaces Remove. sandbox-apiserver and sandbox-envd-proxy take --inventory-stale-after through kubeinventory.Options.AddFlags.
… costs; flag help names its own process Helm never upgrades crds/, and an older CRD prunes publishedAt so no node goes stale; the age uses the reading host's clock; a vk-sandbox restart also drops an e2b kill (404), answers 502 on the data plane, and moves the node's warm-pool share. The shared flag help now scopes itself to the process that parses it.
… drop the applier delete CMGS's K1 decision. The reference is min(newest publishedAt ListNodes saw, now), kept on the Source as unix nanos; an inventory whose stamp trails it by more than StaleAfter is dropped from ListNodes, and NodeInventory and NodeCapacity compare against the last stored reference (zero before the first list, which leaves every node fresh). A control-plane write outage freezes every stamp together, so it never empties the fleet; a publisher clock ahead of the reader's is capped by now and cannot evict the others; the reader's clock no longer decides a node's age. Missing or unparsable stamps stay fresh. Option 3 is dropped: InventoryApplier is Apply-only again and StaticInventorySource.Remove is restored, so a vk-sandbox restart inside the window changes nothing. Docs drop the restart flap and gain the outage row.
…, and a control-plane outage stops only the driver's lease holder Measured on the kube kit: the reference advances only when a live node publishes, so a dead node left 120.8 s after its last stamp; with kube-apiserver down 150 s the replica holding the warm-pool lease exited on the lost lease (pre-existing), while the second replica and envd-proxy kept every node listed and a claim landed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Head:
6b9cb2e8a1d1e2ec3888c0aada593371d671f582, 4 commits on master6da4f6f7. Commit835f250creworks the first two to CMGS's K1 decision, and6b9cb2e8corrects the docs from the hardware results.K1: NodeInventory freshness on the Kubernetes path, as section 9 of the e2b drop-in plan was rewritten after the decision:
The vk-sandbox follow-up, which only stamps
publishedAt, follows once this merges and is pinned to it.What
publishedAt:NodeInventorygainspublishedAt(metav1.Time, omitempty). The CRD underhelm/crdsanddocs/api.mdare regenerated.kubeinventory.Options{StaleAfter}defaults to 90 s, and the constructor is nowNew(reader, opts). In the passListNodesalready makes, it computes reference = min(newestpublishedAt, now) and stores it on the Source as atomic unix nanos.ListNodesdrops an inventory whose stamp trails the reference by more thanStaleAfter.NodeInventoryandNodeCapacitycompare against the last stored reference and answer a wrappedNotFoundfor a stale node.--inventory-stale-after(default 90s) onsandbox-apiserverandsandbox-envd-proxy, throughkubeinventory.Options.AddFlags.InventoryApplierstays Apply-only, andStaticInventorySource.Removeis unchanged from master.configuration.md: flag rows; the reference semantics; that a dead node leaves between the window and one publish interval later, because the reference only advances when a live node publishes; the CRD-plus-vk-sandbox upgrade condition.e2b-compat.md: the limit.scaling-design.md: the dead-node row, and a control-plane outage row.helm/README.md:publishedAtnamed among the pruned fields.Closure
NodeInventory.PublishedAtkubeinventory.Source; vk-sandbox's publisher in the follow-upkubeinventory.Options,.StaleAfter,.AddFlagscmd/sandbox-apiserver,cmd/sandbox-envd-proxyPackage edges: none added. kubeinventory's new imports are pflag, apimachinery
api/errorsandruntime/schema, all external, plus stdlibsync/atomic.The exported scale surface is unchanged from master.
Comment delta
The additions are the field doc with its
+optionalmarker, and godocs onOptions,StaleAfterandAddFlags.LOC
Hot path
ListNodesparses each node's RFC3339 stamp once and takes oneminagainst the clock. It stores one atomic value and allocates one stamp slice per call. A point lookup costs one parse and one atomic load.A/B on
BenchmarkClientInventoryWarmCandidates/*/nocopy, the informer-fed production read path with stamped inventories. Base and the rework head ran interleaved over 4 rounds with the order swapped:Hardware
The kube kit on the test hosts runs:
835f250c(6b9cb2e8changes docs only);76ec64d, on this branch;k1-a, a vk-sandbox serving host A's sandboxd, and nodek1-b, a vk-sandbox serving host B's;SandboxWarmPoolof 4, the e2b API, and default windows of 30 s publish and 90 s stale.Lane (a), hard kill,
kill -9of B's sandboxd and B's vk-sandbox, with 7 fresh sandboxes on B:Lane (b), reworked: SIGTERM and restart of B's vk-sandbox only, inside the window:
Lane (c), an old publisher, vk-sandbox
7d15e45, which never stamps:Outage lane: kube-apiserver killed for 138 s, with two apiserver replicas as the chart ships. Replica 1 held the warm-pool lease; replica 2 had e2b on its own port.
startWarmPoolDrivercallsfailwhenmgr.Startreturns "leader election lost". With the chart's 2 replicas, the other keeps serving. A single-replica deployment loses its e2b API for the outage. The outage row inscaling-design.mdsays so. Whether the driver should survive a lost lease is a separate decision.Harness notes:
Review
25d0e940: /simplify, altitude and /code are in the history of this PR.>=, +1 s), the min against now (removed either way), the store, the list filter, the get filter, the zero stamp, the parse error, andmaxvsmin. Every mutation is caught.StaleAfter, and the stamp parser.Gates
GOWORK=off make lint: 8 ×0 issues.make fmt-check: clean.asl -forwarder=falseon both GOOS: clean.go mod tidy -diff: clean.make generate: leaves no diff.go test -race -count=1 ./...: ok.go vetclean,go test -race ./...ok.