整体架构图如下:
- 使用
github.com/urfave/cli
启动,有 command- configCommand: 和 containerd 配置相关
- publishCommand:event 相关
- ociHook: 提供了 preStart, preStop 等 container hook
- 未执行子 command,则执行默认的 action
- 加载配置文件
- 创建顶层文件夹:
- root = “/var/lib/containerd”
- state = “/run/containerd”
- 创建 /var/lib/containerd/tmpmounts
- 清理 tmpmounts 下的临时挂载点
- 创建和初始化 containerd server
- 将配置设置的 server 进程上
- 如果设置了 OOMScore,则应用到进程上。OOMScore 越低,系统内存不足时越不会被 kill
- 如果设置了 containerd 的 Cgroup path。则会将自己的进程加入到 cgroup 下。这里还会判断使用 cgroup v1 还是 v2。
- 设置一系列超时参数
- 加载 plugin,containerd 通过 plugin 来划分模块。
- 通过设置的 plugin 目录(默认在 /var/lib/containerd/plugins)来加载。go1.8 之后就不支持了。
- 注册 content plugin:containred 架构中 storage 部分的 content。负责镜像的存储
- 注册 metadata plugin:使用的是 bolt 这个嵌入式的 key/value 数据库。依赖 content 和 snapshot plugin。
- 注册 proxy plugin: proxy plugin 支持 content, snapshot 两种类型。相当于起了一个 GRPC 服务,替换掉内置的 content, snapshot plugin。
- 还有很多 plugin 是在包的 init 方法中注册的
- 大量 snapshot 的插件: aufs, btrfs, devmapper, native, overlayfs, zfs
- diff 插件: walking
- GC 插件
- 大量 service 插件:introspection,containers,content,diff,images,leases,namespaces,snapshots,tasks
- runtime 插件:linux,task
- monitoring 插件:cgroups
- internal 插件:restart,opt
- GRPC 插件:containers,content,diff,events,healthcheck,images,leases,namespaces,snapshots,tasks,version,introspection
- CRI 插件:实现 CRI,提供给 kubelet 调用
- diff 模块注册 stream processor,支持两种
- application/vnd.oci.image.layer.v1.tar+encrypted
- application/vnd.oci.image.layer.v1.tar+gzip+encrypted
- 启动 TTRPC server:/run/containerd/containerd.sock.ttrpc
- 启动 GRPC server:/run/containerd/containerd.sock
- 如果开启了 TCP,还会将 GRPC server 监听到 tcp 上。
此时,containerd 已经可以对外提供服务了。下面对上述提到的一些概念或模块做个简单的解释:
- service: GRPC 服务依赖于对应的 service。service 是则用来封装内部的实现。
- TTRPC: TTRPC 是为低内存环境做的优化,通过淘汰
net/http
,net/http2
和grpc
包,实现了更轻量的 framing protocol,实现了更小的二进制文件以及更少的常驻内存使用。 - storage 模块:包含 content, snapshot 和 diff 三个子模块。
- content: content 是负责整个镜像的存储流程的。
- snapshot:为了保证镜像层的数据不可变,所以在运行容器时会从 layer 中创建 snapshot。
- diff:diff 模块实现了两个功能: diff 和 apply。diff 用来比较上层和下层之间的差异,然后按照 OCI 规范对该层打包。apply 用来根据底层的联合文件系统,对某一层进行挂载。
- metadata 模块: 包含 images 和 containers 两个子模板。
- images: 存储镜像相关的元数据。
- containers: 存储容器相关的元数据。
- tasks 模块:一个 container 的运行被抽象成一个 task
- event 模块:提供了事件的发布订阅功能。第三方可以通过 event 获取 containerd 中的事件,比如镜像的创建,更新,容器的创建,删除等等。