nsenter
nsenter 命令是一个可以在指定进程的命令空间下运行指定程序的命令,它位于 util-linux 包中。通过 nsenter 命令可以极大方便容器网络等场景的调试,本文将介绍其原理与使用。
用途
一个最典型的用途就是进入容器的网络命令空间。相当多的容器为了轻量级,是不包含较为基础的命令的,比如说ip address,ping,telnet,ss,tcpdump等等命令,这就给调试容器网络带来相当大的困扰:只能通过docker inspect ContainerID命令获取到容器 IP,以及无法测试和其他网络的连通性。这时就可以使用 nsenter 命令仅进入该容器的网络命名空间,使用宿主机的命令调试容器网络。
此外,nsenter 也可以进入 mnt, uts, ipc, pid, user 命令空间,以及指定根目录和工作目录。
使用
首先看下 nsenter 命令的语法:
|
|
示例,在节点上有一个 coredns 的容器,可以看到 Pod IP 为 9.166.64.132,查看该容器的 pid
|
|
然后,使用 nsenter 命令进入该容器的网络命令空间,可以看到容器内部 IP 为 9.166.64.132,符合预期。
|
|
原理
关于 Linux Namespace 可以阅读我之前的博文,此处主要介绍 nsenter 的原理。
setns
clone 用于创建新的命令空间,而 setns 则用来让当前线程(单线程即进程)加入一个命名空间。
语法:
|
|
因此,往往该函数的用法为:
- 调用 setns 函数:指定该线程的命名空间。
- 调用 execvp 函数:执行指定路径的程序,创建子进程并替换父进程。
这样,就可以指定命名空间运行新的程序了。
代码示例:
|
|
使用示例:
|
|
nsenter
那么,最后就是 nsenter 了,nsenter 相当于在 setns 的示例程序之上做了一层封装,使我们无需指定命名空间的文件描述符,而是指定进程号即可。
指定进程号 PID 以及需要进入的命名空间后,nsenter 会帮我们找到对应的命名空间文件描述符/proc/PID/ns/FD,然后使用该命名空间运行新的程序。
参考文档
-
No backlinks found.