Namespace详解:让你秒懂容器的“隔离与共享”
Namespace详解:让你秒懂容器的“隔离与共享”
Docker 和 K8s 是如何把进程“关”进容器里的?当你执行
ls -l /proc/self/ns 时看到的那些神秘文件又代表什么?本文带你通过生动的比喻和实例,彻底搞懂 Linux Namespaces。
作为一名云原生工程师,我们每天都在和容器打交道。但你是否好奇过,所谓的“容器”在 Linux 内核层面到底长什么样?
当你登录到一台 Linux 服务器,执行 ls -l /proc/$$/ns,你会看到下面这些“天书”:
lrwxrwxrwx ... cgroup -> cgroup:[4026531835]lrwxrwxrwx ... ipc -> ipc:[4026531839]lrwxrwxrwx ... mnt -> mnt:[4026531840]lrwxrwxrwx ... net -> net:[4026531993]lrwxrwxrwx ... pid -> pid:[4026531836]lrwxrwxrwx ... user -> user:[4026531837]lrwxrwxrwx ... uts -> uts:[4026531838]
这些文件,就是容器技术的基石——Linux Namespaces。今天我们就来逐一拆解它们。
什么是 Namespace
如果把 Linux 操作系统比作一栋大楼,所有的进程原本都住在大厅里,共享所有的资源(水、电、厕所)。而 Namespace 就是在大楼里隔出的独立房间。
-
隔离:房间里的人以为自己拥有整个大楼,看不到房间外面的人。
-
共享:虽然住在房间里,但大家其实还是在同一栋大楼(同一个内核)里。
七大 Namespace 详解
1. mnt (Mount Namespace) —— 独立的“视界”
-
作用:隔离文件系统挂载点。
-
比喻:给房间装了单向玻璃。
-
实例:
-
你在容器里执行 mount -t tmpfs tmpfs /tmp,只有容器里的人能看到这个挂载,宿主机和其他容器完全无感。
-
这就是为什么 Docker 容器里有独立的 /proc、/sys,而不会和宿主机混淆。
-
2. net (Network Namespace) —— 独立的“网线”
-
作用:隔离网络栈(网卡、IP、路由表、端口)。
-
比喻:房间里单独拉了一根网线,有独立的路由器。
-
实例:
-
容器里的 eth0 IP 是 10.244.1.2,而宿主机是 192.168.1.100。
-
容器里监听 80 端口,宿主机上也可以监听 80 端口,互不冲突。
-
3. pid (PID Namespace) —— 独立的“户口本”
-
作用:隔离进程编号。
-
比喻:在房间里,你是“1号人物”(老大);但在大楼管理处,你只是个普通住户(编号 10086)。
-
实例:
-
容器内:ps -ef 看到主进程 PID 是 1。
-
宿主机:ps -ef 看到同一个进程,PID 可能是 45678。
-
这让容器内的进程以为自己是系统的初始化进程,拥有至高无上的地位。
-
4. uts (UTS Namespace) —— 独立的“门牌号”
-
作用:隔离主机名 (Hostname) 和域名。
-
比喻:你可以给自己的房间起名叫“总统套房”,不影响大楼叫“希尔顿”。
-
实例:
-
-
容器里 hostname my-web-app,宿主机的 hostname 依然是 node-01。
-
5. ipc (IPC Namespace) —— 独立的“电话线”
-
作用:隔离进程间通信(共享内存、信号量、消息队列)。
-
比喻:房间里的内线电话,打不到隔壁房间去。
-
实例:
-
防止不同容器的进程因为使用了相同的共享内存 Key 而发生冲突或数据泄露。
-
6. user (User Namespace) —— 独立的“身份”
-
作用:隔离用户 ID (UID) 和组 ID (GID)。
-
比喻:你在房间里穿着“皇帝的新衣”(Root),但走出房间你就是个平民。
-
实例:
-
容器内:你是 root (UID 0),可以为所欲为。
-
宿主机:你只是个普通用户 (UID 1000),没有破坏系统的权限。
-
这是容器安全的重要特性(Rootless Container)。
-
7. cgroup (Cgroup Namespace) —— 独立的“电表”
-
作用:隔离 Cgroup 根目录视图。
-
比喻:你只能看到自己房间的电表读数,看不到整栋楼的电表。
-
实例:
-
在容器里查看 /proc/self/cgroup,路径会变短,隐藏了宿主机复杂的层级结构。
-
那些数字代表什么
回到开头的文件列表: lrwxrwxrwx ... net -> net:[4026531993]
中括号里的数字 4026531993 是 Namespace 的 Inode 编号(身份证号)。
-
如何判断两个进程是否在同一个容器里? 看它们的 Namespace Inode 是否一样!如果 net:[...] 的数字一样,说明它们共享同一个网络栈(比如 K8s Pod 里的 Pause 容器和业务容器)。
-
常用命令:
-
lsns:列出系统所有 Namespace。
-
nsenter -t <PID> -n:穿越到目标进程的 Network Namespace 里去(修网络神器)。
-
举例:
下面是一个pod的两个容器,在node节点上分别查看这两个容器的进程:
pod的信息:sysops sysops-788dfd5f5c-8lmdm 2/2 Running 0 10d两个容器进程:.....containers:- args:- -c- python3 manage.py migrate && gunicorn -c sysops/config/gunicorn_conf.py sysops.asgi:applicationcommand:- shimage: x.com/ops/sysops:v5.4.25imagePullPolicy: IfNotPresentname: sysopsports:- containerPort: 8000name: sysopsprotocol: TCPresources:limits:cpu: "4"memory: 4Girequests:cpu: "2"memory: 2GiterminationMessagePath: /dev/termination-logterminationMessagePolicy: File......- args:- -c- cd ./golang-k8s;./k8s_informercommand:- shimage: x.com/ops/sysops:v5.4.25imagePullPolicy: IfNotPresentname: go-informerresources:limits:cpu: "2"memory: 2Girequests:cpu: "2"memory: 2Gi.....查看两个进程对应在/prod/pid/ns/net的inode值,结果一样,再查看一个非相同pod的容器进程,发现net inode值不同# ps -ef|grep k8s_informerroot 38881 36852 0 22:20 pts/0 00:00:00 grep --color=auto k8s_informerroot 50299 13547 0 Nov19 ? 00:00:00 sh -c cd ./golang-k8s;./k8s_informerroot 50312 50299 0 Nov19 ? 00:46:34 ./k8s_informer(root@k8n1-k8n1 2025-11-29 22:20:02 ~)# ls /proc/50299/ns/ipc mnt net pid user uts(root@k8n1-k8n1 2025-11-29 22:20:17 ~)# ls /proc/50299/ns/ -ltotal 0lrwxrwxrwx 1 root root 0 Nov 29 22:20 net -> net:[4026532784](root@k8n1-k8n1 2025-11-29 22:20:21 ~)# ps -ef|grep gunicorn_conf.pyroot 43142 36852 0 22:20 pts/0 00:00:00 grep --color=auto gunicorn_conf.pyroot 50266 13547 0 Nov19 ? 00:00:00 sh -c python3 manage.py migrate && gunicorn -c sysops/config/gunicorn_conf.py sysops.asgi:applicationroot 52904 50266 0 Nov19 ? 00:03:25 /usr/local/bin/python3.11 /usr/local/bin/gunicorn -c sysops/config/gunicorn_conf.py sysops.asgi:application# ls -l /proc/50266/ns/total 0lrwxrwxrwx 1 root root 0 Nov 29 22:20 net -> net:[4026532784](root@k8n1-k8n1 2025-11-29 22:20:57 ~)第三个进程-非相同pod的容器进程# ps -ef|grep argocd-root 40761 36852 0 22:31 pts/0 00:00:00 grep --color=auto argocd-1001 46942 43638 0 Nov13 ? 00:13:17 /shared/argocd-dex rundexpolkitd 59513 59098 0 Nov13 ? 00:01:30 /usr/bin/tini -- /usr/local/bin/argocd-applicationset-controllerpolkitd 59526 59513 0 Nov13 ? 00:38:52 /usr/local/bin/argocd-applicationset-controllerpolkitd 61684 61459 0 Nov13 ? 00:01:30 /usr/bin/tini -- /usr/local/bin/argocd-application-controllerpolkitd 61697 61684 1 Nov13 ? 07:11:29 /usr/local/bin/argocd-application-controller(root@k8n1-k8n1 2025-11-29 22:31:09 ~)# ls /proc/59513/ns/net -llrwxrwxrwx 1 polkitd input 0 Nov 29 22:31 /proc/59513/ns/net -> net:[4026532962]
结尾
Linux Namespaces 通过这 7 种隔离机制,为进程编织了一个完美的“楚门的世界”。理解了它们,你就理解了容器技术的灵魂。如果你觉得这篇文章有用,欢迎点赞、在看、转发! ❤️
小知识
使用 nsenter 进入容器网络空间执行-查看网络相关内容nsenter -t 659030(容器服务进程) -n ss -xl|grep phpnsenter 是 Linux 容器调试的“瑞士军刀”。容器本质上就是利用 Linux 的 Namespace(命名空间) 技术做隔离的。nsenter (Namespace Enter) 的作用就是进入这些隔离的空间。只要你知道容器进程的 PID,你就可以用 nsenter 进入它的任何维度:网络 (-n / --net):用途:看 IP、端口、防火墙规则、抓包。命令:nsenter -t <PID> -n ip addr 或 nsenter -t <PID> -n tcpdump ...
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)