news 2026/5/9 7:10:54

第二部分-Docker核心原理——07. 命名空间(Namespace)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第二部分-Docker核心原理——07. 命名空间(Namespace)

07. 命名空间(Namespace)

1. 命名空间概述

命名空间(Namespace)是 Linux 内核实现容器隔离的核心技术。它让每个容器拥有独立的资源视图,容器内的进程看不到宿主机和其他容器的资源。

┌─────────────────────────────────────────────────────────────┐ │ Linux 命名空间类型 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 宿主机内核空间 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ┌───────────────┼───────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ 容器 A │ │ 容器 B │ │ 容器 C │ │ │ │ │ │ │ │ │ │ │ │ PID: 1 │ │ PID: 1 │ │ PID: 1 │ │ │ │ NET: 独立 │ │ NET: 独立 │ │ NET: 独立 │ │ │ │ MNT: 独立 │ │ MNT: 独立 │ │ MNT: 独立 │ │ │ │ UTS: 独立 │ │ UTS: 独立 │ │ UTS: 独立 │ │ │ │ IPC: 独立 │ │ IPC: 独立 │ │ IPC: 独立 │ │ │ │ USER: 独立│ │ USER: 独立│ │ USER: 独立│ │ │ └───────────┘ └───────────┘ └───────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘

2. 六种命名空间

命名空间功能隔离内容
PID进程隔离进程 ID 空间
NET网络隔离网络设备、IP、端口
MNT文件系统隔离挂载点、文件系统视图
UTS主机名隔离主机名、域名
IPC进程间通信隔离信号量、消息队列
USER用户隔离用户和组 ID

3. PID 命名空间

3.1 原理

PID 命名空间让容器内的进程拥有独立的 PID 编号,每个容器都从 1 开始。

┌─────────────────────────────────────────────────────────────┐ │ PID 命名空间隔离 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 宿主机 PID 空间 容器 PID 空间 │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ PID: 1 systemd│ │ PID: 1 nginx │ │ │ │ PID: 2 kthread│ │ PID: 2 bash │ │ │ │ PID: 100 dockerd│ │ PID: 3 sh │ │ │ │ PID: 150 nginx │◄────────┐│ │ │ │ │ PID: 151 bash │ ││ │ │ │ └─────────────────┘ │└─────────────────┘ │ │ │ │ │ └─ 映射关系 │ │ 宿主机 PID 150 ←→ 容器 PID 1 │ │ │ └─────────────────────────────────────────────────────────────┘

3.2 演示与实践

# 查看当前进程的命名空间ls-la/proc/$$/ns/# lrwxrwxrwx 1 user user 0 ... ipc -> ipc:[4026531839]# lrwxrwxrwx 1 user user 0 ... mnt -> mnt:[4026531840]# lrwxrwxrwx 1 user user 0 ... net -> net:[4026531992]# lrwxrwxrwx 1 user user 0 ... pid -> pid:[4026531836]# lrwxrwxrwx 1 user user 0 ... user -> user:[4026531837]# lrwxrwxrwx 1 user user 0 ... uts -> uts:[4026531838]# 启动容器并查看其命名空间CONTAINER_PID=$(dockerinspect-f'{{.State.Pid}}'container_name)ls-la/proc/$CONTAINER_PID/ns/# 验证 PID 隔离dockerrun-it--rmalpinesh# 容器内执行/# ps aux# PID USER TIME COMMAND# 1 root 0:00 sh# 7 root 0:00 ps aux# 宿主机上查看对应进程psaux|grep-E"sh|ps"# 在容器内创建新命名空间# unshare 命令创建隔离环境sudounshare--fork--pid--mount-procbashpsaux# 现在 PID 从 1 开始

4. NET 命名空间

4.1 原理

NET 命名空间提供独立的网络栈,包括网络设备、IP 地址、端口、路由表等。

┌─────────────────────────────────────────────────────────────┐ │ NET 命名空间隔离 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 宿主机网络 容器网络 │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ eth0: 192.168.1.10 │ eth0: 172.17.0.2│ │ │ │ lo: 127.0.0.1 │ │ lo: 127.0.0.1 │ │ │ │ docker0: 172.17.0.1 │ │ │ │ │ iptables 规则 │◄────────│ iptables 规则 │ │ │ │ 路由表 │ veth │ 路由表 │ │ │ └─────────────────┘ └─────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘

4.2 演示与实践

# 查看网络命名空间ipnetns list# 创建网络命名空间sudoipnetnsaddtest-nssudoipnetns list# 进入网络命名空间sudoipnetnsexectest-nsbash# 在命名空间内查看网络ipaddr# 1: lo: <LOOPBACK> ...# 只有 lo 接口,没有 eth0# 创建 veth pair 连接命名空间sudoiplinkaddveth0typeveth peer name veth1sudoiplinksetveth1 netns test-ns# 分配 IPsudoipaddradd10.0.0.1/24 dev veth0sudoipnetnsexectest-nsipaddradd10.0.0.2/24 dev veth1# 启动接口sudoiplinksetveth0 upsudoipnetnsexectest-nsiplinksetveth1 up# 测试连通性ping10.0.0.2# Docker 容器网络命名空间dockerrun-d--nameweb nginxCONTAINER_PID=$(dockerinspect-f'{{.State.Pid}}'web)# 进入容器的网络命名空间sudonsenter-t$CONTAINER_PID-nipaddr# 清理sudoipnetns delete test-nsdockerrm-fweb

5. MNT 命名空间

5.1 原理

MNT 命名空间提供独立的文件系统挂载点视图,每个容器有独立的根文件系统。

┌─────────────────────────────────────────────────────────────┐ │ MNT 命名空间隔离 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 宿主机挂载点 容器挂载点 │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ / │ │ / (alpine root) │ │ │ │ ├─ bin │ │ ├─ bin │ │ │ │ ├─ etc │ │ ├─ etc │ │ │ │ ├─ home │ │ ├─ home │ │ │ │ ├─ var │ │ └─ var │ │ │ │ └─ docker │ │ │ │ │ │ │ │ 额外挂载: │ │ │ │ /data (bind) │◄────────│ /data (bind) │ │ │ └─────────────────┘ └─────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘

5.2 演示与实践

# 查看挂载命名空间ls-la/proc/$$/ns/mnt# 创建新的 MNT 命名空间sudounshare--mountbash# 在新命名空间中挂载exportPS1="ns-mnt$ "mount-ttmpfs tmpfs /tmpmount|greptmpfs# 退出后,挂载消失exit# Docker 容器文件系统dockerrun-it--rmalpinesh/# mount | head -5# overlay on / type overlay (rw,relatime)# proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)# 查看容器的 rootfsCONTAINER_ID=$(dockercreate alpine)dockerexport$CONTAINER_ID|tar-tv|head-20dockerrm$CONTAINER_ID

6. UTS 命名空间

6.1 原理

UTS(UNIX Time-sharing System)命名空间隔离主机名和域名。

# 查看 UTS 命名空间ls-la/proc/$$/ns/uts# 创建新的 UTS 命名空间sudounshare--utsbash# 修改主机名exportPS1="ns-uts$ "hostnamecontainer-hosthostname# container-host# 新开终端查看宿主机主机名(未变化)hostname# Docker 容器演示dockerrun-it--rm--hostnamemycontainer alpinesh/# hostname# mycontainer/# cat /etc/hostname# mycontainer# 自定义主机名dockerrun-it--rm--hostnameweb-server alpinehostname

7. IPC 命名空间

7.1 原理

IPC 命名空间隔离进程间通信资源,如信号量、消息队列、共享内存。

# 查看 IPC 命名空间ls-la/proc/$$/ns/ipc# 创建消息队列(宿主机)ipcmk-Qipcs-q# 创建新的 IPC 命名空间sudounshare--ipcbash# 在新命名空间中查看消息队列ipcs-q# 看不到宿主机创建的消息队列# Docker 演示dockerrun-it--rmalpinesh/# ipcmk -Q# 容器内创建的消息队列/# ipcs -q# 不同容器之间的 IPC 隔离dockerrun-d--nameipc1 alpinesleep3600dockerrun-d--nameipc2 alpinesleep3600dockerexecipc1 ipcmk-Qdockerexecipc2 ipcs-q# 看不到 ipc1 创建的消息队列# 共享 IPC 命名空间dockerrun-it--rm--ipccontainer:ipc1 alpine ipcs-q# 可以看到

8. USER 命名空间

8.1 原理

USER 命名空间隔离用户 ID 和组 ID,实现非特权用户运行容器。

┌─────────────────────────────────────────────────────────────┐ │ USER 命名空间映射 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 容器内 UID 宿主机 UID │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ UID 0 (root) │ ────────▶│ UID 100000 │ │ │ │ UID 1 (daemon) │ ────────▶│ UID 100001 │ │ │ │ UID 1000 (user) │ ────────▶│ UID 101000 │ │ │ └─────────────────┘ └─────────────────┘ │ │ │ │ 容器内 root 权限被映射为宿主机普通用户权限 │ │ 提升安全性:即使容器被攻破,也无法获取宿主机 root │ │ │ └─────────────────────────────────────────────────────────────┘

8.2 演示与实践

# 查看 USER 命名空间ls-la/proc/$$/ns/user# 启用 user namespace(需要配置)# /etc/docker/daemon.json{"userns-remap":"default"}# 重新加载配置sudosystemctl restartdocker# 查看映射cat/proc/self/uid_mapcat/proc/self/setgroups# 容器中查看用户dockerrun-it--rmalpineid# uid=0(root) gid=0(root) groups=0(root)# 宿主机查看对应进程的用户# 如果启用了 userns-remap,容器内 root 对应宿主机普通用户# 手动创建 user namespacesudounshare--user--map-root-userbashid# uid=0(root) gid=0(root)# 查看实际映射cat/proc/self/uid_map# 0 1000 1

9. 命名空间操作工具

9.1 lsns - 列出命名空间

# 列出所有命名空间lsns# 列出特定类型lsns-tnet lsns-tpid lsns-tmnt# 查看详细信息lsns-oNS,TYPE,NPROCS,PID,COMMAND# 查看特定进程的命名空间lsns-p1234

9.2 nsenter - 进入命名空间

# 进入容器的网络命名空间dockerinspect-f'{{.State.Pid}}'container_namesudonsenter-t<PID>-nipaddr# 进入容器的所有命名空间sudonsenter-t<PID>-abash# 只进入特定命名空间sudonsenter-t<PID>-n-mbash# 网络 + 挂载

9.3 unshare - 创建命名空间

# 创建新的 PID 命名空间sudounshare--fork--pid--mount-procbash# 创建新的网络命名空间sudounshare--netbash# 创建新的 UTS 命名空间并修改主机名sudounshare--utsbashhostnamenewhost# 创建新的所有命名空间sudounshare--user--ipc--pid--net--uts--mount--forkbash

10. Docker 中的命名空间

# 查看 Docker 容器的命名空间CONTAINER_PID=$(dockerinspect-f'{{.State.Pid}}'container_name)# 查看命名空间ls-la/proc/$CONTAINER_PID/ns/# 命名空间 ID 格式:类型:[inode号]# ipc:[4026532540]# mnt:[4026532538]# net:[4026532543]# pid:[4026532541]# user:[4026531837]# uts:[4026532539]# 两个容器共享网络命名空间dockerrun-d--namecontainer1 nginxdockerrun-d--namecontainer2--networkcontainer:container1 nginxdockerexeccontainer2ipaddr# 和 container1 相同的网络配置

11. 总结对比

命名空间隔离内容容器中使用核心命令示例
PID进程 ID必须unshare --pid
NET网络栈必须unshare --net
MNT文件系统必须unshare --mount
UTS主机名必须unshare --uts
IPC进程通信必须unshare --ipc
USER用户 ID可选unshare --user

12. 常见问题

Q1: 如何判断两个进程在同一命名空间?

# 比较命名空间 IDls-la/proc/PID1/ns/pidls-la/proc/PID2/ns/pid# 如果 inode 号相同,则在同一命名空间

Q2: 如何让容器共享宿主机网络?

dockerrun--networkhostnginx

Q3: 如何让容器共享其他容器的命名空间?

# 共享网络dockerrun--networkcontainer:other_container# 共享 IPCdockerrun--ipccontainer:other_container# 共享 PIDdockerrun--pidcontainer:other_container

13. 小结

  • 命名空间是容器隔离的基础
  • Linux 提供 6 种命名空间实现资源隔离
  • PID:进程隔离,容器内 PID 从 1 开始
  • NET:网络隔离,独立网络栈
  • MNT:文件系统隔离,独立根文件系统
  • UTS:主机名隔离
  • IPC:进程间通信隔离
  • USER:用户 ID 隔离,提升安全性
  • 使用lsns,nsenter,unshare工具操作命名空间

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 7:09:19

Qwen3.5-4B-AWQ详细步骤:GPU显存不足时kill残留VLLM进程标准流程

Qwen3.5-4B-AWQ详细步骤&#xff1a;GPU显存不足时kill残留VLLM进程标准流程 1. 项目概述 Qwen3.5-4B-AWQ-4bit是阿里云通义千问团队推出的轻量级稠密模型&#xff0c;经过4bit AWQ量化后显存占用仅约3GB&#xff0c;可以在RTX 3060/4060等消费级显卡上流畅运行。 核心优势&…

作者头像 李华
网站建设 2026/5/9 7:07:34

ru-text:为AI编码助手注入专业俄语文本质量引擎

1. 项目概述&#xff1a;为AI编码助手注入俄语文本质量之魂 如果你是一名在俄语环境中工作的开发者、产品经理或内容创作者&#xff0c;并且正在使用诸如 Claude Code、GitBrains 或 Cursor 这类AI编码助手&#xff0c;那么你很可能面临一个共同的痛点&#xff1a;当助手用俄语…

作者头像 李华
网站建设 2026/5/9 6:57:31

ARM分散加载文件详解:内存管理与优化实践

1. ARM分散加载文件基础概念解析在嵌入式系统开发中&#xff0c;内存管理是决定系统稳定性和性能的关键因素。ARM架构的链接器通过一种称为分散加载文件&#xff08;Scatter File&#xff09;的配置文件&#xff0c;为开发者提供了精细控制代码和数据在内存中布局的能力。这种技…

作者头像 李华
网站建设 2026/5/9 6:53:31

AI智能体工作流编排:从单体到流水线的工程实践

1. 项目概述&#xff1a;当AI智能体需要“流水线”最近在折腾AI智能体&#xff08;Agent&#xff09;的开发&#xff0c;发现一个挺普遍的问题&#xff1a;单个智能体的能力再强&#xff0c;也总有边界。比如&#xff0c;一个能写代码的智能体&#xff0c;可能不擅长做数据可视…

作者头像 李华
网站建设 2026/5/9 6:49:36

Fabrk框架全解析:一体化RAD方案加速全栈开发与后台管理

1. 项目概述&#xff1a;一个被低估的快速应用开发框架如果你是一名全栈开发者&#xff0c;或者正带领一个小团队从零开始构建一个现代化的Web应用&#xff0c;那么你大概率经历过这样的场景&#xff1a;项目初期&#xff0c;你花了大量时间在搭建项目脚手架、配置数据库连接、…

作者头像 李华