#作者:朱雷
文章目錄
- 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 系統管理和調試的重要工具。