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

Harness 怎么打包而不把状态塞进容器:Image、Dockerfile、Layer 与 Volume ​

前置:Harness API、Worker 与 Sandbox 应暴露什么:Linux Permission、Network 与 Port
核心问题:Image、Container、Layer、Volume 生命周期不同,哪些东西可以打进镜像,哪些 Runtime 状态绝不能依赖容器层保存?

先把四种状态分开 ​

text
Image
→ 程序代码、锁定依赖、启动入口

Container writable layer
→ 可丢的运行时临时文件

Workspace / Artifact volume
→ Agent 操作的文件、构建产物(按 session policy 管理)

Durable Runtime Store
→ Run/Node/Checkpoint/Approval/Event/Idempotency facts

最常见的错误是看到 Volume 能持久化,就把 SQLite checkpoint、Queue state、Workspace 全塞进同一个目录。单机 demo 能跑,多实例、回滚和恢复会迅速失去边界。

Image / Container ​

Image 是不可变部署工件;Container 是 Image 的运行实例。容器被替换应当是正常操作,因此一个 active Run 不能依赖“这台容器的内存/可写层永远存在”。

这也是 graceful shutdown、checkpoint、worker lease 存在的原因。

Dockerfile 要为可复现和最小运行面服务 ​

Harness worker 常需要 Python build dependency,但生产镜像不需要编译器。使用 multi-stage build:

text
builder
→ install/build wheel
→ runtime image 只复制产物与必要 runtime dependency

同时:

  • pin base image / lock dependency;
  • 非 root user;
  • 明确 WORKDIR/ENTRYPOINT;
  • 不把 secret bake 进 build arg/layer;
  • 记录最终 image digest 到 deployment/run manifest。

Layer / Build Cache 只优化构建,不保存运行事实 ​

常见顺序:

dockerfile
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen ...
COPY src ./src

这样源码变化不会让依赖层每次失效。

但 Build Cache 可能保留历史输入,所以 API key、credential 不应通过普通 COPY/RUN 写入 layer。

Volume 用于文件生命周期,不等于数据库一致性 ​

Workspace/Sandbox 可能需要 volume 让后续 Run 继续看到文件,但要定义:

  • session/workspace identity;
  • 多 worker 是否允许同时挂载;
  • snapshot/cleanup policy;
  • artifact 与 source 的权限;
  • volume 丢失后的恢复策略。

对于 Run state,优先使用真正的 durable store;Volume 不是 event log、transaction 或 distributed coordination substitute。

Failure Modes ​

Container local file 是唯一 Checkpoint ​

后果: reschedule 到另一个节点后无法 resume。

处理: checkpoint 进入 durable store;本地文件只能做 cache/temporary workspace。

Mutable Tag 无法复现旧 Run ​

处理: deployment 使用 immutable digest,并把 image/config revision 纳入 RunManifest。

如何验证 ​

场景必须成立
删除并重建 worker containerpaused Run 仍能恢复
同 release 在另一节点启动image digest/config 相同
清空 container writable layerdurable Runtime facts 不丢

自测 ​

  1. 把 Runtime checkpoint 写进容器可写层,容器重建后会发生什么?哪些状态应放 Volume/外部 Store?
  2. Dockerfile 把 secret 写进某一层后即使下一层删除,为什么镜像历史里仍可能泄露?

Sources ​

AI Engineering · Agent · Harness · Backend Systems