mirror of
https://github.com/kvcache-ai/AgentENV.git
synced 2026-11-05 01:17:36 +00:00
[PR #111] [CLOSED] feat(deploy): bootstrap node prerequisites and cap runtime footprint #187
Labels
No labels
bug
documentation
enhancement
enhancement
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/AgentENV#187
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/kvcache-ai/AgentENV/pull/111
Author: @cleverhu
Created: 8/3/2026
Status: ❌ Closed
Base:
main← Head:feat/k8s-daemonset-node-bootstrap📝 Commits (1)
1b7fb3efeat(deploy): bootstrap node prerequisites and cap runtime footprint📊 Changes
1 file changed (+52 additions, -0 deletions)
View changed files
📝
deploy/k8s/base/agentenv-daemonset.yaml(+52 -0)📄 Description
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
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.