Skip to content
预计 1 分钟右侧目录可快速定位

容器如何安全退出并可复现部署:Graceful Shutdown、Resource Limit 与 Deployment ​

前置:Harness 实例什么时候能接流量:Network、Secret、Liveness 与 Readiness
核心问题:Rolling Deploy 时有 active Run 正在执行,旧实例怎样停止接单、完成/持久化工作并让新版本安全接管?

Graceful Shutdown:先停止拿新工作,再收束旧工作 ​

Worker 收到 SIGTERM 后不应直接退出。一个更合理的顺序是:

text
mark not-ready / draining
→ stop claiming new Run/Node
→ bounded finish or cancel active execution
→ persist attempt/checkpoint facts
→ release/expire lease safely
→ flush required trace/audit buffers
→ close connections
→ exit before hard-kill deadline

API 实例则先停止接新流量,再处理已有短请求。长 Run 的存在本身不能依赖某个 API connection 或某个 Worker 进程一直活着;未完成任务应能由 durable state 在新进程恢复。

Resource Limit:让失控 Tool 只伤到自己的额度 ​

CPU、memory、pid、disk/time limit 限制执行单元最多消耗多少资源。例如 Sandbox OOM 应被归一化成 resource_exhausted Tool failure,由 Runtime 决定失败、降级或重试,而不是拖垮整个 Harness 服务。

Resource limit 是运行稳定性边界,不等价于 Security Sandbox;权限、网络和 credential 仍由 Module 17 的安全策略负责。

Reproducible Deployment:能回答“这次 Run 跑的到底是哪一版” ​

部署 artifact 应尽可能由固定的:

text
source commit
+ dependency lock
+ base image digest
+ build config
→ immutable image digest

生成。使用 floating latest、未锁依赖或不可追踪配置,会导致“同一个版本号”实际上运行不同代码。

RunManifest 可以记录 application commit、image digest、runtime/state schema version 和关键 policy version。排障时才能把历史 Run 对回当时真正运行的环境,而不是用今天的代码解释昨天的问题。

Rolling Upgrade 还要考虑长 Run 的恢复兼容性 ​

普通无状态 API 只要逐步替换实例;Harness 还可能存在昨天创建、今天仍处于 WAITING_APPROVAL 的 Run。新 Worker 接管前至少要确认:

text
old checkpoint/event schema
pending Tool / approval contract
runtime compatibility policy

兼容时直接恢复;需要 migration 时走显式 state migration;如果高风险 pending action 的语义或权限已经变化,应 fail closed 或重新审批。

所以 Deployment 负责提供“哪个版本正在运行”,Runtime/State 层负责判断“旧 Run 能不能被这个版本安全恢复”。两者不要混成自动猜测。

Failure Modes ​

收到 SIGTERM 后仍继续 claim 新任务 ​

后果: orchestrator hard-kill 时留下更多未完成 attempt,lease/retry 数量反而增加。

处理: shutdown 第一阶段先进入 draining/not-ready,再收束已有工作。

只记录可漂移的镜像 Tag ​

后果: 无法证明某个历史 Run 实际执行的是哪份代码和依赖。

处理: 记录 immutable image digest + source/config/schema version,并验证可从同一输入重建 artifact。

如何验证 ​

场景必须成立
Worker 正在执行时发送 SIGTERM不再 claim 新任务,active work 按 policy 完成/恢复,最终在 grace deadline 前退出
Sandbox 超过 memory limitTool 被隔离终止,主服务继续工作并记录 normalized error
旧版本 WAITING Run 被新 Worker 接管先执行 compatibility/migration policy,不静默按新 schema 解释旧状态
同一 release 重新构建关键 dependency/source/version 可追溯,RunManifest 能定位实际 image digest

自测 ​

  1. Rolling deploy 时一个 Worker 正持有 active Run。Graceful shutdown 应先停止接新任务、等待/转移哪些状态,再退出?
  2. 同一代码在两次部署装出不同依赖,说明镜像/构建哪一层没有做到 reproducible?

Sources ​

AI Engineering · Agent · Harness · Backend Systems