多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
有时候容器内没有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] <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 -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 do not fork before exec'ing <program> -Z, --follow-context set SELinux context according to --target PID ``` ## **进入网络命名空间** 进入到PID为18809这个进程的网络命名空间 ``` $ nsenter -t 18809 -n ``` 然后,查看网络命名空间下的相关资源:网卡应该是容器内看到的网卡 ``` $ ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> 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<UP,LOOPBACK,RUNNING> 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 ```