在节点上进入docker容器的namespace

来自三线的随记

随记mark: to be continue

众所周知容器最大的特点之一在于他的namespace隔离

cgroup  ipc  mnt  net  pid  pid_for_children  user  uts

通常如果要debug容器的话会选择通过docker exec进去debug

network namespace

然而有的docker image没有我们需要的debug tool的话就会出现很尴尬的情况(常见于容器中没有 nc telnet ping nslookup dig等等网络连通性调试工具)

或者说有的docker image里面的debug tool非常坑爹

(是的,我就是在骂busybox 的nslookup [这玩意不能在command option中指定dns server address,指定了参数以后从结果来看你以为是指定了,其实是假的!])


这时候可以选择在容器的运行节点上进入容器的network namespace中进行 debug

Executing commands in the container network namespace Method 1

-> 利用ip netns命令

ip [-all] netns exec [ NAME ] cmd ... - Run cmd in the named network namespace

      This command allows applications that are network namespace unaware to be run in something other than the default network namespace with all of the
      configuration for the specified network namespace appearing in the customary global locations. A network namespace and bind mounts are used to move
      files from their network namespace specific location to their default locations without affecting other processes.

      If -all option was specified then cmd will be executed synchronously on the each named network namespace even if cmd fails on some of them. Network
      namespace name is printed on each cmd executing.

假设有一容器名为temp 先通过inspect命令获取其进程id值

[root@demo ~]# docker inspect temp|grep Pid\"
            "Pid": 1944847,

创建文件夹以供ip netns 获知namespace (这个文件夹系统一般不会自己创建,同时由于这个路径一般是挂载在内存中的,所以系统重启需要重新mkdir)

mkdir -p /var/run/netns

在netns目录下创建符号链接以便ip netns 可以识别到该pid使用的net namepace

ln -sf /proc/1944847/ns/net /var/run/netns/1944847

这时候使用list命令就可以看到该pid的net namespace信息

[root@demo ~]# ip netns list
1944847 (id: 1)

然后在该 namespace 中执行你所需要的命令即可

[root@demo ~]# ip netns exec 1944847 ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
4: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default  link-netnsid 0
    inet 172.29.41.195/32 brd 172.29.41.195 scope global eth0
       valid_lft forever preferred_lft forever
Related commands
ip netns attach NAME PID - create a new named network namespace

    If NAME is available in /var/run/netns/ this command attaches the network namespace of the process PID to NAME as if it were created with ip netns.


Executing commands in the container network namespace Method 2

-> 利用nsenter命令