nsenter 命令详解
更新时间:2026-09-17。「一个命令一个文档」系列,属于容器与云族。容器隔离本质是 namespace,nsenter 让你钻进某个进程的 namespace 里执行命令,是排查容器(尤其极简镜像)的利器。
一、常用法
bash
nsenter -t <PID> -a <cmd> # 进入该进程全部 namespace
nsenter -t <PID> -n <cmd> # 只进 net namespace(网络栈)
nsenter -t <PID> -m <cmd> # 进 mount namespace(文件系统视图)
nsenter -t <PID> -p <cmd> # 进 pid namespace(需配合 -m 才能看到 /proc 生效)
nsenter -t <PID> -u <cmd> # uts(主机名)
nsenter -t <PID> -i <cmd> # ipc
nsenter -t <PID> -U <cmd> # user namespace| 标志 | namespace | 典型用途 |
|---|---|---|
-n/--net | net | 用容器网络栈执行 ss/ip/curl/tcpdump |
-m/--mount | mount | 看容器视角的挂载/文件 |
-p/--pid | pid | 进入容器进程号空间(常配 -m) |
-a/--all | 全部 | 等同 docker exec 进容器,但用的是宿主二进制 |
二、最常见:进容器网络栈排查
bash
# 1. 找到容器中某进程在宿主上的 PID
PID=$(docker inspect -f '{{.State.Pid}}' mycontainer)
# 或 crictl inspect --output go-template ...;K8s 用 crictl/containerd 取 PID
# 2. 在该容器网络命名空间里用宿主工具
nsenter -t $PID -n ss -tanp
nsenter -t $PID -n ip addr
nsenter -t $PID -n curl -v http://localhost:8080/health
nsenter -t $PID -n tcpdump -i any -nn port 53这解决了容器里没有排查工具的痛点:很多精简/distroless 镜像里没有 ss、curl、tcpdump,也没有 shell(
docker exec -it ... sh直接报 no shell)。nsenter 用的是宿主机的二进制,却在容器的网络/挂载命名空间里执行,工具和环境各取所长。
三、和 docker exec / kubectl exec 的区别
| 维度 | nsenter | docker exec |
|---|---|---|
| 依赖容器内有命令 | 否,用宿主命令 | 是,镜像里得有 sh/工具 |
| 视角 | 指定单个 namespace,可只进 net | 进容器默认工作环境 |
| 权限 | 需要宿主 root/CAP_SYS_ADMIN | 受容器配置限制 |
| 适用 | distroless、只查网络栈、宿主抓容器包 | 普通容器内交互 |
K8s 节点上还可用 ephemeral container(kubectl debug)做类似事;但只要能登录节点、拿到容器 PID,nsenter 最直接。
四、注意
-p进 pid namespace 后想让ps看到新空间的进程,需同时-m挂载该 namespace 的 /proc,否则 ps 仍读宿主 /proc:bashnsenter -t $PID -a ps -ef # -a 已含 mount,最省心- 操作的是真实运行环境,在 net 命名空间里改规则/抓包会影响该容器,注意授权。
- 列出系统现有 namespace 用配套的 lsns;namespace 与 cgroup 的关系见容器概念章。
相关命令
列 namespace 用 lsns,新建隔离用 unshare,容器内连接仍可结合 ss/tcpdump,资源限制见 cgroup 命令族(cgcreate)。
总结
nsenter -t PID -n/-m/-p/-a cmd = 钻进目标进程/容器的某个 namespace 执行命令:最常用 -n 借容器网络栈、用宿主的 ss/ip/curl/tcpdump 排查,解决 distroless 镜像没 shell、没工具的问题;它用宿主二进制在容器命名空间里运行,比 docker exec 更底层、不依赖镜像内容,进 pid 空间要配 -m,并需要宿主 root 权限。