containerd 2.1.8 超深度源码分析 --- 总体架构与模块全景
分析对象:
github.com/containerd/containerdv2.1.8代码根目录:
/home/lin/src/github.com/containerd-2.1.8非测试非vendor Go源码:948 文件,174,070 行
一、项目定位
1.1 containerd 是什么
containerd 是云原生容器运行时的 核心基础设施层,介于编排系统(Kubernetes)和底层运行时(runc)之间:
- 容器生命周期管理:创建/启动/停止/删除容器
- 镜像分发与存储:pull/push/内容寻址存储
- 执行与运行时:任务管理、shim 进程管理
- 快照与差异:overlayfs/btrfs/devicemapper 快照
- CRI 兼容:直接对接 kubelet
1.2 在容器生态中的位置
#mermaid-svg-uxWfDkXt7w6isEoP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-uxWfDkXt7w6isEoP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-uxWfDkXt7w6isEoP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-uxWfDkXt7w6isEoP .error-icon{fill:#552222;}#mermaid-svg-uxWfDkXt7w6isEoP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-uxWfDkXt7w6isEoP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-uxWfDkXt7w6isEoP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-uxWfDkXt7w6isEoP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-uxWfDkXt7w6isEoP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-uxWfDkXt7w6isEoP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-uxWfDkXt7w6isEoP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-uxWfDkXt7w6isEoP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-uxWfDkXt7w6isEoP .marker.cross{stroke:#333333;}#mermaid-svg-uxWfDkXt7w6isEoP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-uxWfDkXt7w6isEoP p{margin:0;}#mermaid-svg-uxWfDkXt7w6isEoP .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-uxWfDkXt7w6isEoP .cluster-label text{fill:#333;}#mermaid-svg-uxWfDkXt7w6isEoP .cluster-label span{color:#333;}#mermaid-svg-uxWfDkXt7w6isEoP .cluster-label span p{background-color:transparent;}#mermaid-svg-uxWfDkXt7w6isEoP .label text,#mermaid-svg-uxWfDkXt7w6isEoP span{fill:#333;color:#333;}#mermaid-svg-uxWfDkXt7w6isEoP .node rect,#mermaid-svg-uxWfDkXt7w6isEoP .node circle,#mermaid-svg-uxWfDkXt7w6isEoP .node ellipse,#mermaid-svg-uxWfDkXt7w6isEoP .node polygon,#mermaid-svg-uxWfDkXt7w6isEoP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-uxWfDkXt7w6isEoP .rough-node .label text,#mermaid-svg-uxWfDkXt7w6isEoP .node .label text,#mermaid-svg-uxWfDkXt7w6isEoP .image-shape .label,#mermaid-svg-uxWfDkXt7w6isEoP .icon-shape .label{text-anchor:middle;}#mermaid-svg-uxWfDkXt7w6isEoP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-uxWfDkXt7w6isEoP .rough-node .label,#mermaid-svg-uxWfDkXt7w6isEoP .node .label,#mermaid-svg-uxWfDkXt7w6isEoP .image-shape .label,#mermaid-svg-uxWfDkXt7w6isEoP .icon-shape .label{text-align:center;}#mermaid-svg-uxWfDkXt7w6isEoP .node.clickable{cursor:pointer;}#mermaid-svg-uxWfDkXt7w6isEoP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-uxWfDkXt7w6isEoP .arrowheadPath{fill:#333333;}#mermaid-svg-uxWfDkXt7w6isEoP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-uxWfDkXt7w6isEoP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-uxWfDkXt7w6isEoP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-uxWfDkXt7w6isEoP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-uxWfDkXt7w6isEoP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-uxWfDkXt7w6isEoP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-uxWfDkXt7w6isEoP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-uxWfDkXt7w6isEoP .cluster text{fill:#333;}#mermaid-svg-uxWfDkXt7w6isEoP .cluster span{color:#333;}#mermaid-svg-uxWfDkXt7w6isEoP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-uxWfDkXt7w6isEoP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-uxWfDkXt7w6isEoP rect.text{fill:none;stroke-width:0;}#mermaid-svg-uxWfDkXt7w6isEoP .icon-shape,#mermaid-svg-uxWfDkXt7w6isEoP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-uxWfDkXt7w6isEoP .icon-shape p,#mermaid-svg-uxWfDkXt7w6isEoP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-uxWfDkXt7w6isEoP .icon-shape .label rect,#mermaid-svg-uxWfDkXt7w6isEoP .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-uxWfDkXt7w6isEoP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-uxWfDkXt7w6isEoP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-uxWfDkXt7w6isEoP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 网络层
存储层
底层运行时
高层运行时 (本项目)
编排层
CRI gRPC
containerd API
Kubernetes
(kubelet)
Docker Engine
containerd
(daemon)
CRI Plugin
containerd-shim-runc-v2
runc
runhcs (Windows)
BoltDB (metadata)
Content Store (blobs)
Snapshotter (overlayfs/btrfs)
CNI Plugins
1.3 核心能力
| # | 能力 | 对应模块 |
|---|---|---|
| 1 | Plugin 体系 | 插件注册/依赖解析/初始化 |
| 2 | gRPC + ttrpc 双协议 | daemon 暴露 gRPC,shim 通信用 ttrpc |
| 3 | Metadata 存储 | BoltDB + 8 类 bucket |
| 4 | Content 寻址存储 | CAS (Content Addressable Storage) |
| 5 | Snapshot 管理 | overlayfs/btrfs/devicemapper/native |
| 6 | Diff 计算 | walking diff / differ 插件 |
| 7 | 镜像管理 | pull/push/unpack/resolve |
| 8 | Runtime 抽象 | PlatformRuntime + Task 接口 |
| 9 | Shim 进程管理 | shim v2 (一容器一shim → 多容器一shim) |
| 10 | Sandbox 支持 | Pod 级沙箱 + 独立控制器 |
| 11 | 事件系统 | 异步事件总线 + namespace 隔离 |
| 12 | GC 回收 | 标记-清除式垃圾收集 |
| 13 | Transfer 服务 | 统一传输接口 (pull/push/import/export) |
| 14 | CRI 插件 | CRI 兼容层 (Pod/Sandbox/Container) |
| 15 | NRI 集成 | Node Resource Interface 插件 |
二、源码目录结构与行数
2.1 顶层模块行数
| 模块 | 行数 | 文件数 | 功能 |
|---|---|---|---|
api/ |
38,331 | 108 | Protobuf API 定义 + gRPC/ttrpc 服务桩 |
core/ |
37,903 | 181 | 核心业务逻辑(metadata/content/snapshot/diff/runtime/sandbox/images/remotes/mount/transfer/events/leases/streaming/unpack/containers/introspection/metrics) |
internal/ |
31,572 | 205 | 内部工具(shim/runtime/task/userns/eventq/nri/erofs/kmutex/registrar/failpoint...) |
cmd/ |
19,796 | 125 | CLI入口(containerd/ctr/shim/stress)+ builtins |
plugins/ |
17,944 | 99 | 插件实现(gc/sandbox/restart/transfer/streaming/cri/metadata/events/nri/leases/services/imageverifier) |
pkg/ |
16,495 | 149 | 公共工具包(oci/archive/shim/filters/sys/cio/netns/tracing/progress/namespaces/reference/gc/...) |
client/ |
6,744 | 30 | Go SDK(New/Container/Task/Image/Pull/Transfer/Events/...) |
contrib/ |
1,951 | 15 | 贡献代码(apparmor/seccomp/nvidia/gce) |
defaults/ |
251 | 8 | 默认配置常量 |
version/ |
41 | 1 | 版本信息 |
2.2 core/ 子模块详解
| 子模块 | 行数 | 功能 |
|---|---|---|
metadata/ |
6,217 | BoltDB 元数据存储(containers/images/content/gc/leases/namespaces) |
mount/ |
2,155 | Mount 操作封装 |
images/ |
1,135 | 镜像管理 |
content/ |
617 | 内容寻址存储接口 |
unpack/ |
599 | 镜像解压 |
runtime/ |
554 | 运行时抽象(PlatformRuntime/Task/IO) |
remotes/ |
516 | 远程仓库访问 |
sandbox/ |
411 | 沙箱管理 |
diff/ |
684 | 差异计算 |
snapshots/ |
397 | 快照管理接口 |
leases/ |
245 | 租约管理 |
events/ |
80 | 事件接口 |
transfer/ |
178 | 传输服务 |
streaming/ |
47 | 流管理 |
containers/ |
117 | 容器数据模型 |
introspection/ |
30 | 自省服务 |
三、六层架构
#mermaid-svg-QyQE87AT3xnk7ZAn{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QyQE87AT3xnk7ZAn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QyQE87AT3xnk7ZAn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QyQE87AT3xnk7ZAn .error-icon{fill:#552222;}#mermaid-svg-QyQE87AT3xnk7ZAn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QyQE87AT3xnk7ZAn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QyQE87AT3xnk7ZAn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QyQE87AT3xnk7ZAn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QyQE87AT3xnk7ZAn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QyQE87AT3xnk7ZAn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QyQE87AT3xnk7ZAn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QyQE87AT3xnk7ZAn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QyQE87AT3xnk7ZAn .marker.cross{stroke:#333333;}#mermaid-svg-QyQE87AT3xnk7ZAn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QyQE87AT3xnk7ZAn p{margin:0;}#mermaid-svg-QyQE87AT3xnk7ZAn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QyQE87AT3xnk7ZAn .cluster-label text{fill:#333;}#mermaid-svg-QyQE87AT3xnk7ZAn .cluster-label span{color:#333;}#mermaid-svg-QyQE87AT3xnk7ZAn .cluster-label span p{background-color:transparent;}#mermaid-svg-QyQE87AT3xnk7ZAn .label text,#mermaid-svg-QyQE87AT3xnk7ZAn span{fill:#333;color:#333;}#mermaid-svg-QyQE87AT3xnk7ZAn .node rect,#mermaid-svg-QyQE87AT3xnk7ZAn .node circle,#mermaid-svg-QyQE87AT3xnk7ZAn .node ellipse,#mermaid-svg-QyQE87AT3xnk7ZAn .node polygon,#mermaid-svg-QyQE87AT3xnk7ZAn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QyQE87AT3xnk7ZAn .rough-node .label text,#mermaid-svg-QyQE87AT3xnk7ZAn .node .label text,#mermaid-svg-QyQE87AT3xnk7ZAn .image-shape .label,#mermaid-svg-QyQE87AT3xnk7ZAn .icon-shape .label{text-anchor:middle;}#mermaid-svg-QyQE87AT3xnk7ZAn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QyQE87AT3xnk7ZAn .rough-node .label,#mermaid-svg-QyQE87AT3xnk7ZAn .node .label,#mermaid-svg-QyQE87AT3xnk7ZAn .image-shape .label,#mermaid-svg-QyQE87AT3xnk7ZAn .icon-shape .label{text-align:center;}#mermaid-svg-QyQE87AT3xnk7ZAn .node.clickable{cursor:pointer;}#mermaid-svg-QyQE87AT3xnk7ZAn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QyQE87AT3xnk7ZAn .arrowheadPath{fill:#333333;}#mermaid-svg-QyQE87AT3xnk7ZAn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QyQE87AT3xnk7ZAn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QyQE87AT3xnk7ZAn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QyQE87AT3xnk7ZAn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QyQE87AT3xnk7ZAn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QyQE87AT3xnk7ZAn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QyQE87AT3xnk7ZAn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QyQE87AT3xnk7ZAn .cluster text{fill:#333;}#mermaid-svg-QyQE87AT3xnk7ZAn .cluster span{color:#333;}#mermaid-svg-QyQE87AT3xnk7ZAn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QyQE87AT3xnk7ZAn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QyQE87AT3xnk7ZAn rect.text{fill:none;stroke-width:0;}#mermaid-svg-QyQE87AT3xnk7ZAn .icon-shape,#mermaid-svg-QyQE87AT3xnk7ZAn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QyQE87AT3xnk7ZAn .icon-shape p,#mermaid-svg-QyQE87AT3xnk7ZAn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QyQE87AT3xnk7ZAn .icon-shape .label rect,#mermaid-svg-QyQE87AT3xnk7ZAn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QyQE87AT3xnk7ZAn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QyQE87AT3xnk7ZAn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QyQE87AT3xnk7ZAn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Layer 6: OS/Kernel
Layer 5: Shim (cmd/shim + internal/shim)
Layer 4: Plugin 体系 (plugins/ + internal/)
Layer 3: Core 业务 (core/)
Layer 2: Client SDK (client/)
Layer 1: API 层 (api/)
gRPC Services
(containers/images/content/tasks/snapshots/diff/leases/sandbox/transfer/version/events/namespaces)
ttrpc Services
(events/task v2)
Protobuf Types
(task/runc/transfer/runtimeoptions)
Client
Container
Task
Image
Pull/Transfer
Events
Metadata (BoltDB)
Content Store (CAS)
Snapshotter
Diff Service
Runtime (Task)
Sandbox
Image Manager
Remotes (Registry)
Events Bus
GC Scheduler
Transfer Service
Plugin Registry
Plugin Init (依赖图)
CRI Plugin
NRI Plugin
Restart Monitor
Streaming Manager
GC Scheduler Plugin
Shim Manager
Shim Process
Task Service (ttrpc)
containerd-shim-runc-v2
runc
overlayfs/btrfs
Linux Kernel
四、核心数据流
4.1 镜像拉取完整流程
Metadata (BoltDB) Snapshotter Content Store Docker Hub (Registry) Transfer Service containerd Client 用户/Controller Metadata (BoltDB) Snapshotter Content Store Docker Hub (Registry) Transfer Service containerd Client 用户/Controller #mermaid-svg-YgUZReaO8siWQnvc{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YgUZReaO8siWQnvc .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YgUZReaO8siWQnvc .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YgUZReaO8siWQnvc .error-icon{fill:#552222;}#mermaid-svg-YgUZReaO8siWQnvc .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YgUZReaO8siWQnvc .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YgUZReaO8siWQnvc .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YgUZReaO8siWQnvc .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YgUZReaO8siWQnvc .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YgUZReaO8siWQnvc .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YgUZReaO8siWQnvc .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YgUZReaO8siWQnvc .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YgUZReaO8siWQnvc .marker.cross{stroke:#333333;}#mermaid-svg-YgUZReaO8siWQnvc svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YgUZReaO8siWQnvc p{margin:0;}#mermaid-svg-YgUZReaO8siWQnvc .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-YgUZReaO8siWQnvc text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-YgUZReaO8siWQnvc .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-YgUZReaO8siWQnvc .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-YgUZReaO8siWQnvc .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-YgUZReaO8siWQnvc .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-YgUZReaO8siWQnvc #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-YgUZReaO8siWQnvc .sequenceNumber{fill:white;}#mermaid-svg-YgUZReaO8siWQnvc #sequencenumber{fill:#333;}#mermaid-svg-YgUZReaO8siWQnvc #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-YgUZReaO8siWQnvc .messageText{fill:#333;stroke:none;}#mermaid-svg-YgUZReaO8siWQnvc .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-YgUZReaO8siWQnvc .labelText,#mermaid-svg-YgUZReaO8siWQnvc .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-YgUZReaO8siWQnvc .loopText,#mermaid-svg-YgUZReaO8siWQnvc .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-YgUZReaO8siWQnvc .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-YgUZReaO8siWQnvc .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-YgUZReaO8siWQnvc .noteText,#mermaid-svg-YgUZReaO8siWQnvc .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-YgUZReaO8siWQnvc .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-YgUZReaO8siWQnvc .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-YgUZReaO8siWQnvc .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-YgUZReaO8siWQnvc .actorPopupMenu{position:absolute;}#mermaid-svg-YgUZReaO8siWQnvc .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-YgUZReaO8siWQnvc .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-YgUZReaO8siWQnvc .actor-man circle,#mermaid-svg-YgUZReaO8siWQnvc line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-YgUZReaO8siWQnvc :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} loop每个 layer blob client.Pull("docker.io/library/nginx:latest")Transfer.Pull(ref)Resolve ref → 获取 manifest digestFetch manifestWriteBlob(manifest)Fetch config blobWriteBlob(config)Fetch layer blobWriteBlob(layer)Unpack(layer blobs) → Apply diffCreateImage("nginx:latest", manifest digest)Image*Image
4.2 容器创建完整流程
Metadata runc containerd-shim Shim Manager Tasks Service (gRPC) containerd Client 用户 Metadata runc containerd-shim Shim Manager Tasks Service (gRPC) containerd Client 用户 #mermaid-svg-rKBRvJOsRIGYGWLO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rKBRvJOsRIGYGWLO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rKBRvJOsRIGYGWLO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rKBRvJOsRIGYGWLO .error-icon{fill:#552222;}#mermaid-svg-rKBRvJOsRIGYGWLO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rKBRvJOsRIGYGWLO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rKBRvJOsRIGYGWLO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rKBRvJOsRIGYGWLO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rKBRvJOsRIGYGWLO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rKBRvJOsRIGYGWLO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rKBRvJOsRIGYGWLO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rKBRvJOsRIGYGWLO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rKBRvJOsRIGYGWLO .marker.cross{stroke:#333333;}#mermaid-svg-rKBRvJOsRIGYGWLO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rKBRvJOsRIGYGWLO p{margin:0;}#mermaid-svg-rKBRvJOsRIGYGWLO .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rKBRvJOsRIGYGWLO text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-rKBRvJOsRIGYGWLO .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-rKBRvJOsRIGYGWLO .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-rKBRvJOsRIGYGWLO .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-rKBRvJOsRIGYGWLO .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-rKBRvJOsRIGYGWLO #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-rKBRvJOsRIGYGWLO .sequenceNumber{fill:white;}#mermaid-svg-rKBRvJOsRIGYGWLO #sequencenumber{fill:#333;}#mermaid-svg-rKBRvJOsRIGYGWLO #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-rKBRvJOsRIGYGWLO .messageText{fill:#333;stroke:none;}#mermaid-svg-rKBRvJOsRIGYGWLO .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rKBRvJOsRIGYGWLO .labelText,#mermaid-svg-rKBRvJOsRIGYGWLO .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-rKBRvJOsRIGYGWLO .loopText,#mermaid-svg-rKBRvJOsRIGYGWLO .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-rKBRvJOsRIGYGWLO .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-rKBRvJOsRIGYGWLO .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-rKBRvJOsRIGYGWLO .noteText,#mermaid-svg-rKBRvJOsRIGYGWLO .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-rKBRvJOsRIGYGWLO .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rKBRvJOsRIGYGWLO .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rKBRvJOsRIGYGWLO .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rKBRvJOsRIGYGWLO .actorPopupMenu{position:absolute;}#mermaid-svg-rKBRvJOsRIGYGWLO .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-rKBRvJOsRIGYGWLO .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rKBRvJOsRIGYGWLO .actor-man circle,#mermaid-svg-rKBRvJOsRIGYGWLO line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-rKBRvJOsRIGYGWLO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} container.NewTask(ctx, cio.NewCreator())Create(request{containerID, bundle, rootfs, terminal, stdin, stdout, stderr})Create(containerID, opts)启动/复用 shim 进程runc create --bundle <bundle>容器已创建 (PID)Task{PID, Status=created}CreateResponse{PID}Tasktask.Start(ctx)Start(request{containerID})Start(containerID)ttrpc Startrunc start <id>Status=runningStartResponse{PID}OK
4.3 Plugin 加载流程
#mermaid-svg-r2VWyozt4FMonRyH{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-r2VWyozt4FMonRyH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-r2VWyozt4FMonRyH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-r2VWyozt4FMonRyH .error-icon{fill:#552222;}#mermaid-svg-r2VWyozt4FMonRyH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-r2VWyozt4FMonRyH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-r2VWyozt4FMonRyH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-r2VWyozt4FMonRyH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-r2VWyozt4FMonRyH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-r2VWyozt4FMonRyH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-r2VWyozt4FMonRyH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-r2VWyozt4FMonRyH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-r2VWyozt4FMonRyH .marker.cross{stroke:#333333;}#mermaid-svg-r2VWyozt4FMonRyH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-r2VWyozt4FMonRyH p{margin:0;}#mermaid-svg-r2VWyozt4FMonRyH .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-r2VWyozt4FMonRyH .cluster-label text{fill:#333;}#mermaid-svg-r2VWyozt4FMonRyH .cluster-label span{color:#333;}#mermaid-svg-r2VWyozt4FMonRyH .cluster-label span p{background-color:transparent;}#mermaid-svg-r2VWyozt4FMonRyH .label text,#mermaid-svg-r2VWyozt4FMonRyH span{fill:#333;color:#333;}#mermaid-svg-r2VWyozt4FMonRyH .node rect,#mermaid-svg-r2VWyozt4FMonRyH .node circle,#mermaid-svg-r2VWyozt4FMonRyH .node ellipse,#mermaid-svg-r2VWyozt4FMonRyH .node polygon,#mermaid-svg-r2VWyozt4FMonRyH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-r2VWyozt4FMonRyH .rough-node .label text,#mermaid-svg-r2VWyozt4FMonRyH .node .label text,#mermaid-svg-r2VWyozt4FMonRyH .image-shape .label,#mermaid-svg-r2VWyozt4FMonRyH .icon-shape .label{text-anchor:middle;}#mermaid-svg-r2VWyozt4FMonRyH .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-r2VWyozt4FMonRyH .rough-node .label,#mermaid-svg-r2VWyozt4FMonRyH .node .label,#mermaid-svg-r2VWyozt4FMonRyH .image-shape .label,#mermaid-svg-r2VWyozt4FMonRyH .icon-shape .label{text-align:center;}#mermaid-svg-r2VWyozt4FMonRyH .node.clickable{cursor:pointer;}#mermaid-svg-r2VWyozt4FMonRyH .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-r2VWyozt4FMonRyH .arrowheadPath{fill:#333333;}#mermaid-svg-r2VWyozt4FMonRyH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-r2VWyozt4FMonRyH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-r2VWyozt4FMonRyH .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-r2VWyozt4FMonRyH .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-r2VWyozt4FMonRyH .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-r2VWyozt4FMonRyH .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-r2VWyozt4FMonRyH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-r2VWyozt4FMonRyH .cluster text{fill:#333;}#mermaid-svg-r2VWyozt4FMonRyH .cluster span{color:#333;}#mermaid-svg-r2VWyozt4FMonRyH div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-r2VWyozt4FMonRyH .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-r2VWyozt4FMonRyH rect.text{fill:none;stroke-width:0;}#mermaid-svg-r2VWyozt4FMonRyH .icon-shape,#mermaid-svg-r2VWyozt4FMonRyH .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-r2VWyozt4FMonRyH .icon-shape p,#mermaid-svg-r2VWyozt4FMonRyH .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-r2VWyozt4FMonRyH .icon-shape .label rect,#mermaid-svg-r2VWyozt4FMonRyH .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-r2VWyozt4FMonRyH .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-r2VWyozt4FMonRyH .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-r2VWyozt4FMonRyH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Yes + fail
No
plugin.Register()
编译时注册所有插件
registry.Graph()
拓扑排序依赖图
LoadPlugins()
V2DisabledFilter
排除 DisabledPlugins
遍历 sorted plugins
plugin.NewContext()
- initialized set
config.Decode()
插件配置
p.Init(initContext)
result.Instance()
类型断言
grpcService → Register(grpcServer)
ttrpcService → RegisterTTRPC(ttrpcServer)
tcpService → RegisterTCP(tcpServer)
required plugin?
skip/continue
返回错误
五、Plugin 体系核心类型
5.1 Plugin Type 常量
| Type | 值 | 描述 |
|---|---|---|
InternalPlugin |
io.containerd.internal.v1 |
内部插件 |
RuntimePlugin |
io.containerd.runtime.v1 |
运行时 v1 |
RuntimePluginV2 |
io.containerd.runtime.v2 |
运行时 v2 |
ServicePlugin |
io.containerd.service.v1 |
内部服务 |
GRPCPlugin |
io.containerd.grpc.v1 |
gRPC 服务 |
TTRPCPlugin |
io.containerd.ttrpc.v1 |
ttrpc 服务 |
SnapshotPlugin |
io.containerd.snapshotter.v1 |
快照驱动 |
DiffPlugin |
io.containerd.differ.v1 |
差异计算 |
MetadataPlugin |
io.containerd.metadata.v1 |
元数据 |
ContentPlugin |
io.containerd.content.v1 |
内容存储 |
GCPlugin |
io.containerd.gc.v1 |
GC 策略 |
EventPlugin |
io.containerd.event.v1 |
事件处理 |
LeasePlugin |
io.containerd.lease.v1 |
租约 |
StreamingPlugin |
io.containerd.streaming.v1 |
流管理 |
TransferPlugin |
io.containerd.transfer.v1 |
传输 |
SandboxStorePlugin |
io.containerd.sandbox.store.v1 |
沙箱存储 |
SandboxControllerPlugin |
io.containerd.sandbox.controller.v1 |
沙箱控制器 |
ShimPlugin |
io.containerd.shim.v1 |
Shim |
CRIServicePlugin |
io.containerd.cri.v1 |
CRI 服务 |
NRIApiPlugin |
io.containerd.nri.v1 |
NRI |
ImageVerifierPlugin |
io.containerd.image-verifier.v1 |
镜像验证 |
5.2 Plugin 注册结构
go
type Registration struct {
Type Type // 插件类型
ID string // 插件 ID
Config interface{} // 默认配置
Requires []Type // 依赖的插件类型
InitFn func(*InitContext) (interface{}, error) // 初始化函数
// ...
}
六、Server 结构体 --- daemon 核心
go
type Server struct {
prometheusServerMetrics *grpc_prometheus.ServerMetrics // Prometheus 指标
grpcServer *grpc.Server // gRPC 服务 (Unix socket)
ttrpcServer *ttrpc.Server // ttrpc 服务 (shim 通信)
tcpServer *grpc.Server // TCP gRPC (可选 TLS)
config *srvconfig.Config // 配置
plugins []*plugin.Plugin // 已加载插件列表
ready sync.WaitGroup // 就绪信号
}
Server 服务矩阵
| 服务 | 协议 | 监听 | 用途 |
|---|---|---|---|
| gRPC Server | gRPC | Unix socket | 客户端 API |
| ttrpc Server | ttrpc | Unix socket | Shim 通信 |
| TCP Server | gRPC+TLS | TCP | 远程访问 |
| Metrics | HTTP | TCP | Prometheus |
| Debug | HTTP | TCP | pprof/expvar |
七、gRPC Service 清单
| Service | 包 | 功能 |
|---|---|---|
Containers |
api/services/containers/v1 | 容器 CRUD |
Content |
api/services/content/v1 | 内容存储 |
Diff |
api/services/diff/v1 | 差异计算 |
Events |
api/services/events/v1 | 事件订阅 |
Images |
api/services/images/v1 | 镜像管理 |
Leases |
api/services/leases/v1 | 租约管理 |
Namespaces |
api/services/namespaces/v1 | 命名空间 |
Snapshots |
api/services/snapshots/v1 | 快照管理 |
Tasks |
api/services/tasks/v1 | 任务管理 |
Transfer |
api/services/transfer/v1 | 传输服务 |
Sandbox |
api/services/sandbox/v1 | 沙箱管理 |
Version |
api/services/version/v1 | 版本信息 |
Introspection |
api/services/introspection/v1 | 自省 |