Linux Namespace 是 Docker 实现容器资源隔离的核心机制,通过创建独立命名空间副本使容器拥有进程、网络、文件系统等独立视图;共六类:PID、Network、MNT、UTS、IPC、User,分别隔离进程树、网络栈、挂载点、主机名、IPC 通信和用户 ID;其仅提供视图隔离,资源限制需依赖 cgroups,安全性增强需结合 User Namespace 与 SELinux 等机制。

Linux Namespace 是 Docker 实现容器资源隔离的核心机制,它让每个容器拥有独立的视图(如进程、网络、文件系统等),彼此互不可见。这种“看不见对方”的效果,并非靠限制,而是靠创建独立命名空间副本来达成。
六类核心 Namespace 及其隔离作用
Linux 内核提供 6 种 Namespace 类型,Docker 启动容器时默认启用其中多数:
- PID Namespace:容器内 PID=1 的进程只看到自己命名空间内的进程树,宿主机和其他容器的进程完全不可见;注意:子命名空间无法看到父命名空间的进程,但父可查看子(需权限)
-
Network Namespace:每个容器拥有独立的网络栈(网卡、IP、路由表、iptables 规则),实现网络隔离;Docker 默认用
bridge模式为其分配私有 IP 并通过 veth-pair 连接宿主机网桥 -
MNT Namespace:隔离挂载点,使容器可拥有专属的根文件系统(如通过
chroot或mount --bind构建);Docker 利用联合文件系统(如 overlay2)叠加只读镜像层与可写层,再挂载进该命名空间 -
UTS Namespace:隔离主机名(hostname)和域名(domainname),因此
docker run --hostname myapp只影响当前容器内uname -n输出 - IPC Namespace:隔离 System V IPC 和 POSIX 消息队列,防止容器间通过共享内存或信号量意外通信
-
User Namespace:映射容器内 UID/GID 到宿主机非特权 UID(如容器 root→宿主机 100000),大幅提升安全性;Docker 默认不启用,需显式配置
--userns-remap
Namespace 如何被创建与组合使用
Docker 不直接调用 clone() 系统调用,而是通过 runc(底层运行时)在创建容器进程时传入对应标志位(如 CLONE_NEWPID | CLONE_NEWNET),一次性创建多个 Namespace。关键点在于:
- 每个 Namespace 类型是独立的内核对象,可单独启用或禁用;例如
docker run --network host就是复用宿主机 Network Namespace,跳过网络隔离 - Namespace 具有层级关系:子进程默认继承父进程的 Namespace,只有显式指定新标志才会创建新实例;容器启动后,其 init 进程(PID=1)即成为该 Namespace 的“领头进程”
- 可通过
/proc/[pid]/status查看某进程所属的 Namespace ID(如NSpid:行),也可用ls -l /proc/[pid]/ns/查看绑定关系
Namespace 的局限性与补充手段
Namespace 解决的是“视图隔离”,而非“资源限制”。它让容器“看不见”其他资源,但不阻止其耗尽 CPU、内存或磁盘 IO——这部分由 cgroups 负责。
- 例如:一个容器即使在自己的 PID Namespace 中只有 10 个进程,仍可能用满宿主机全部内存;必须配合 cgroups 的
memory.limit_in_bytes才能硬性约束 - 某些场景下 Namespace 隔离不彻底:比如未启用 User Namespace 时,容器内 root 用户在宿主机上仍具高权限(UID=0),一旦逃逸即等同宿主机 root
- 部分内核对象(如时间、sysctl 参数)尚未被 Namespace 化,仍全局可见;因此容器间若需强隔离,需结合 SELinux/AppArmor 等强制访问控制机制










