Docker 底层知识:从 Namespace 到 UnionFS

很多人用 Docker 时觉得它很"轻量",但轻量背后其实是一套扎实的 Linux 内核机制。理解这些底层知识,能帮你更好地排查容器问题、设计镜像和规划资源。

文章目录

一、容器不是虚拟机

虚拟机靠 Hypervisor 模拟硬件,每个 VM 有独立内核;而容器直接共享宿主机内核,只是通过内核提供的隔离能力"伪装"成独立系统。所以容器启动快、开销小,但也意味着容器内的内核版本必须和宿主机兼容。

Docker 的底层依赖主要有四块:Namespace、Cgroups、UnionFS 和网络虚拟化。

二、Namespace:隔离"看到什么"

Namespace 是 Linux 内核提供的资源隔离机制。Docker 启动容器时,会为进程创建一组新的 Namespace,让进程只能看到自己 Namespace 内的资源。

常见的几种:

  • PID Namespace:容器内进程 PID 从 1 开始,看不到宿主机其他进程
  • Mount Namespace:容器有独立的挂载点视图,根目录由镜像提供
  • Network Namespace:独立的网卡、IP、端口、路由表
  • UTS Namespace:独立的主机名和域名
  • IPC Namespace:独立的信号量、消息队列
  • User Namespace:用户和用户组映射,可实现 root 权限隔离

举个例子,容器里执行 ps aux 只看到几个进程,就是 PID Namespace 在起作用。

三、Cgroups:限制"能用多少"

Namespace 解决"看得见看不见",Cgroups(Control Groups)解决"能用多少"。它负责对 CPU、内存、磁盘 I/O、网络带宽等资源做限制和统计。

Docker 运行时的 --cpus、--memory、--blkio-weight 等参数,最终都是写到 Cgroups 的对应子系统里。比如:

bash 复制代码
docker run -m 512m --cpus=1.5 nginx

本质是在 /sys/fs/cgroup/ 下为这个容器创建一组限制文件。如果容器被 OOM Kill,往往就是 memory cgroup 触发了限制。

四、UnionFS:镜像分层的秘密

Docker 镜像最迷人的地方是"分层复用",靠的是联合文件系统(UnionFS),常见实现有 OverlayFS、AUFS、devicemapper 等。

核心思想:

  • 镜像由多个只读层叠加而成,每层是一次构建的变更
  • 容器启动时,在最上面加一个可写层
  • 读文件时从上层往下找,写文件时用 Copy-on-Write:把文件从只读层复制到可写层再修改

这带来几个直接结果:

  1. 镜像层可共享:多个容器用同一镜像,只读层在磁盘上只有一份
  2. 容器删除后数据丢失:可写层随容器销毁,所以要用 Volume 持久化
  3. 构建要合并指令 :Dockerfile 里多条 RUN 会生成多层,层数越多镜像越大,所以常把命令用 && 合并

五、网络:靠虚拟设备串联

Docker 默认的 bridge 网络,底层是 Linux 的 veth pair 和 网桥:

  • 每个容器有一对 veth 设备,一端在容器 Network Namespace 内(如 eth0),另一端挂在宿主机的 docker0 网桥上
  • 容器间通信通过网桥二层转发
  • 访问外网靠 iptables 的 NAT 规则做源地址转换
  • 端口映射 -p 8080:80 本质是一条 DNAT 规则

六、一次 docker run 发生了什么

把上面串起来:

  1. Docker Daemon 收到请求,准备镜像层
  2. 创建 Namespace(PID、Mount、Network 等)
  3. 创建 Cgroups 并写入资源限制
  4. 用 OverlayFS 挂载镜像层 + 可写层作为容器根文件系统
  5. 创建 veth pair,接入网桥,配置 IP 和 iptables
  6. 启动容器内 1 号进程,执行 entrypoint

小结

机制 作用
Namespace 隔离资源视图
Cgroups 限制资源用量
UnionFS 镜像分层与写时复制
veth + 网桥 容器网络通信

Docker 本身并不神秘,它更像是对 Linux 内核能力的"封装与编排"。理解了这四块,再看容器的性能问题、网络不通、磁盘占用,思路会清晰很多。

相关推荐
_smart_boy__1 小时前
I.MX6U开发板Uboot无法ping Ubuntu问题解决方案(二)
linux·运维·ubuntu
~光~~2 小时前
【嵌入式Linux学习】GFP_NOIO / GFP_NOFS(Linux 内核 gfp 分配标志)
linux·运维·学习
涵美女程序猿2 小时前
ChatCut online 剪负载均衡健康检查演练录屏:后端池、探针路径与摘除阈值怎样对应
运维·程序人生·电脑·负载均衡
分布式存储与RustFS2 小时前
升级 RustFS 二进制不停机:一条一条换,留一条退路
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
吴声子夜歌2 小时前
Nginx应用与运维——Nginx核心配置指令(一)
运维·nginx
android阿杜2 小时前
Ubuntu 26.04 LTS 系统每次重启后屏幕亮度都会增加一点
linux·运维·ubuntu
路溪非溪4 小时前
Linux下Shell脚本基础知识(二)
linux·运维·服务器
fruge4 小时前
飞牛OS部署Flare导航页:Docker Compose、YAML书签配置与cpolar公网访问
运维·docker·容器
NailiConveyor4 小时前
输送机皮带材质选型指南:PVC、PU、橡胶、模块化塑料各适用什么场景?
大数据·运维·自动化·制造·业界资讯·材质