Docker 容器如何实现隔离
Docker 容器通过 Linux 内核的多种技术实现隔离,主要包括 Namespace(命名空间)、Cgroups(控制组) 和 联合文件系统。以下是详细原理:
1. Linux Namespace(命名空间) - 核心隔离机制
Namespace 是 Linux 内核提供的资源隔离技术,Docker 使用 6 种命名空间实现不同维度的隔离:
(1) PID Namespace(进程隔离)
# 宿主机查看所有进程
ps aux# 容器内只能看到容器自己的进程
docker run -it alpine ps aux
原理:
每个容器有独立的进程 ID 编号体系
容器内的 PID 1 进程在宿主机上可能是 PID 1000
容器无法看到或影响宿主机和其他容器的进程
(2) Network Namespace(网络隔离)
# 宿主机网络接口
ip addr show# 容器内网络接口(完全独立)
docker run -it alpine ip addr show
原理:
每个容器有独立的网络栈(网卡、IP、路由表、端口)
容器间网络通过虚拟网桥(docker0)通信
支持端口映射:容器端口 ↔ 宿主机端口
(3) Mount Namespace(文件系统隔离)
# 容器有独立的文件系统视图
docker run -it alpine ls /
# 输出:bin dev etc home lib ...(容器内文件系统)# 宿主机文件系统不受影响
ls / # 宿主机自己的文件系统
原理:
每个容器有独立的文件系统挂载点
基于联合文件系统(OverlayFS)实现分层存储
(4) UTS Namespace(主机名隔离)
# 容器可以有自己的主机名
docker run -it --hostname mycontainer alpine hostname
# 输出:mycontainer(不影响宿主机主机名)
原理:
每个容器可以设置独立的主机名和域名
(5) IPC Namespace(进程间通信隔离)
# 容器间共享内存、信号量、消息队列隔离
docker run -it alpine ipcs # 只能看到容器内的 IPC 资源
原理:
隔离 System V IPC 和 POSIX 消息队列
(6) User Namespace(用户隔离)
# 容器内用户映射到宿主机非特权用户
docker run -it alpine whoami # 显示 root
# 实际在宿主机上以普通用户运行
原理:
容器内 root 用户映射到宿主机非 root 用户
增强安全性,防止容器逃逸
2. Cgroups(控制组) - 资源限制
Cgroups 限制容器对硬件资源的使用:
(1) CPU 限制
# 限制容器最多使用 50% 的 CPU
docker run -it --cpus="0.5" ubuntu# 或使用 CPU 份额(相对权重)
docker run -it --cpu-shares=512 ubuntu
(2) 内存限制
# 限制容器内存使用为 100MB
docker run -it --memory=100m ubuntu# 限制内存 + 交换分区
docker run -it --memory=100m --memory-swap=200m ubuntu
(3) 磁盘 I/O 限制
# 限制磁盘读写速率
docker run -it \--device-read-bps /dev/sda:1mb \--device-write-bps /dev/sda:1mb \ubuntu
(4) Cgroups 子系统
子系统 | 功能 | Docker 参数示例 |
---|---|---|
cpu | CPU 时间分配 |
|
memory | 内存使用限制 |
|
blkio | 块设备 I/O 限制 |
|
devices | 设备访问控制 |
|
pids | 进程数限制 |
|
3. 联合文件系统(UnionFS) - 存储隔离
Docker 使用联合文件系统实现镜像分层和容器可写层:
(1) OverlayFS 工作原理
容器层(可写)↓
联合视图(容器看到的文件系统)↓
镜像层(只读)← 镜像层(只读)← 基础镜像
(2) 写时复制(Copy-on-Write)
# 多个容器共享同一个镜像,只有修改时才复制
docker run -it ubuntu # 容器1
docker run -it ubuntu # 容器2 - 共享基础镜像层
4. 安全隔离机制
(1) Capabilities(能力机制)
# 默认删除危险的能力,如 CAP_SYS_ADMIN
docker run -it --cap-drop=ALL --cap-add=NET_BIND_SERVICE ubuntu
(2) Seccomp(系统调用过滤)
# 使用自定义 seccomp 配置文件
docker run -it --security-opt seccomp=profile.json ubuntu
(3) AppArmor/SELinux
# 使用 AppArmor 配置文件
docker run -it --security-opt apparmor=docker-default ubuntu
5. 实际隔离效果演示
进程树视图
宿主机进程树:
systemd(1)─┬─dockerd(1000)─┬─docker-containerd(1001)─┬─nginx(1002) # 容器1│ │ └─redis(1003) # 容器2└─bash(500) # 宿主机shell容器1内进程树:
nginx(1)─┬─nginx(10)└─nginx(11)容器2内进程树:
redis(1)
网络隔离示例
# 宿主机
ip addr show docker0 # 显示 docker0 网桥# 容器1
docker run -d --name web nginx
docker exec web ip addr show # 显示容器的 veth 接口# 容器2
docker run -d --name db redis
docker exec db ip addr show # 不同的网络命名空间
6. 与虚拟机的对比
特性 | Docker 容器 | 虚拟机 |
---|---|---|
隔离级别 | 进程级别 | 硬件级别 |
启动速度 | 秒级 | 分钟级 |
性能损耗 | 1-5% | 15-30% |
镜像大小 | MB 级 | GB 级 |
隔离性 | 较弱(共享内核) | 强(完全隔离) |
适用场景 | 应用隔离、微服务 | 完整操作系统隔离 |
7. 总结
Docker 通过 Namespace + Cgroups + UnionFS 三大核心技术实现隔离:
Namespace:提供环境隔离(进程、网络、文件系统等)
Cgroups:提供资源限制(CPU、内存、磁盘 I/O 等)
UnionFS:提供存储隔离(镜像分层、写时复制)
这种设计使得容器既轻量快速(共享主机内核),又具备足够的隔离性(满足多应用部署需求),成为现代云原生应用的事实标准。