Nsenter使用记录篇
介绍
nsenter是用来进入容器内部的一个命令,它的优势之处在于可以自己选择加载容器的那些namespaces
使用
$ nsenter --help
用法:
nsenter [options] <program> [<argument>...]
Run a program with namespaces of other processes.
选项:
-t, --target <pid> 要获取名字空间的目标进程
-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
-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 执行 <程序> 前不 fork
-Z, --follow-context set SELinux context according to --target PID
-h, --help 显示此帮助并退出
-V, --version 输出版本信息并退出
可以看到选项很多,但是大致上都是进入某个namespace
--mount 参数是进去到mount namespace中
--uts 参数是进入到uts namespace中
--ipc 参数是进入到System V IPC namaspace中
--net 参数是进入到network namespace中
--pid 参数是进入到pid namespace中
--user 参数是进入到user namespace中
在使用nsenter命令之前需要获取到docker容器的进程,然后再使用nsenter工具进去到docker容器中,具体的使用方法如下:
$ docker inspect -f {{.State.Pid}} 容器名或者容器id #查询容器的PID
$ nsenter -t 容器PID -m -u -i -n -p #输入该命令进入容器
在排查coredns问题时用到了此命令.Pod bash环境并没有curl命令,无法在容器内部使用curl命令来判断pod能否访问Kubernetes API,具体使用如下
nsenter -n -t $PID curl -kg -6 $URI
如果RUNC为Containerd不为docker 则可以使用 ps -ef来获取Pod PID
Example:
$ ps -ef | grep core
root 16557 16338 0 Sep12 ? 00:13:13 /coredns -conf /etc/coredns/Corefile
root 16706 16505 0 Sep12 ? 00:13:31 /coredns -conf /etc/coredns/Corefile
root 17347 17266 0 Sep12 ? 00:13:48 /coredns -conf /etc/coredns/Corefile
nsenter机制是使用哪个参数,就进入该进程的哪个namespce,不使用则使用宿主机的namespace。而-m是进入mount namespace的,这个名称空间是用来文件系统名称空间,所以当我们不加-m的时候,使用的是宿主机的文件系统,可以使用宿主机内的命令对容器进行问题的排查,当然你也可以选择使用宿主机的其他namespace来帮助你排查问题