Nsenter 调取宿主机工具调试容器内程序

nsenter 是一个可以用来进入到目标程序所在 Namespace 中运行命令的工具,一般常用于在宿主机上调试容器中运行的程序。

nsenter 安装
nsenter 位于 util-linux 包中,一般常用的 Linux 发行版都已经默认安装。如果你的系统没有安装,可以使用以下命令进行安装:

nsenter 用途
一个比较典型的用途就是进入容器的网络命名空间。通常容器为了轻量级,大多都是不包含较为基础网络管理调试工具,比如:ip、ping、telnet、ss、tcpdump 等命令,给调试容器内网络带来相当大的困扰。

nsenter 命令可以很方便的进入指定容器的网络命名空间,使用宿主机的命令调试容器网络。

除此以外,nsenter 还可以进入 mnt、uts、ipc、pid、user 等命名空间,以及指定根目录和工作目录。

nsenter 用法
首先看下 nsenter 命令的语法:

$ yum install util-linux
如果没有给出 program,则默认执行 $SHELL。最常用的参数组合是:

$ nsenter [options] [program [arguments]]

options:

-a, --all enter all namespaces of the target process by the default /proc/[pid]/ns/* namespace paths.
-m, --mount[=]:进入 mount 命令空间。如果指定了 file,则进入 file 的命名空间
-u, --uts[=]:进入 UTS 命名空间。如果指定了 file,则进入 file 的命名空间
-i, --ipc[=]:进入 System V IPC 命名空间。如果指定了 file,则进入 file 的命名空间
-n, --net[=]:进入 net 命名空间。如果指定了 file,则进入 file 的命名空间
-p, --pid[=:进入 pid 命名空间。如果指定了 file,则进入 file 的命名空间
-U, --user[=:进入 user 命名空间。如果指定了 file,则进入 file 的命名空间
-t, --target # 指定被进入命名空间的目标进程的 pid
-G, --setgid gid:设置运行程序的 GID
-S, --setuid uid:设置运行程序的 UID
-r, --root[=directory]:设置根目录
-w, --wd[=directory]:设置工作目录
nsenter 使用实例
进入 docker 容器的 namespace 中运行指定程序
使用 nsenter 进入 docker 容器的 namespace 是非常简单的,通常你只需要以下两步:

有的版本不一定有 -a 这个参数

$ nsenter -a -t
$ nsenter -m -u -i -n -p -t
下面我们来看几个实例:

进入指定程序所在的所有命名空间

获取相应的 Dokcer 容器的 PID

$ PID=$(docker inspect --format {{.State.Pid}} )

使用相应参数进入程序所在的不同 NameSpace

$ nsenter -m -u -i -n -p -t $PID
进入指定程序所在的网络命名空间
运行一个 Nginx 容器,查看该容器的 Pid:

$ docker run --rm --name test -d busybox sleep 10000
8115009baccc53a2a5f6dfff642e0d8ab1dfb95dde473d14fb9a06ce4e89364c

$ docker ps |grep busybox
8115009baccc busybox “sleep 10000” 9 seconds ago Up 8 seconds test

$ PID=$(docker inspect --format {{.State.Pid}} 8115009baccc)

$ nsenter -m -u -i -n -p -t $PID ps aux
PID USER TIME COMMAND
1 root 0:00 sleep 10000
7 root 0:00 ps aux

$ nsenter -m -u -i -n -p -t $PID hostname
8115009baccc
然后,使用 nsenter 命令进入该容器的网络命令空间:

$ docker inspect -f {{.State.Pid}} nginx
进入 Kubernetes 容器的 namespace 中运行指定程序
如果是在 Kubernetes 中,在得到容器 Pid 之前,你还需先获取容器的 ID,可以使用如下命令获取:

$ nsenter -n -t5645
$ ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
18: eth0@if19: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
或者更为精确地获取 containerID:

$ kubectl get pod nginx -n web -o yaml|grep containerID

  • containerID: docker://cf0873782d587dbca6aa32f49605229da3748600a9926e85b36916141597ec85
    其它的步骤就和前面进入 Docker 容器的命名空间类似了。

参考文档

  1. https://www.googgle.com
  2. https://staight.github.io/2019/09/23/nsenter%E5%91%BD%E4%BB%A4%E7%AE%80%E4%BB%8B/
  3. https://mozillazg.com/2020/04/nsenter-usage.html

你可能感兴趣的:(linux,运维,服务器)