ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

从bocker学懂Linux容器本质:命名空间与cgroups从零到一完全指南

从bocker学懂Linux容器本质:命名空间与cgroups从零到一完全指南 从bocker学懂Linux容器本质命名空间与cgroups从零到一完全指南【免费下载链接】bockerDocker implemented in around 100 lines of bash项目地址: https://gitcode.com/gh_mirrors/bo/bockerbocker 是一个仅用约 100 行 bash 脚本就实现 Docker 核心能力镜像拉取、容器运行、日志、提交的极简项目。它把 Docker 的黑盒拆开给你看Linux 容器的全部本质就是命名空间namespaces负责看不见邻居cgroups 负责用不完资源再加一个 chroot 提供的独立文件系统。读懂这一个脚本你就真正懂了容器原理。为什么100行脚本能写出Docker很多人以为 Docker 很神秘其实它站在三个 Linux 内核特性之上内核特性作用bocker 中对应代码命名空间隔离进程、网络、PID、挂载视图unshare -fmuipcgroups限制 CPU、内存等资源cgcreate/cgset/cgexec根文件系统切换让容器活在自己的目录里chrootDocker 做了引擎、镜像仓库、网络插件等大量工程工作而 bocker 只用 bocker 一个脚本就把跑一个隔离容器的最小闭环完整走了一遍——这正是学习容器原理的最佳路径。快速准备一键搭好实验环境bocker 需要 root 权限、btrfs 文件系统和一块叫bridge0的网桥。作者贴心地提供了 Vagrantfile克隆仓库后执行vagrant up即可自动完成全部配置git clone https://gitcode.com/gh_mirrors/bo/bocker cd bocker vagrant upVagrantfile 中的关键动作值得留意创建 btrfs 卷挂载到/var/bocker存放镜像与容器快照、开启 IP 转发、用 iptables 给网桥做 MASQUERADE 出网、创建bridge0IP 为10.0.0.1/24。这些正是 README.md Prerequisites 一节列出的前置条件。⚠️ bocker 以 root 运行且会改动网络接口与防火墙规则官方建议务必在虚拟机中折腾别在主力机上直接跑。命名空间实操bocker run 的隔离魔法运行容器的核心逻辑在 bocker 的bocker_run函数里。最精华的是这一段隔离链bockercgexec -g cpu,cpuacct,memory:$uuid \ ip netns exec netns_$uuid \ unshare -fmuip --mount-proc \ chroot $btrfs_path/$uuid \ /bin/sh -c /bin/mount -t proc proc /proc $cmd一条命令链层层递进我们逐个拆解。H3-拆解 unshare -fmuip五种命名空间一次到位unshare的每个字母对应一种命名空间这是容器隔离的全部家底uuser独立用户视图mmount独立挂载表容器内挂载不影响宿主机ppid独立 PID 空间——容器里的进程自认为是 1 号进程iipc独立进程间通信资源ffork立即 fork 子进程进入新空间因为已有进程无法迁入命名空间-nnetwork独立网络栈bocker 用ip netns exec预建好网络空间后再接管--mount-proc会自动为新 PID 空间挂一个专属 /proc让容器内看到的进程列表只有自己一家人——这就是隔离最直观的体验。H3-网络命名空间veth 对 网桥容器如何上网网络部分在 bocker为每个容器创建一对 veth 虚拟网卡一头挂到宿主机网桥bridge0另一头塞进容器的网络命名空间netns_xxx然后容器内配置 IP10.0.0.x/24、默认网关指向10.0.0.1。再叠加 iptables 的 MASQUERADE容器流量经网桥做地址转换直达外网——这套veth bridge NAT正是 Docker 默认 bridge 网络的原型。tests/test_run 里ping 8.8.8.8与 DNS 解析两条断言验证的就是这条通路。cgroups实操给容器套上资源枷锁隔离解决看不见限流解决抢不过。cgroups 部分在 bockercgcreate创建 cgroup 组cpu、cpuacct、memory 三层同时cgset写入cpu.sharesCPU 权重与memory.limit_in_bytes内存上限cgexec让容器进程带着这些限制启动默认 CPU 权重 512、内存上限 512MB可用环境变量临时调整。在容器内cat /proc/1/cgroup你会看到自己挂在memory:/ps_xxx、cpu,cpuacct:/ps_xxx下宿主机上cat /sys/fs/cgroup/memory/ps_xxx/memory.limit_in_bytes则直接读到字节数。这正是docker run --cpus --memory背后的全部真相。✅镜像、快照与提交分层存储的最简实现bocker 的镜像不是 tar 包而是btrfs 子卷bocker init / 拉取镜像→ 创建一个img_xxx子卷bocker run→ 用btrfs subvolume snapshot秒级复制出ps_xxx容器卷写时复制几乎零开销bocker commit→ 把容器子卷再快照回镜像见 bocker容器镜像的快照——一句话点破 Docker 镜像分层的思想内核。想系统验证所有命令行为运行仓库自带测试入口 test 即可它会依次跑 tests/test_run、tests/test_pull、tests/test_exec 等用例。常见疑问快答容器和虚拟机有什么区别虚拟机隔离的是硬件靠 Hypervisor容器隔离的是操作系统视图靠内核命名空间cgroups所以容器启动是毫秒级、开销极小但也共享同一个内核。怎么进入运行中的容器看 bocker 的bocker_execnsenter -t pid -m -u -i -n -p以目标进程的五个命名空间身份进入——nsenter与unshare是一对姐妹工具一个用于进入一个用于创建。为什么 PID 1 很特别新 PID 命名空间中的第一个进程会成为 init 角色不产生僵尸进程bocker 中容器主进程就是 1 号进程tests/test_run 用cat /proc/self/stat断言了这一点。动手清单从零到一验证你的容器知识按顺序执行并观察输出你就完成了容器原理的闭环vagrant up起环境 →bocker pull centos 7拉镜像bocker run img_xxx uname跑一个容器再在容器内cat /proc/1/cgroup在宿主机ls /sys/fs/cgroup/memory/找到容器组读取memory.limit_in_bytesip link show观察 veth 对ip netns list观察命名空间BOCKER_CPU_SHARE1024 BOCKER_MEM_LIMIT1024 bocker run ...验证资源参数生效跑通这 5 步再看 Docker 源码或文档时你会发现所谓容器引擎不过是把 unshare、cgroups、chroot、快照这些内核能力编排得优雅些而已。【免费下载链接】bockerDocker implemented in around 100 lines of bash项目地址: https://gitcode.com/gh_mirrors/bo/bocker创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进