Docker 底层知识:从 Namespace 到 UnionFS
很多人用 Docker 时觉得它很轻量但轻量背后其实是一套扎实的 Linux 内核机制。理解这些底层知识能帮你更好地排查容器问题、设计镜像和规划资源。文章目录一、容器不是虚拟机二、Namespace隔离看到什么三、Cgroups限制能用多少四、UnionFS镜像分层的秘密五、网络靠虚拟设备串联六、一次 docker run 发生了什么小结一、容器不是虚拟机虚拟机靠 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 解决看得见看不见CgroupsControl Groups解决能用多少。它负责对 CPU、内存、磁盘 I/O、网络带宽等资源做限制和统计。Docker 运行时的--cpus、--memory、--blkio-weight等参数最终都是写到 Cgroups 的对应子系统里。比如dockerrun-m512m--cpus1.5nginx本质是在/sys/fs/cgroup/下为这个容器创建一组限制文件。如果容器被 OOM Kill往往就是 memory cgroup 触发了限制。四、UnionFS镜像分层的秘密Docker 镜像最迷人的地方是分层复用靠的是联合文件系统UnionFS常见实现有 OverlayFS、AUFS、devicemapper 等。核心思想镜像由多个只读层叠加而成每层是一次构建的变更容器启动时在最上面加一个可写层读文件时从上层往下找写文件时用Copy-on-Write把文件从只读层复制到可写层再修改这带来几个直接结果镜像层可共享多个容器用同一镜像只读层在磁盘上只有一份容器删除后数据丢失可写层随容器销毁所以要用 Volume 持久化构建要合并指令Dockerfile 里多条RUN会生成多层层数越多镜像越大所以常把命令用合并五、网络靠虚拟设备串联Docker 默认的 bridge 网络底层是 Linux 的veth pair和网桥每个容器有一对 veth 设备一端在容器 Network Namespace 内如 eth0另一端挂在宿主机的docker0网桥上容器间通信通过网桥二层转发访问外网靠 iptables 的 NAT 规则做源地址转换端口映射-p 8080:80本质是一条 DNAT 规则六、一次docker run发生了什么把上面串起来Docker Daemon 收到请求准备镜像层创建 NamespacePID、Mount、Network 等创建 Cgroups 并写入资源限制用 OverlayFS 挂载镜像层 可写层作为容器根文件系统创建 veth pair接入网桥配置 IP 和 iptables启动容器内 1 号进程执行 entrypoint小结机制作用Namespace隔离资源视图Cgroups限制资源用量UnionFS镜像分层与写时复制veth 网桥容器网络通信Docker 本身并不神秘它更像是对 Linux 内核能力的封装与编排。理解了这四块再看容器的性能问题、网络不通、磁盘占用思路会清晰很多。