nsenter命令是一个可以在指定进程的命令空间下运行指定程序的命令。它位于util-linux包中。
1、用途
一个最典型的用途就是进入容器的网络命令空间。相当多的容器为了轻量级,是不包含较为基础的命令的,
比如说ip address,ping,telnet,ss,tcpdump等等命令,这就给调试容器网络带来相当大的困扰:
只能通过docker inspect ContainerID命令获取到容器IP,以及无法测试和其他网络的连通性。
这时就可以使用nsenter命令仅进入该容器的网络命名空间,使用宿主机的命令调试容器网络。
此外,nsenter也可以进入mnt,uts,ipc,pid,user命令空间,以及指定根目录和工作目录。
2、用法
nsenter [options] [program [arguments]]
options:
- -t, --target pid:指定被进入命名空间的目标进程的pid
- -m, --mount[=file]:进入mount命令空间。如果指定了file,则进入file的命令空间
- -u, --uts[=file]:进入uts命令空间。如果指定了file,则进入file的命令空间
- -i, --ipc[=file]:进入ipc命令空间。如果指定了file,则进入file的命令空间
- -n, --net[=file]:进入net命令空间。如果指定了file,则进入file的命令空间
- -p, --pid[=file]:进入pid命令空间。如果指定了file,则进入file的命令空间
- -U, --user[=file]:进入user命令空间。如果指定了file,则进入file的命令空间
- -G, --setgid gid:设置运行程序的gid
- -S, --setuid uid:设置运行程序的uid
- -r, --root[=directory]:设置根目录
- -w, --wd[=directory]:设置工作目录
如果没有给出program,则默认执行$SHELL。
3、示例
在 Linux 系统里,nsenter 是一个命令行工具,用于进入到另一个 namespace。
譬如,nsenter -n -t 1 bash 就是进入到 pid 为 1 的进程所在的网络 namespace 里。
如果不断的执行 nsenter 命令,就形成了一个 nsenter 套娃。
通过nsenter获取容器ip,可进行docker网络连通性测试
# 查看pid
docker inspect 354 -f '{{.State.Pid}}'
30354
# 执行nsenter命令
nsenter -n -t 30354
# 查看容器IP配置 ifconfig
eth0: flags=4163
<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:3 prefixlen 64 scopeid 0x20
<link>
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 656 (656.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73
<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# 退出
exit
# 物理机ip配置
docker0: flags=4163
<UP ,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
ether 02:42:de:5d:bb:55 txqueuelen 0 (Ethernet)
RX packets 2388 bytes 231674 (226.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2517 bytes 1687771 (1.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163
<UP ,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.27.0.9 netmask 255.255.240.0 broadcast 172.27.15.255
ether 52:54:00:ee:87:05 txqueuelen 1000 (Ethernet)
RX packets 11373521 bytes 1780959272 (1.6 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 11638601 bytes 3904021709 (3.6 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73
<UP ,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 785897 bytes 389858802 (371.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 785897 bytes 389858802 (371.7 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
veth5a433e9: flags=4163
<UP ,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 02:bd:5e:79:55:c6 txqueuelen 0 (Ethernet)
RX packets 1056 bytes 136666 (133.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1447 bytes 116315 (113.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
vethf366923: flags=4163
<UP ,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 5a:fc:ae:17:dc:a5 txqueuelen 0 (Ethernet)
RX packets 8 bytes 656 (656.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
4、关于 namespace
namespace是Linux中一些进程的属性的作用域,使用命名空间,可以隔离不同的进程。
Linux在不断的添加命名空间,目前有:
- mount:挂载命名空间,使进程有一个独立的挂载文件系统,始于Linux 2.4.19
- ipc:ipc命名空间,使进程有一个独立的ipc,包括消息队列,共享内存和信号量,始于Linux 2.6.19
- uts:uts命名空间,使进程有一个独立的hostname和domainname,始于Linux 2.6.19
- net:network命令空间,使进程有一个独立的网络栈,始于Linux 2.6.24
- pid:pid命名空间,使进程有一个独立的pid空间,始于Linux 2.6.24
- user:user命名空间,是进程有一个独立的user空间,始于Linux 2.6.23,结束于Linux 3.8
- cgroup:cgroup命名空间,使进程有一个独立的cgroup控制组,始于Linux 4.6
参考:https://staight.github.io/2019/09/23/nsenter%E5%91%BD%E4%BB%A4%E7%AE%80%E4%BB%8B/