ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

从 2017 年 3 月开发报告看 containerd:进程 Reaper、快照器动态注册与 OCI 合规之路

从 2017 年 3 月开发报告看 containerd:进程 Reaper、快照器动态注册与 OCI 合规之路 从 2017 年 3 月开发报告看 containerd进程 Reaper、快照器动态注册与 OCI 合规之路【免费下载链接】containerdAn open and reliable container runtime项目地址: https://gitcode.com/GitHub_Trending/co/containerd2017 年 3 月 10 日发布的这份 containerd 开发周报docs/historical/reports/2017-03-10.md记录了 containerd 在 1.0 发布前夕围绕 OCI 运行时规范、进程回收Reaper、快照器动态注册等核心方向的关键进展。本文将完整还原这份报告的技术内容并结合当前仓库源码追溯这些设计决策的最终形态pkg/sys/reaper中的全局进程收割器、cmd/containerd/builtins中的插件注册模式以及快照器生态的扩张路径。读完本文你可以理解 containerd 进程生命周期管理的底层机制、插件式扩展的编译期注册原理以及一条从 2017 到今日的架构演进脉络。报告背景1.0 前夕的 containerd这份报告发布于 containerd 从 Docker 项目中剥离、走向独立项目的关键时期。报告明确给出了两条时间线目标4 月中旬达到 feature complete功能完备状态Q2 发布 1.0 版本对应 GitHub 上的 Beta 里程碑。在功能完备之后团队计划完成 Docker、Swarm 与 Kubernetes CRI 的集成验证确保各生态所需的特性集齐备后再冻结 API。这一点解释了为何报告中反复强调为 OCI 规范打基础和通过 API 串联 distribution、content、snapshotters——这些正是 1.0 稳定 API 的基石。一、OCI 运行时规范与 runc为 1.0 打地基报告第一项进展围绕 OCIOpen Container Initiative运行时规范。当时 containerd 的目标是完全兼容 OCI 规范因此需要推动规范本身达到 1.0以获得稳固的底层基础。报告提到 OCI 规范侧已接近完成并发布了最终 RCRelease Candidate供社区评审。在runc侧作者crosbymichael主要做了两件事修复exec的终端terminal处理在 Go 绑定go bindings中落地相应改动。从当前仓库可以印证这条技术路线runc 的 Go 绑定如今由独立的 github.com/containerd/go-runc 与pkg/sys/reaper均依赖它。例如 reaper 中的runc.Exit事件类型就来自 go-runc 库见 pkg/sys/reaper/reaper_unix.go这说明runc 绑定 → containerd 核心的依赖关系从 2017 年延续至今。二、全局进程 Reaper终结 SIGCHLD 与 exec.Cmd 的竞态报告用较大篇幅介绍了**全局进程监视/回收器global process monitor/reaper**的设计动机这是当时最具技术深度的部分值得展开。2.1 要解决的问题容器场景下containerd 及其 shim 进程会被系统当作孤儿进程的新父亲——容器内进程退出后会被 reparent 到 containerd 或 shim 上。进程退出时内核会向父进程发送SIGCHLD父进程必须调用waitpid系列调用回收reap这些僵尸进程否则会积累僵尸进程。报告的难点陈述非常具体Go 的exec.Cmd及其Wait方法与自建的SIGCHLDreaper 之间存在竞态——reaper 执行waitpid与exec.Cmd执行Wait可能同时收割同一个子进程导致状态错乱。报告的结论是只要所有代码都基于reaperAPI 编写这个问题就能被彻底解决代价是 containerd 开发者需要遵循统一的回收入口但换来的是进程被 reparent 到 containerd 与其 shim 时的系统健壮性。2.2 今日源码中的 reaper 实现这一设计在今天的仓库中落地为 pkg/sys/reaper 包Unix 实现见 reaper_unix.go核心结构包括Monitor与订阅者subscriber机制Monitor内部维护一张subscribers映射map[chan runc.Exit]*subscriber任何模块都可以通过Subscribe()注册一个容量为 32 的退出事件通道bufferSize 32并在结束用Unsubscribe()注销。这避免了所有调用方直接竞争waitpid。Start/StartLockedStart(c *exec.Cmd)先订阅退出事件通道再启动命令把进程纳入 reaper 管辖StartLocked额外使用runtime.LockOSThread()锁定 OS 线程用于对线程亲和性有要求的场景见 reaper_unix.go。Wait/WaitTimeoutWait从事件通道中匹配e.Pid c.Process.Pid的退出事件随后调用c.Wait()冲刷 IO 并返回退出状态WaitTimeout则在超时后对目标进程执行SIGKILL并返回超时错误避免调用方无限期阻塞见 reaper_unix.go。Reap()与底层wait4收到SIGCHLD时调用Reap()内部通过unix.Wait4(-1, ws, unix.WNOHANG, rus)以非阻塞方式循环收割所有已退出子进程将(Pid, Status)打包为runc.Exit事件广播给所有订阅者见 reaper_unix.go。退出码规范化exitStatus对被信号终止的进程返回128 signalexitSignalOffset 128对正常退出返回ExitStatus()确保上层拿到统一语义的退出码见 reaper_unix.go。2.3 shim 中的子收割器报告提到进程被 reparent 到 containerd 及其 shim这在当前 shim 代码中有直接体现。pkg/shim/shim_unix.go 的注释明确写道setupSignals会将 shim 设置为sub-reaper子收割器使容器进程在退出后被 reparent 到 shim 名下。其信号处理逻辑为默认监听SIGTERM、SIGINT、SIGPIPE若配置未设置NoReaper额外追加SIGCHLD主循环reap()收到SIGCHLD后调用reaper.Reap()回收僵尸进程并派发退出事件见 shim_unix.go。这套信号订阅 统一 Reap 事件广播的架构正是报告中所说写代码时必须基于 reaper API的落地形态——所有进程的回收都收敛到pkg/sys/reaper单一实现从机制上排除了多个waitpid调用方互相竞争的可能。三、快照器动态注册与 builtins.go 模式报告记录的第三项进展是合并了让快照器snapshotter注册变为动态的 PR允许用户在 containerd 核心内置的快照器之外编译时加入额外的快照器。3.1 2017 年的注册示例报告指出受当时 Go 1.8 插件plugin机制不成熟限制添加新运行时、快照器及其他扩展的最佳方式是修改 containerd 命令的builtins.go并重新编译。报告附带的原始代码示例如下package main // register containerd builtins here import ( _ github.com/containerd/containerd/linux _ github.com/containerd/containerd/services/content _ github.com/containerd/containerd/services/execution _ github.com/containerd/containerd/snapshot/btrfs _ github.com/containerd/containerd/snapshot/overlay )这段代码的核心机制是Go 的空导入blank import通过import _ ...触发包内init()函数的副作用使快照器在init()阶段完成向全局注册表的自注册。彼时内置的linux运行时、content/execution服务以及btrfs/overlay两个快照器构成了 containerd 的最小功能集。3.2 今日的 builtins 结构这一改 builtins.go 重新编译的模式在今天演化为一个独立包 cmd/containerd/builtins。其职责更清晰分平台组织builtins.go通用注册清单涵盖core/runtime/v2运行时、content/metadata/gc/leases/nri/restart/sandbox等核心插件以及services下的 containers、content、diff、events、images、introspection、leases、mounts、namespaces、sandbox、snapshots、streaming、tasks、transfer、version 等全部 gRPC/ttrpc 服务builtins_linux.goLinux 平台专属注册如runc选项类型、cgroups 指标v1/v2、erofs 相关插件、snapshots/native与snapshots/overlay另有btrfs_linux.go、zfs_linux.go、devmapper_linux.go、cri.go等按平台/功能拆分的注册文件。对比可见报告时代一个扁平文件 5 个导入的形态如今变成了按平台、按功能分组的 builtins 包 数十个插件注册但编译期空导入自注册的核心机制一脉相承。这正是 containerd 插件架构plugins 目录、core/runtime/v2 运行时插件模型的基础。3.3 快照器生态的扩展动态注册的成果直接体现在快照器目录的扩张上。当前仓库 plugins/snapshots 下已包含 8 个快照器blockfile、btrfs、devmapper、erofs、lcow、native、overlay、windows远超 2017 年的 btrfs 与 overlay 两个。以 plugins/snapshots/overlay/plugin/plugin.go 为例可以看到注册已高度参数化插件通过plugin.Registration声明类型SnapshotPlugin与 IDoverlayfs并暴露root_path、upperdir_label、sync_remove、slow_chown、mount_options等 TOML 配置项见 plugin.go初始化时还会根据内核能力如是否支持 idmap 挂载动态追加remap-ids、only-remap-ids、rebase等能力声明见 plugin.go。这正是动态注册从简单导入升级为能力自描述、按需启用的现代形态。四、里程碑时间表feature complete 与 Q2 1.0报告原样记录了当时的排期承诺4 月中旬达到 feature completeQ2发布 1.0功能完备后依次完成Docker、Swarm、Kube CRI三类集成确保满足各自需求的功能集随后冻结 API。这份排期体现了 containerd 早期以生态集成为验收标准、以 API 稳定为交付底线的工程策略。从今日仓库看CRI 集成已成为 containerd 的核心能力之一见 internal/cri 与 plugins/cri而 API 冻结的承诺则体现在 api 目录下以 protobuf 定义并版本化的服务接口中——这些都可以视为 2017 年先集成验证、后冻结 API路线的延续成果。需要说明的是报告所述日期为 2017 年的历史计划实际发布节奏以 containerd 官方 release 记录为准。五、Containerd Summit用预先议题提升研讨效率报告还预告了 Dockercon 期间的第二次 containerd summit。作者在仓库中创建了一份文档用于收集分组讨论breakout session的议题理由很实际参会规模预计远超上一届预先定义若干讨论点有助于讨论聚焦当然临场自由讨论仍然保留有准备总不会错。这一节虽无代码内容但记录了 containerd 社区运营模式的早期实践——用公开文档沉淀讨论议题让社区协作过程可追溯、可参与与当前仓库中 ADOPTERS.md、ROADMAP.md、RELEASES.md 等治理文档一脉相承。六、Nextdistribution、content、snapshot 在 API 上的整合报告末尾点明了下一步的技术攻坚方向让 distribution、content 与 snapshotter 通过统一 API 协同工作其中最大的挑战是在 gRPC 上跑好——报告特别举了docker build的例子要求性能达到甚至超过用户预期。这条主线在今天的架构中清晰可辨content 层见 core/content含adaptor.go、content.go、helpers.go等与 plugins/contentsnapshot 层见 core/snapshots 与 plugins/snapshotsdistribution/remotes 层见 core/remotes/docker36 个文件的 docker 远程仓库实现API 暴露content、snapshots、images、tasks 等服务均通过 api/services 下的 protobuf 定义以 gRPC/ttrpc 对外提供对应服务端实现集中在 plugins/services。报告担忧的gRPC 上的大流量数据通路如镜像拉取、内容读写也在后续演进中通过流式streaming见 core/streaming与传输transfer见 core/transfer等机制得到系统性解决。今天的 docs/transfer.md 与 docs/content-flow.md 即是对这条链路的完整说明可作为延伸阅读。结语一份周报里的架构基因回看这份 2017 年 3 月的开发周报containerd 1.0 前夜的三个关键决策——面向 OCI 规范做运行时合规、用统一 Reaper API 解决进程回收竞态、以空导入实现快照器动态注册——都在今天的仓库中留下了清晰而持久的印记pkg/sys/reaper的订阅者模型、cmd/containerd/builtins的分平台注册、plugins/snapshots的八类快照器生态以及 content/snapshot/distribution 通过 gRPC 服务协同的架构主线。对于想深入理解 containerd 进程管理与插件机制的读者沿着本文给出的源码路径逐一阅读会是一份与历史设计意图直接对话的绝佳素材。【免费下载链接】containerdAn open and reliable container runtime项目地址: https://gitcode.com/GitHub_Trending/co/containerd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表