解决容器中缺少命令问题

nsenter介绍

1.1.1 命令介绍

docker中,为了尽可能缩减镜像大小,常常不会包含一些常用的工具,类似ping,curl,tcpdump等,虽然精简了镜像,但如果我们需要在容器内部测试网络联通性时,没有这些工具就非常的头疼。其实容器内部和主机之间的网络环境是互相隔离的,处于独立的命名空间下,那如果能在主机上切换命名空间,就可以在主机上以容器的网络环境进行操作,就可以利用主机上的工具,利用这个思想,我们就能够实现不用进入容器内部也可以实现容器内部一样的环境。这种需求的工具就是我们今天要介绍的nsenter。

nsenter命令是一个可以在指定进程的命令空间下运行指定程序的命令。它位于util-linux包中。

格式:nsenter [options] [program [arguments]]
参数详情:options:-t, --target pid:指定被进入命名空间的目标进程的pid
-m, --mount[=file]:进入mount命令空间。如果指定了file,则进入file的命令空间
-u, --uts[=file]:进入uts命令空间。如果指定了file,则进入file的命令空间
-i, --ipc[=file]:进入ipc命令空间。如果指定了file,则进入file的命令空间
-n, --net[=file]:进入net命令空间。如果指定了file,则进入file的命令空间
-p, --pid[=file]:进入pid命令空间。如果指定了file,则进入file的命令空间
-U, --user[=file]:进入user命令空间。如果指定了file,则进入file的命令空间
-G, --setgid gid:设置运行程序的gid
-S, --setuid uid:设置运行程序的uid
-r, --root[=directory]:设置根目录
-w, --wd[=directory]:设置工作目录
如果没有给出program,则默认执行$SHELL。

很多时候我们需要知道容器内部解析的域名ip信息,如果没有这些工具,本来很简单的事就变得很麻烦,通过以下步骤就可以通过nsenter解决以上问题

1.1.2 使用方法
  1. 第一步获取容器的PID
// 方法一 根据容器名获取 引号加不加都可以
[root@VM-4 ~]# docker inspect nginx-app -f '{{.State.Pid}}'
23069
// 方法二 根据容器ID 也可以通过ContainerID
[root@VM-4 ~]# docker inspect 2c0b7246f4a1 -f '{{.State.Pid}}'
23069
  1. 第二步使用命令nsenter 进入空间
// 根据id进入空间
[root@VM-4 ~]# nsenter -n -t23069
// 这个时候我们就已经有了容器内部的环境,就可以利用宿主的ping 等工具查看容器内的信息了
[root@VM-4 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.2  netmask 255.255.255.192  broadcast 10.0.0.63
        ether 02:42:0a:00:00:02  txqueuelen 0  (Ethernet)
        RX packets 86  bytes 7827 (7.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 194  bytes 18401 (17.9 KiB)
        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 4  bytes 386 (386.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4  bytes 386 (386.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

nsenter -n -t23069 这个命令没有任何输出,通过ifconfig命令查看当前ip可以确定我们已经进入了容器的网络空间,这里的pid=23069的容器的ip是10.0.0.2,可以看到已经打印出来了。

这时候主机上的命令都可以使用,curl ping 等命令可以使用了

[root@VM-4 ~]# ping baidu.com
PING baidu.com (220.181.38.251) 56(84) bytes of data.
64 bytes from 220.181.38.251 (220.181.38.251): icmp_seq=1 ttl=48 time=29.0 ms
64 bytes from 220.181.38.251 (220.181.38.251): icmp_seq=2 ttl=48 time=29.1 ms
64 bytes from 220.181.38.251 (220.181.38.251): icmp_seq=3 ttl=48 time=29.1 ms
^C
--- baidu.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 29.074/29.121/29.186/0.202 ms
You have new mail in /var/spool/mail/root
[root@VM-4~]# curl baidu.com
<html>
<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">
</html>
  1. 第三步 退出,输入exit,回车即可
[root@VM-4 ~]# exit
logout
posted @ 2024-03-21 13:58  屈宏志  阅读(28)  评论(0编辑  收藏  举报