mirror of
https://github.com/kvcache-ai/AgentENV.git
synced 2026-11-05 01:17:36 +00:00
[GH-ISSUE #413] Node drain outlives the termination grace period; server is SIGKILLed mid-shutdown #103
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#103
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?
Originally created by @dushulin on GitHub (Oct 22, 2026).
Original GitHub issue: https://github.com/kvcache-ai/AgentENV/issues/413
Summary
When a busy node is drained (DaemonSet rollout or pod deletion), the AgentENV server usually never gets to finish its graceful shutdown. It is SIGKILLed while it is still pausing sandboxes.
Two things combine to cause this:
deploy/k8s/base/agentenv-daemonset.yamlhas no deadline, so it can use up the whole termination grace period.run_shutdown_cleanuppauses sandboxes one at a time, so the time the server needs after SIGTERM grows with the number of running sandboxes.The result: running sandboxes that were not paused yet are lost, and
uvm-ublk-daemonis killed while its ublk devices still have live queues and guest I/O in flight. The graceful daemon shutdown added in #266 and #335 never runs.Affected component
Orchestrator / sandbox lifecycle (and the Kubernetes manifest under
deploy/k8s/base)AgentENV version
main@b4ee1b7Host environment
deploy/k8s/base(terminationGracePeriodSeconds: 3600).virtualization_mode = "kvm", Ubuntu 24.04 with the 6.8 GA kernel.Operation and configuration
Rolling update (or any pod deletion) of
agentenv-nodewhile the node still has running sandboxes. The deadline problem needs sandboxes whose timeout is longer than the grace period, for example sandboxes created with a 24h timeout.Steps to reproduce
deploy/k8s/base.timeout> 3600s and keep them running.agentenv-nodepod, or roll the DaemonSet.Expected behavior
Schedule.Actual behavior
1. preStop holds the pod for the whole grace period. The loop waits until
GET /sandboxesreports 0 and has no other exit. Sandboxes with long timeouts never finish within the hour, so preStop runs for the full 3600s. When a preStop hook overruns the grace period, kubelet grants a one-off 2s extension, sends SIGTERM, and sends SIGKILL 2s later. The server gets about 2 seconds for its whole shutdown.2. Shutdown time is linear in the sandbox count.
src/bin/server.rscallsorchestrator.shutdown().run_shutdown_cleanup(src/orchestrator/service.rs) pauses Running sandboxes one by one, awaiting each pause before starting the next.UblkDeviceManager::global().shutdown_daemon()runs only after that returns.What SIGKILL does. It takes out the whole container cgroup at once:
uvm-ublk-daemon;Consequences
Pausedafter the restart.Host crash risk. On kernels without torvalds/linux@f40139fde5 ("ublk: fix race between io_uring_cmd_complete_in_task and ublk_cancel_cmd", merged for 6.15), a ublk server dying with outstanding uring_cmds while block I/O is in flight can crash the host. The Ubuntu 24.04 6.8 GA kernels we checked do not carry that fix. During a rollout we hit one host panic in that path: a NULL dereference in
io_fallback_tw, raised from a ublk queue thread duringdo_exit. That happened when the daemon was killed with devices still registered. AgentENV cannot fix the kernel, but this makes an ungraceful daemon exit far more expensive than "only" losing sandboxes.Logs and diagnostics
Observed during a DaemonSet rollout:
preStop: N sandbox(es) remainingevery 3s until the grace period expired.Paused. 2s is enough for one pause, not for many.Reproduction frequency
Always (whenever running sandboxes outlive the grace period, or there are more of them than the server can pause one by one in the time left)
Proposed fix
run_shutdown_cleanup: preserve sandboxes with bounded concurrency instead of one at a time, so those 10 minutes cover a busy node.I have a PR for both.
Additional context
Pre-submission checklist