namespaces

Linux 命名空间:隔离 PID、网络、挂载、用户等资源视图

补充说明

namespace 是内核提供的资源视图隔离机制,容器本质上是“namespace + cgroup + 文件系统”的组合。常用类型有 mount、PID、network、IPC、UTS、user、cgroup(4.6+)和 time(5.6+)。排查时要区分“进程属于哪个 namespace”和“我在哪个 namespace 里观察”。

常用示例

# 查看当前所有 namespace 及其中的进程
lsns

# 查看当前 shell 的 namespace inode
readlink /proc/self/ns/*

# 创建独立 PID + mount namespace,并挂载新的 /proc
sudo unshare --fork --pid --mount --mount-proc bash

# 进入目标进程的 mount/uts/ipc/net/pid namespace
sudo nsenter -t <PID> -m -u -i -n -p

# 创建独立网络 namespace 并启用回环
sudo ip netns add lab0
sudo ip netns exec lab0 ip link set lo up
sudo ip netns exec lab0 ip addr

# 非特权用户创建 user namespace,并把当前 uid 映射为 root
unshare --user --map-root-user --fork bash

易错点与排错

读完自测

  1. 为什么 unshare --pid bash 之后 echo $$ 还是原来的 PID?
  2. 进入容器的 PID namespace 后,为什么 ps 里的 PID 和宿主机不一样?
  3. 容器的网络 namespace 与宿主机网络栈是什么关系?
答案
  1. unshare(CLONE_NEWPID) 只让之后创建的子进程进入新 namespace;需要 --fork 让 bash 成为新 namespace 的第一个进程。
  2. PID namespace 有自己的 PID 编号,容器内 PID 1 在宿主机上通常是另一个编号;映射关系见 /proc/<pid>/status 的 NSpid。
  3. 容器有独立的 net namespace(自己的接口、路由、iptables),通过 veth 对连接到宿主机 net namespace,最终走宿主机物理网卡和 qdisc。

相关条目