进入到docker容器的命名空间
有时候容器内没有ifconfig、route等命令,给网络调试带来了很大的困难。我们知道,容器有自已的网络命名空间,所以我们只需要进入到容器的网络命名空间,再利用主机上的命令进行调试就可以了。
接下来给一个例子
准备
1、运行一个容器
$ docker run -itd --name nginx nginx:1.16.1 4ac2dc3735d6134112806667745cac916596132655c099499950d9307481166b
2、找到容器中PID为1的进程在root命名空间下的PID
$ docker inspect -f {{.State.Pid}} nginx 18809
我们可以在root命名空间下(即在主机的shell下),查看这个进程的相关信息
$ ps -ef | grep 18809 root 18809 18781 0 17:49 pts/0 00:00:00 nginx: master process nginx -g daemon off; 101 18854 18809 0 17:49 pts/0 00:00:00 nginx: worker process
3、nsenter命令如下
$ nsenter --help Usage: nsenter [options] [...] Run a program with namespaces of other processes. Options: -t, --target target process to get namespaces from -m, --mount[=] enter mount namespace -u, --uts[=] enter UTS namespace (hostname etc) -i, --ipc[=] enter System V IPC namespace -n, --net[=] enter network namespace -p, --pid[=] enter pid namespace -U, --user[=] enter user namespace -S, --setuid set uid in entered namespace -G, --setgid set gid in entered namespace --preserve-credentials do not touch uids or gids -r, --root[=] set the root directory -w, --wd[=] set the working directory -F, --no-fork do not fork before exec'ing -Z, --follow-context set SELinux context according to --target PID
进入网络命名空间
进入到PID为18809这个进程的网络命名空间
$ nsenter -t 18809 -n
然后,查看网络命名空间下的相关资源:网卡应该是容器内看到的网卡
$ ifconfig eth0: flags=4163 mtu 1500 inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet) RX packets 28 bytes 2152 (2.1 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
进入PID命名空间
先执行exit命令从上面的网络命名空间退出来,然后执行以下命令进行到PID命令空间
$ nsenter -t 18809 -p
我们查看PID命名空间下的相关资源,这里看到的进程应该只有容器内的进程
$ ps PID TTY TIME CMD 14377 pts/0 00:00:01 bash 18809 pts/0 00:00:00 nginx 52630 pts/0 00:00:00 nsenter 52631 pts/0 00:00:00 bash 52646 pts/0 00:00:00 ps
上面有点奇怪的是,PID没有显示为1,而且执行ps -ef
的话,会看到很多主机上很多其他的进程,暂时未明白原因
进入mount命名空间
先执行exit命令从上面的PID命名空间退出来,然后执行以下命令进行到mount命令空间
$ nsenter -t 18809 -m
然后我们ls发现,看到是的容器里面的文件,查看/etc/hostname
就是容器ID的前几位(就是docker ps看到的容器ID)
$ cat /etc/hostname 4ac2dc3735d6