unshare 命令详解
更新时间:2026-09-17。「一个命令一个文档」系列,属于容器与云族。容器的隔离由 namespace 实现,
unshare让你手工创建新 namespace 并在其中跑进程,是理解容器最小原理、做网络/文件系统隔离实验的工具。
一、常用法
bash
sudo unshare -n bash # 新建 net namespace 后开 shell(只有 lo,无路由)
sudo unshare -u bash # 新 uts,可独立 hostname
sudo unshare -m bash # 新 mount namespace,mount/umount 不影响宿主
sudo unshare -p -f bash # 新 pid namespace,-f fork 让其中进程看到 PID 1
unshare -U -r bash # 新 user ns 并映射为 root(普通用户可免 sudo,需内核允许)
sudo unshare -n -m -p -f bash # 组合多个 namespace,接近"裸容器"| 标志 | namespace | 效果 |
|---|---|---|
-n | net | 独立网卡/路由/端口,初始只有 down 的 lo |
-m | mount | 独立挂载表,配合 mount --make-rprivate / |
-p | pid | 独立进程号空间,常配 -f 与 --mount-proc |
-u | uts | 独立 hostname/domainname |
-i | ipc | 隔离 System V IPC、消息队列 |
-U | user | 独立 uid/gid 映射,-r/--map-root-user 在里面当 root |
二、两个高频正确姿势
bash
# 1. PID namespace 里要能看到新的 /proc,否则 ps 仍显示宿主进程
sudo unshare -p -f --mount-proc bash
ps -ef # 现在 bash 是 PID 1
# 2. 无 root 用 user namespace 做网络/挂载实验
unshare -Urn bash # -U user + -r 映射 root + -n net,普通用户即可
ip link set lo up在新 net namespace 里
ss/curl一开始什么都连不出去是正常的:它只有一块未启用的 lo,需要用ip link set lo up、veth pair/ip netns接到宿主才能通信。做 veth 联调时常用ip netns add(内部也是 unshare+bind mount ns)。
三、和相关命令/概念的关系
- 与 nsenter:unshare 创建并进入新 namespace;nsenter 加入已存在的 namespace,方向相反。
- 与容器:Docker/containerd 启动容器等价于"unshare 一组 namespace + cgroup 限额 + 切根文件系统"。unshare 是这层机制的手动入口(chroot/pivot_root 负责文件系统根)。
- 常见报错
Operation not permitted:缺 CAP_SYS_ADMIN,或发行版/user namespace 受限(sysctl kernel.unprivileged_userns_clone、seccomp、受限环境);root 下多数可用。
相关命令
进入已存在 namespace 用 nsenter,列出用 lsns,网络配置用 ip,隔离后限资源用 cgroup(cgcreate)。
总结
unshare = 在新建的 namespace 中运行程序,是容器隔离的最小手工原型:-n 独立网络栈、-m 独立挂载、-p -f --mount-proc 独立进程号、-u 独立主机名,普通用户可借 -U -r 在 user namespace 里当 root;它负责"创建并进入",与负责"加入既有 namespace"的 nsenter 相对,配合 cgroup 和切根就凑齐了容器的隔离与限额两大要素。