《跟唐老师学习云网络》 - nsenter魔法棒

举报
tsjsdbd 发表于 2023/06/21 18:46:42 2023/06/21
【摘要】 nsenter魔法棒,执行容器中没有安装的网络命令。

 有时候Docker容器中缺少需要的软件。比如 curlwgetifconfigiptcpdump 等基础软件包,什么都干不了,很是让人抓狂。

[root@tsjsdbd home]# docker exec -it 8402 /bin/bash

root@8402d89fe04a:/# ifconfig

bash: ifconfig: command not found

root@8402d89fe04a:/# ip

bash: ip: command not found

root@8402d89fe04a:/# tcpdump

bash: tcpdump: command not found

root@8402d89fe04a:/# curl

bash: curl: command not found

root@8402d89fe04a:/# nslookup

bash: nslookup: command not found

root@8402d89fe04a:/# wget

wget: missing URL

Usage: wget [OPTION]... [URL]...

面对这种容器镜像,定位问题就会很困难,因为你进入容器后,想执行命令还得重新安装各种基础软件,非常麻烦。

 

这个时候,我们要拿起“nsenter”这个根魔法棒,在主机上上面挥舞起来。

ns-enter,顾名思义,就是「进入各种namespace」,即nsenter命令可以进入到指定目标进程的ns视角。

所以nsenter可以站在指定进程的“视角”看世界,本文重点关注进入目标进程的“网络ns”视角,即站在「容器中的进程视角」看待容器里面的网络世界,并在那个视角中执行命令。

 

首先,我们要找到,要进入的「目标ns」的目标进程ID。即:容器里面的根进程

[root@tsjsdbd ubuntu]# docker inspect 8402d89fe04a

[

    {

        "Id": "8402d89fe04a7e161faf8a01a86c47f8402d4c8d7207b6897d8e6d661d670df4",

        "State": {

            "Status": "running",

            "Pid": 18751,

            "ExitCode": 0,

            "Error": "",

            "StartedAt": "2023-05-10T03:12:19.221460059Z",

            "FinishedAt": "0001-01-01T00:00:00Z"

        },

容器里的“老大”是进程18751号。

所以我们直接在Host主机上,跟踪这个进程,并进入它的“视角”,我们就可以看到容器里面的世界了。而且由于我们这个时候,作为控制者,还是处在Host主机上的,因此可以执行Host主机上的各种命令行。

如下:

[root@tsjsdbd ubuntu]# nsenter -t 18751 -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 1688355  bytes 194318903 (185.3 MiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 138826  bytes 146246172 (139.4 MiB)

        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 0  (Local Loopback)

        RX packets 13939  bytes 13140220 (12.5 MiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 13939  bytes 13140220 (12.5 MiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

其他命令,照搬都可以执行。

比如,容器里面没有nslookup命令,但是只有Host主机上有,咱就可在容器中执行它:

[root@tsjsdbd ubuntu]# nsenter -t 18751 -n nslookup www.baidu.com

Server:       10.129.2.34

Address:   10.129.2.34#53

 

Non-authoritative answer:

www.baidu.com canonical name = www.a.shifen.com.

Name:  www.a.shifen.com

Address: 14.119.104.254

Name:  www.a.shifen.com

Address: 14.119.104.189

所以原本在容器里面,无法执行的调试行为,就这么可以完成调试。

 

更直接的,如果不带最后的执行命令参数,可以直接进到“目标视角”里面去,进行交互式执行cli

[root@tsjsdbd ubuntu]# nsenter -t 18751 -n

#这里就进入交互模式,相当于没有填写cli时,默认执行[当前bash]

[root@tsjsdbd ubuntu]# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN

4261: eth0@if4262: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP

[root@tsjsdbd ubuntu]# curl

curl: try 'curl --help' or 'curl --manual' for more information

[root@tsjsdbd ubuntu]# tcpdump

listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

^C

0 packets captured

0 packets received by filter

0 packets dropped by kernel

[root@tsjsdbd ubuntu]# exit

#执行exit,可退出“目标视角”

可以看到,所有的网络相关的cli命令行都可以执行。

并且,这些命令,都是站在容器内的“视角”执行的,所以效果与在容器中是一样的(虽然它们本身在Host中发起的)。

类似电影《源代码》《骇客帝国》中那样,用外面世界中的“人”,去控制“里面世界”中的行为。希望可以理解这种上帝视角的逻辑:-)


 

总结用法:

1) 找到目标进程PID

docker inspect xxx

 

2)直接执行特定的cli命令

nsenter -n -t 822647 ifconfig

 

3)进入容器视角,进行交互式cli

nsenter -n -t 822647

exit

 

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。