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 内核能力的"封装与编排"。理解了这四块,再看容器的性能问题、网络不通、磁盘占用,思路会清晰很多。

相关推荐
修己xj1 天前
服务器无法解析域名?一次 DNS 配置缺失的排查与修复
运维
xbzb1 天前
自定义 yum 软件源:Linux 上 createrepo,Windows 上纯 Python 也能造
linux·运维·windows·python·yum·createrepo
Android系统攻城狮1 天前
Linux FFmpeg深度解析之avio_open调用流程与实战(三十八)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
我不会起名字3221 天前
K8s Pod 反复重启 CrashLoopBackOff:从 exit code 到根因的 5 步排查
云原生·容器·kubernetes·k8s
瑞克-桑切斯1 天前
ERP 企业生产管理系统部署手册
运维·docker·云原生·容器·eureka
江屿风1 天前
【Git-组件】【Git入门:从文档灾难到版本掌控】流食般投喂
运维·笔记·git·组件·版本控制
我不会起名字3221 天前
K8s 节点磁盘打满导致 Pod 被驱逐:4 类占用与回收顺序
运维·kubernetes·k8s·diskpressure·evicted
雪落漂泊1 天前
Linux进程(五):进程地址空间篇
linux·运维·服务器
瑞克-桑切斯1 天前
docker mail商城
运维·docker·容器
java_logo1 天前
Docker 部署 ReMe:轻松搭建 AI Agent 记忆管理平台
人工智能·docker·容器·ai agent·轩辕镜像·reme·agentscope-ai