Appearance
Harness 实例什么时候能接流量:Network、Secret、Liveness 与 Readiness
前置:Harness 怎么打包而不把状态塞进容器:Image、Dockerfile、Layer 与 Volume
核心问题:进程还活着但 Provider/DB/Secret 已不可用时,为什么 Liveness 仍可能通过而 Readiness 必须失败?
“进程活着”不等于“这个 Harness 能工作”
一个 worker PID 存在,但可能:
- DB schema migration 尚未完成;
- Queue connection 未建立;
- Provider credential 没加载;
- 正在 draining,不应接新 Run;
- Sandbox backend 不可用。
因此 health 必须区分:
text
liveness → 进程是否卡死,需要重启?
readiness → 当前是否应该接新流量/新 work?
draining → 正在退出,只完成/转交已有 workNetwork:依赖连通不等于依赖可信
API/Worker 可在内部 network 访问 DB、Queue、MCP Gateway,但仍需要应用层 auth 和最小 egress。Sandbox network 应单独更严格,不能因为同属 private network 就访问控制面依赖。
服务发现和网络名称是部署便利,不是 security identity。
Secret:模型不应该看到真正 credential
普通配置可以环境变量;高价值 credential 更适合由 secret manager/broker 在执行边界注入。
Harness 特别要避免:
text
API key → Prompt
OAuth token → Tool arguments shown to Model
DB password → Trace metadata
provider credential → Workspace env inherited by untrusted subprocess理想路径:
text
Model emits credential_ref / capability intent
→ Executor/Adapter resolves credential
→ secret only exists at the narrow execution boundary部署层还要控制 child process 是否继承 env。
Readiness 需要反映“能否安全接新工作”
API readiness 可以检查核心初始化是否完成;Worker readiness 可以在 draining、无法访问 StateStore、严重依赖不可用时变 false。
但不要把每个下游短暂波动都变成 liveness failure,否则 Provider 5 秒故障会触发所有实例重启,制造更大风暴。
典型逻辑:
text
startup complete? no → not ready
state store unusable? yes → not ready
shutdown/draining? yes → not ready
provider temporary 429? → process still live; reliability policy handles itFailure Modes
/health 永远 200
后果: rolling deploy 时正在 draining 的 worker 仍接新 Run。
处理: liveness/readiness 分开;shutdown 第一阶段先 readiness=false。
Secret 注入到整个 Sandbox 环境
后果: 不可信命令可以枚举并外传 credential。
处理: credential broker + per-tool injection,不让 workspace subprocess 自动继承控制面 secrets。
如何验证
| 场景 | 必须成立 |
|---|---|
| worker 进入 draining | readiness 立即 false,但 liveness 保持 true |
| Provider 429 30 秒 | 实例不发生重启风暴 |
Sandbox 执行 env | 看不到 Control Plane/Provider secrets |
自测
- 进程还活着但 DB 未连接完成。Liveness 与 Readiness 哪一个应该失败,为什么不能混用?
- 健康检查依赖一个很慢的外部服务,会怎样反过来放大平台重启/摘流量问题?