土法炼钢兴趣小组的算法知识备份

从零造容器系列文章

目录

从零造容器

容器不是魔法,它是一堆 Linux 内核特性的组合拳:namespace 做隔离、cgroup 做资源限制、overlayfs 做文件系统分层。本系列用 C 和 Go 从零实现一个能跑的容器运行时,每篇拆解一个内核机制,最终组装成 OCI 兼容的迷你运行时。

为什么要自己造? Docker/containerd/runc 加起来几十万行代码,但核心机制其实就那么几个系统调用。造一遍,你就再也不会觉得容器是黑盒了。

适合谁看

本系列假设你熟悉 Linux 基础(进程、文件系统、网络),能读 C 和 Go 代码。如果你用过 Docker 但不知道它底层在干什么,这个系列就是为你写的。

推荐阅读顺序: - 只想懂容器本质 → 01(namespace)→ 03(rootfs)→ 04(cgroup)→ 05(overlay) - 想自己写 runtime → 按顺序 01-07 - 关注安全 → 先看 01,然后跳到 08(seccomp)→ 09(rootless) - 想做性能优化 → 先看 02(网络基础),再看 11(性能实测)→ 10(microVM 对比)

目录

第一阶段:内核积木

用 C 逐个拆解容器依赖的内核机制。每篇一个系统调用家族,附可编译的示例代码。

  1. Linux Namespaces:用 50 行 C 隔离一个进程
    • clone() + CLONE_NEWPID / CLONE_NEWUTS / CLONE_NEWNS
    • PID 1 在容器里的特殊角色
  2. Network Namespace:给你的进程接上虚拟网线
    • veth pair + bridge + NAT
    • 用 tcpdump 验证数据流向
  3. Mount Namespace 与 pivot_root:构建容器文件系统
    • chroot 的安全缺陷 vs pivot_root
    • 手工组装 Alpine minirootfs
  4. Cgroups v2:让容器不能吃掉整台机器
    • CPU / Memory / IO 资源限制
    • OOM killer 行为与 CFS bandwidth 尾延迟

第二阶段:存储与组装

有了内核积木,现在用 Go 把它们拼成一个真正能跑的运行时。

  1. OverlayFS:一层一层像洋葱
    • copy-on-write 的实际性能代价
    • 手工构建分层”镜像”
  2. 用 Go 组装迷你容器运行时:把积木拼起来
    • 容器生命周期:create → start → exec → kill → delete
    • init 进程与 reexec 技巧
  3. OCI 规范兼容:让迷你运行时说标准语言
    • OCI Runtime Spec 关键字段拆解
    • 用 ctr 调用自己的运行时

第三阶段:安全加固

容器能跑了,但还不安全。这一阶段给容器加上”不能做什么”的约束。

  1. Seccomp-BPF 与 Capabilities:容器安全的两道防线
    • seccomp 过滤器编写与 capability 裁剪
    • Docker 默认 seccomp profile 拆解
  2. User Namespace 与 Rootless 容器:不需要 root 也能跑
    • UID/GID 映射与 rootless 限制
    • Podman rootless 实现分析

第四阶段:性能与对比

跳出容器看全局:和 microVM 比安全性,用数据说话看网络性能,最后回到 runc 源码看工业级实现。

  1. 容器 vs microVM:Firecracker 凭什么 125ms 启动
    • KVM API 最小化实现
    • 启动时间与资源开销拆解
  2. 容器网络性能真相:veth vs macvlan vs eBPF 数据面
    • 各网络方案多维度实测
    • Cilium eBPF 替代 iptables 的收益
  3. runc 源码考古:OCI 参考实现到底长什么样
    • libcontainer 核心流程
    • 对比迷你运行时与 runc 的差距

相关阅读

本系列与博客其他文章形成交叉引用网络,按主题分组:

内核机制 - eBPF:Linux 内核的隐藏武器 — Seccomp-BPF 与 eBPF 同源 - eBPF + io_uring:高性能网络栈的终极形态 — 容器网络的 eBPF 数据面 - io_uring 系列 — 容器/VM 中的 I/O 路径差异

Go Runtime - Go 调度器深度拆解 — Go runtime fork 的陷阱

性能优化 - 内存分配器擂台 — Cgroups 下分配器行为变化


By .