Linux 命名空间:隔离 PID、网络、挂载、用户等资源视图
namespace 是内核提供的资源视图隔离机制,容器本质上是“namespace + cgroup + 文件系统”的组合。常用类型有 mount、PID、network、IPC、UTS、user、cgroup(4.6+)和 time(5.6+)。排查时要区分“进程属于哪个 namespace”和“我在哪个 namespace 里观察”。
lsns、/proc/<pid>/ns/*、readlink /proc/self/ns/*。nsenter -t <PID>;创建:unshare、ip netns、clone(CLONE_NEW*)。setns 通常需要 root 或 CAP_SYS_ADMIN;user 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
unshare --pid 不带 --fork 时调用者本身不会进入新的 PID namespace,看起来“没生效”;PID namespace 只影响之后创建的子进程。/proc 仍是旧的,ps 会显示错误的 PID 视图;用 nsenter -m -p 或 --mount-proc。nsenter -t <PID> 会失败;需要在宿主机执行,或先进入宿主 PID namespace。ip netns 创建的网络 namespace 前要先停止其中进程,否则 namespace 会因仍被引用而继续存在。unshare/setns;报 Operation not permitted 时先看 capsh --print 和 seccomp 配置。time namespace 需要 5.6+ 内核和较新的 util-linux,老系统上 unshare --time 会直接不支持。unshare --pid bash 之后 echo $$ 还是原来的 PID?ps 里的 PID 和宿主机不一样?unshare(CLONE_NEWPID) 只让之后创建的子进程进入新 namespace;需要 --fork 让 bash 成为新 namespace 的第一个进程。/proc/<pid>/status 的 NSpid。