containerd 与 shim
定义
containerd 是一个守护进程:它管理镜像、容器元数据,并实现 CRI,因而可以直接被 kubelet 使用。containerd 不在守护进程内部完成全部隔离与进程启动;它通过 runtime-v2 shim 把一次容器(或一类 RuntimeClass)交给底层运行时。
shim 是一个小进程。它的职责是:与 containerd 保持约定好的 API,转译 start / kill / wait / delete,并盯住底层进程或虚拟机的真实状态。守护进程重启时,shim 仍可继续持有那次执行,从而避免把容器状态完全绑在守护进程的内存里。
问题背景
若 containerd 直接 clone
出所有容器进程,则守护进程崩溃会牵连全部容器,也难以为不同工作负载换不同的底层运行时。引入
shim 之后,containerd 成为「镜像与元数据的管理者」,具体执行可以是
runc、gVisor,或 A3S Box / A3S OCI Runtime。
机制说明
两条进入 Box 的路径
要把 Kubernetes 工作负载落到 Box,存在两条工程路径。
| 路径 | 调用链 | Box 中的代码 |
|---|---|---|
| 直接 CRI | kubelet → Box CRI 服务器 → LocalExecutionManager |
src/cri/ |
| containerd shim | kubelet → containerd → runtime-v2 shim → Box | containerd-shim/ |
第一条路径让 kubelet 把 Box 当成运行时。第二条路径让已有 containerd
节点通过 RuntimeClass 选择 Box,而不替换整套
CRI。二者都是适配层;产品状态与隔离实现仍在
src/runtime/。
OCI Runtime 自己的 shim
A3S OCI Runtime 仓库也包含 crates/containerd-shim。那是
Runtime 作为底层执行器时的入口,与 Box 仓库根目录的
containerd-shim/ 不是同一二进制。阅读代码时先确认仓库:Box
的 shim 面向产品生命周期;Runtime 的 shim 面向 bundle 执行。
与 a3s-box-shim 的名称碰撞
src/shim/ 中的 a3s-box-shim 是 MicroVM 的
libkrun 子进程,不是 containerd runtime-v2 shim。libkrun 的
krun_start_enter()
会接管当前进程,因此必须单独启动一个进程当 VMM,以免 CLI 或 SDK
进程被接管。名称都叫 shim,职责完全不同。详见 一条 run 命令的调用链。
在 Box 中的位置
- containerd 集成:仓库根
containerd-shim/。 - 部署样例:
deploy/shim/、deploy/helm/。 - MicroVM 进程隔离 shim:
src/shim/src/main.rs。 - 平台状态仍标注为预览,不声明完整 CRI 符合性。
验证命令
在已配置 RuntimeClass 的集群中,创建使用该 RuntimeClass 的
Pod,然后在节点上检查是否出现对应的 shim 进程与 box
记录。没有集群时,比较 containerd-shim/src 与
src/shim/src 的 crate 说明即可区分两条「shim」路径。
相关与易混
- 相关:CRI、Kubernetes、OCI 标准与 bundle
- 易混:containerd 不是 Docker Desktop,也不是 Kubernetes 控制面。Docker 引擎在较新版本中可以在下方使用 containerd。看到「shim」时,先判断它属于 containerd、OCI Runtime,还是 Box 的 libkrun 子进程。