注:本文基于K8S v1.21.2版本编写

1、关于nsenter

nsenter就是namespace enter的意思,它可以进入到目标程序所在的namespace中,因此可以用来调试容器程序。我们都知道目前存在的几个namespace,比如网络,用户,pid等,nsenter都有对应的参数可以指定,从而进入该namespace,

[root@master ~]# nsenter -h

Usage:
 nsenter [options] <program> [<argument>...]

Run a program with namespaces of other processes.

Options:
 -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
 -U, --user[=<file>]    enter user namespace
...

2 常用场景

对于容器中有bash程序的场景,我们通过exec的方式就能进入容器内部,此时并不需要nsenter,但是对于那些没有bash程序的,就没法通过exec进入容器了,比如我们尝试进入coredns容器,

[root@master ~]# kubectl exec -it -n kube-system coredns-74747c454d-w57p8 -- /bin/bash
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "/bin/bash": stat /bin/bash: no such file or directory: unknown
command terminated with exit code 126

这个时候nsenter就派上用场了,因为bash不存在,也就是文件系统层面的隔离导致的,我们可以不进入这个namespace,

[root@master ~]# docker ps | grep coredns |grep -v pause
87c9da4bff1d   296a6d5035e2             "/coredns -conf /etc…"   3 days ago     Up 3 days               k8s_coredns_coredns-74747c454d-sshdk_kube-system_19246bc7-5c13-40b4-afbc-72a7b2fc687a_8
3dc5c132293d   296a6d5035e2             "/coredns -conf /etc…"   3 days ago     Up 3 days               k8s_coredns_coredns-74747c454d-8dttx_kube-system_de4a127f-811e-48d2-a22e-5de060a88c7c_8
b2aa0928b3d9   296a6d5035e2             "/coredns -conf /etc…"   3 days ago     Up 3 days               k8s_coredns_coredns-74747c454d-w57p8_kube-system_17ce6713-101a-4df2-a520-5c52563c5d0f_8
[root@master ~]# docker inspect --format "{{.State.Pid}}" 87c9da4bff1d
5157
[root@master ~]# nsenter -u -n -p -t 5157
[root@coredns-74747c454d-sshdk ~]# hostname
coredns-74747c454d-sshdk
[root@coredns-74747c454d-sshdk ~]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480
        inet 10.244.219.73  netmask 255.255.255.255  broadcast 10.244.219.73
        ether 02:5e:0f:ac:5b:94  txqueuelen 0  (Ethernet)
        RX packets 78006  bytes 7194976 (6.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 78337  bytes 7492525 (7.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

我们首先通过docker inspect获得对应容器的pid,然后通过nsenter进入utc、net、和pid namespace,这样我们就能使用宿主机的调试工具,比如tcpdump,ip等命令。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐