feat(deploy): bootstrap node prerequisites and cap runtime footprint - #111
Open
cleverhu wants to merge 1 commit into
Open
feat(deploy): bootstrap node prerequisites and cap runtime footprint#111cleverhu wants to merge 1 commit into
cleverhu wants to merge 1 commit into
Conversation
Two initContainers make a node ready before the server starts. load-ublk chroots into the host root so modprobe resolves ublk_drv against the node's running kernel, which the server's startup check requires. seed-deps copies the runtime assets baked into the image at /workspace/env into the hostPath that mounts over them, so the server does not re-download firecracker, the kernel and the overlaybd package on every node; --update=none leaves existing host state alone. The runtime also sizes its thread pools from the host core count, which on a large node means hundreds of tokio workers, each holding a jemalloc arena. Cap the worker count and the arena count, and shorten the dirty page decay so resident memory drops back after one-off work such as image conversion.
Contributor
|
✅ OpenCodeReview: Review complete: 0 finding(s) across 1 selected item(s). |
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.
What
Two additions to the node DaemonSet:
load-ublkandseed-depsinitContainers that make a node ready before the server starts.TOKIO_WORKER_THREADSand_RJEM_MALLOC_CONFon the runtime container to stop thread and arena counts from scaling with the host core count.Why
Bootstrap. The server's startup check requires
ublk_drvto be loaded in the host kernel and fails with an actionable error when it is not. Nothing in the manifest loaded it, so the DaemonSet only came up on nodes where an operator had done it by hand.Separately, the
workspacehostPath mounts over/workspace, which shadows the runtime assets the image bakes into/workspace/env(firecracker, the kernel, the overlaybd package, regctl). The server therefore re-downloaded all of them on every node on first start, despite them being present in the image it was just pulled from.Footprint. Both the main runtime and the Firecracker pool runtime size their thread pools from the host core count. On a large node that is hundreds of tokio workers, each holding a jemalloc arena, which inflates the address space; the sandbox start path also spawns helper processes (
iptables,ip) whose cost scales with it. jemalloc separately defaults to 4x the core count in arenas and holds dirty pages for 10 s, so resident memory stays high long after one-off work such as image conversion.Related issue
None. Deployment-manifest change with no code impact.
Scope and non-goals
Included: the initContainers, the host-root volume they need, and the two runtime environment variables.
Explicitly excluded, because they were part of the same internal change but are site-specific:
imagePullPolicy: Always. The initContainers reuseagentenv-runtime:latestwithIfNotPresent, matching the existing container.resources.requests.cpuvalue. It was8internally, which would make the DaemonSet unschedulable on small nodes; it belongs in an overlay, not the base.Design and behavior changes
load-ublkruns privileged andchroot /host modprobe ublk_drv, so modprobe resolves modules for the node's running kernel rather than the container image, then lists/dev/ublk-controlso a failure is visible in the init logs rather than surfacing later as a confusing server error. It mounts the host root read-only. It requires a newhost-roothostPath volume.seed-depscopies/workspace/env/.from the image into the hostPath withcp -a --update=none, so existing host state is never overwritten — only missing files are filled in. It is not privileged.Both are initContainers, so the runtime container starts only after they succeed. On a node missing
ublk_drventirely the pod now fails in init with a clear message instead of crash-looping the server.TOKIO_WORKER_THREADS=32caps the tokio pool._RJEM_MALLOC_CONF=narenas:8,dirty_decay_ms:1000,muzzy_decay_ms:0,background_thread:truecaps arenas and shortens decay so pages are returned promptly.Compatibility and operations
seed-depsis idempotent and never overwrites, so rollback to the previous manifest leaves a working/var/lib/aenv. The addedhost-rootvolume is removed with the manifest./dev. This adds a read-only mount of the host root for the init step only.Validation
make fmtmake clippymake test-unitmake -C services test(required whenservices/changes)maketargetCommands and results:
Skipped checks and reasons:
kubectl apply --dry-run=serveron a real cluster is the check I could not run here.Risks and reviewer notes
Mounting the host root, even read-only, is the change that deserves the most scrutiny. It is confined to the
load-ublkinitContainer and is the standard way tomodprobeagainst the node kernel; the alternative is requiring operators to pre-load the module out of band, which is what this replaces.TOKIO_WORKER_THREADS=32is a fixed number rather than a fraction of the node. On a node with fewer than 32 cores it oversubscribes slightly; on a very large node it may be conservative. A percentage would be better but is not expressible in a plain manifest.cp -a --update=nonerequires a coreutils new enough to support--update=none; the runtime image's Debian base has it.Most important file:
deploy/k8s/base/agentenv-daemonset.yaml.Checklist