进入到docker容器的命名空间

2023年 9月 22日 61.7k 0

有时候容器内没有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

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论