#作者:朱雷
文章目录
- 1、简介
- 2、功能与用途
- 2.1. 核心功能
- 2.1.1. 进入命名空间
- 2.1.2. 支持多种命名空间
- 2.1.3. 容器调试
- 3、安装
- 3.1. 依赖包
- 3.2. 权限要求
- 3.3. 命令用法与示例
- 3.3.1. 基本语法
- 3.3.2. 常用选项包括:
- 3.3.3. 示例
- 4、 应用场景与优势
- 4.1. 容器调试
- 4.2. 资源管理
- 4.3. 简化操作
- 5. 注意事项
- 6、总结
1、简介
nsenter 是 Linux 系统中的一个命令行工具,用于进入指定进程的命名空间(namespace)中执行命令,常用于调试、管理和容器化环境中的资源隔离。nsenter 允许用户进入指定进程的命名空间(如 PID、网络、用户等),在该命名空间内执行命令。
2、功能与用途
2.1. 核心功能
2.1.1. 进入命名空间
通过指定目标进程的 PID 或容器 ID,进入其命名空间,执行命令(如查看网络信息、调试容器等)。
2.1.2. 支持多种命名空间
支持进入 PID、网络、用户、挂载、IPC 等命名空间,适用于容器、网络调试等场景。
2.1.3. 容器调试
常用于容器网络调试(如查看容器网络配置)、容器内命令执行(如执行 ip addr
)。
3、安装
3.1. 依赖包
nsenter 通常位于 util-linux
包中,可通过 apt install util-linux
或源码安装。
3.2. 权限要求
通常需要 root 权限,部分场景(如进入容器)可能需要额外权限。
3.3. 命令用法与示例
3.3.1. 基本语法
Usage:nsenter [options] [<program> [<argument>...]]Run a program with namespaces of other processes.Options:-a, --all enter all namespaces-t, --target <pid> target process to get namespaces from-m, --mount[=<file>] enter mount namespace-u, --uts[=<file>] enter UTS namespace (hostname etc)-i, --ipc[=<file>] enter System V IPC namespace-n, --net[=<file>] enter network namespace-p, --pid[=<file>] enter pid namespace-C, --cgroup[=<file>] enter cgroup namespace-U, --user[=<file>] enter user namespace-S, --setuid <uid> set uid in entered namespace-G, --setgid <gid> set gid in entered namespace--preserve-credentials do not touch uids or gids-r, --root[=<dir>] set the root directory-w, --wd[=<dir>] set the working directory-F, --no-fork do not fork before exec'ing <program>-Z, --follow-context set SELinux context according to --target PID-h, --help display this help-V, --version display version
3.3.2. 常用选项包括:
-a, --all 进入所有命名空间
-t, --target <pid> 从目标进程获取命名空间
-m, --mount[=<文件>] 进入挂载命名空间
-n, --net[=<文件>] 进入网络命名空间
-p, --pid[=<文件>] 进入进程ID命名空间
-C, --cgroup[=<文件>] 进入cgroup命名空间
-e, --env 继承目标进程的环境变量
3.3.3. 示例
进入进程 62117 的 PID 命名空间并执行uptime命令:
[root@paas-node-111 ~]# nsenter -t 62117 -n uptime14:46:03 up 75 days, 18:52, 1 user, load average: 4.49, 4.23, 4.61
进入容器网络命名空间执行ip 命令:
[root@paas-node-111 ~]# nsenter -t 2579 -n ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 172.18.0.4/16 brd 172.18.255.255 scope global eth0valid_lft forever preferred_lft forever
查看docker 容器的pid:
[root@paas-node-111 ~]# docker inspect dcd2220e91b0|grep Pid
"Pid": 2579,
"PidMode": "",
"PidsLimit": null,
或
[root@paas-node-111 ~]# docker inspect -f {{.State.Pid}} dcd2220e91b0
2579
进入所有命名空间执行命令:
[root@paas-node-111 ~]# nsenter -t 2579 -a freetotal used free shared buff/cache available
Mem: 3963132 1819480 162336 6160 1981316 1835540
Swap: 4194300 1731000 2463300
在 K8s 中在得到容器 pid 之前还需获取容器的 ID
查看pod容器id:
[root@paas-node-111 ~]# kubectl describe pod redis-7d67bc68ff-pbzms|grep -i "container id"Container ID: docker://1268be01dbf62a06a50415b4eb7d6cf3bd3be9f2dbf04c9ff765b1a6cad11fd0
或
[root@paas-node-111 ~]# kubectl get pod redis-7d67bc68ff-pbzms -o template --template='{{range .status.containerStatuses}}{{.containerID}}{{end}}'
docker://1268be01dbf62a06a50415b4eb7d6cf3bd3be9f2dbf04c9ff765b1a6cad11fd0
用pod容器id去获取容器的pid
docker ps|grep 1268be01
1268be01dbf6 5bb541ae990c "docker-entrypoint.s…" 2 weeks ago Up 2 weeks k8s_redis_redis-7d67bc68ff-pbzms_default_f68a2459-26fc-4c5f-bfe5-6b5550c81ccc_1
[root@paas-node-113 ~]# docker inspect 1268be01 |grep -i "pid""Pid": 57968,"PidMode": "","PidsLimit": null,
默认使用docker exec 进入容器,容器并没有提供ping 命令:
[root@paas-node-113 ~]# docker exec -it 1268be01 bash
root@redis-7d67bc68ff-pbzms:/data# ping 10.148.55.111
bash: ping: command not found
此时,就可以使用 nsenter 命令进入容器的网络命名空间内,使用ping命令去执行。
[root@paas-node-113 ~]# nsenter -t 57968 -n ping 10.148.55.111
PING 10.148.55.111 (10.148.55.111) 56(84) bytes of data.
64 bytes from 10.148.55.111: icmp_seq=1 ttl=63 time=0.305 ms
64 bytes from 10.148.55.111: icmp_seq=2 ttl=63 time=0.361 ms
64 bytes from 10.148.55.111: icmp_seq=3 ttl=63 time=0.173 ms
^C
--- 10.148.55.111 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.173/0.279/0.361/0.081 ms
看下路由是否是走了容器的网络:
[root@paas-node-113 ~]# nsenter -t 57968 -n mtr 10.148.55.111
[root@paas-node-113 ~]# mtr 10.148.55.111
以上可以看到明显是进入容器网络命名空间后,路由多了一跳。
从以上信息可以看到,进入容器网络空间后,路由先到宿主机再由宿主机将数据包发送到目标地址:10.148.55.111
4、 应用场景与优势
4.1. 容器调试
在容器网络故障排查中,nsenter 可直接进入容器的网络命名空间执行命令(如 ip addr
、ping
),无需容器内安装基础工具。
4.2. 资源管理
用于调试进程隔离、资源隔离(如 PID、用户命名空间)。
4.3. 简化操作
相比 docker exec
,nsenter 提供更灵活的命名空间控制,支持直接进入容器内部执行命令。
5. 注意事项
1、权限限制:部分操作(如进入容器)可能需要 root 权限或特定权限设置。
2、兼容性:nsenter 依赖 Linux 命名空间技术,适用于支持命名空间的 Linux 内核版本。
6、总结
nsenter 是 Linux 中用于命名空间管理和调试的工具,广泛应用于容器、网络调试和资源隔离场景。其核心功能是通过进入指定命名空间执行命令,支持多种命名空间类型和灵活的命令选项,是 Linux 系统管理和调试的重要工具。