找出哪个网络接口属于 docker 容器
Find out which network interface belongs to docker container
Docker 创建 ifconfig
中列出的这些虚拟以太网接口 veth[UNIQUE ID]
。我如何找出哪个接口属于特定的 docker 容器?
我想监听 tcp 流量。
定位接口
在我的例子中,从容器中获取价值就像(检查 eth0
到):
$ docker exec -it my-container cat /sys/class/net/eth1/iflink
123
然后:
$ ip ad | grep 123
123: vethd3234u4@if122: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default
检查tcpdump -i vethd3234u4
关于神秘 iflink
的参考来自 http://lxr.free-electrons.com/source/Documentation/ABI/testing/sysfs-class-net:
150 What: /sys/class/net/<iface>/iflink
151 Date: April 2005
152 KernelVersion: 2.6.12
153 Contact: netdev@vger.kernel.org
154 Description:
155 Indicates the system-wide interface unique index identifier a
156 the interface is linked to. Format is decimal. This attribute is
157 used to resolve interfaces chaining, linking and stacking.
158 Physical interfaces have the same 'ifindex' and 'iflink' values.
根据提供的答案(对我有用),我制作了这个简单的 bash 脚本:
#!/bin/bash
export containers=$(sudo docker ps --format "{{.ID}}|{{.Names}}")
export interfaces=$(sudo ip ad);
for x in $containers
do
export name=$(echo "$x" |cut -d '|' -f 2);
export id=$(echo "$x"|cut -d '|' -f 1)
export ifaceNum="$(echo $(sudo docker exec -it "$id" cat /sys/class/net/eth0/iflink) | sed s/[^0-9]*//g):"
export ifaceStr=$( echo "$interfaces" | grep $ifaceNum | cut -d ':' -f 2 | cut -d '@' -f 1);
echo -e "$name: $ifaceStr";
done
我的回答更像是对该重要主题的改进,因为它无助于“找出哪个网络接口属于 docker 容器”,但是,作为作者注意到,他“想监听 docker 容器内的 tcp 流量 ” - 我会在您对网络进行故障排除时尽力提供帮助。
考虑到 veth network devices are about network namespaces, it is useful to know that we can execute program in another namespace via nsenter 工具如下(记住 - 您需要特权权限 (sudo/root) 才能这样做):
获取您对捕获流量感兴趣的任何容器的 ID,例如它将是 78334270b8f8
然后我们需要获取该容器化应用程序的 PID
(我假设您 运行 在容器内只有 1 个与网络相关的进程并希望捕获其流量。否则,该方法是很难合适):
sudo docker inspect 78334270b8f8 | grep -i pid
例如,pid
的输出将是 111380
- 这是容器化应用程序的 ID,您也可以通过 ps
命令检查它:ps aux | grep 111380
就在好奇.
下一步是检查容器中有哪些网络接口:
sudo nsenter -t 111380 -n ifconfig
此命令将 return 您在容器化应用程序的网络命名空间中列出网络设备(您的容器不应该有 ifconfig
工具,只能在您的 node/machine )
例如,您需要使用以下命令捕获接口 eth2
上的流量并将其过滤到 tcp 目标端口 80(当然可能有所不同):
sudo nsenter -t 111380 -n tcpdump -nni eth2 -w nginx_tcpdump_test.pcap 'tcp dst port 80'
请记住,在这种情况下,您不需要在容器中安装 tcpdump
工具。
然后,在捕获数据包后,.pcap
文件将在您的 machine/node 上可用,并使用您喜欢的任何工具读取它 tcpdump -r nginx_tcpdump_test.pcap
方法的优点:
- 容器内不需要网络工具,只在docker节点上
- 无需在容器和节点中搜索网络设备之间的映射
缺点:
- 您需要拥有 node/machine 到 运行
nsenter
工具 的特权用户
来自@pbaranski 的解决方案的一行
num=$(docker exec -i my-container cat /sys/class/net/eth0/iflink | tr -d '\r'); ip ad | grep -oE "^${num}: veth[^@]+" | awk '{print }'
如果您需要在不包含 cat
的容器上查找,请尝试使用此工具:https://github.com/micahculpepper/dockerveth
您还可以通过 /proc/PID/net/igmp 读取接口名称,例如(容器名称作为参数 1):
#!/bin/bash
NAME=
PID=$(docker inspect $NAME --format "{{.State.Pid}}")
while read iface id; do
[[ "$iface" == lo ]] && continue
veth=$(ip -br addr | sed -nre "s/(veth.*)@if$id.*//p")
echo -e "$NAME\t$iface\t$veth"
done < <(</proc/$PID/net/igmp awk '/^[0-9]+/{print " " ;}')
Docker 创建 ifconfig
中列出的这些虚拟以太网接口 veth[UNIQUE ID]
。我如何找出哪个接口属于特定的 docker 容器?
我想监听 tcp 流量。
定位接口
在我的例子中,从容器中获取价值就像(检查 eth0
到):
$ docker exec -it my-container cat /sys/class/net/eth1/iflink
123
然后:
$ ip ad | grep 123
123: vethd3234u4@if122: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default
检查tcpdump -i vethd3234u4
关于神秘 iflink
的参考来自 http://lxr.free-electrons.com/source/Documentation/ABI/testing/sysfs-class-net:
150 What: /sys/class/net/<iface>/iflink
151 Date: April 2005
152 KernelVersion: 2.6.12
153 Contact: netdev@vger.kernel.org
154 Description:
155 Indicates the system-wide interface unique index identifier a
156 the interface is linked to. Format is decimal. This attribute is
157 used to resolve interfaces chaining, linking and stacking.
158 Physical interfaces have the same 'ifindex' and 'iflink' values.
根据提供的答案(对我有用),我制作了这个简单的 bash 脚本:
#!/bin/bash
export containers=$(sudo docker ps --format "{{.ID}}|{{.Names}}")
export interfaces=$(sudo ip ad);
for x in $containers
do
export name=$(echo "$x" |cut -d '|' -f 2);
export id=$(echo "$x"|cut -d '|' -f 1)
export ifaceNum="$(echo $(sudo docker exec -it "$id" cat /sys/class/net/eth0/iflink) | sed s/[^0-9]*//g):"
export ifaceStr=$( echo "$interfaces" | grep $ifaceNum | cut -d ':' -f 2 | cut -d '@' -f 1);
echo -e "$name: $ifaceStr";
done
我的回答更像是对该重要主题的改进,因为它无助于“找出哪个网络接口属于 docker 容器”,但是,作为作者注意到,他“想监听 docker 容器内的 tcp 流量 ” - 我会在您对网络进行故障排除时尽力提供帮助。
考虑到 veth network devices are about network namespaces, it is useful to know that we can execute program in another namespace via nsenter 工具如下(记住 - 您需要特权权限 (sudo/root) 才能这样做):
获取您对捕获流量感兴趣的任何容器的 ID,例如它将是 78334270b8f8
然后我们需要获取该容器化应用程序的 PID
(我假设您 运行 在容器内只有 1 个与网络相关的进程并希望捕获其流量。否则,该方法是很难合适):
sudo docker inspect 78334270b8f8 | grep -i pid
例如,pid
的输出将是 111380
- 这是容器化应用程序的 ID,您也可以通过 ps
命令检查它:ps aux | grep 111380
就在好奇.
下一步是检查容器中有哪些网络接口:
sudo nsenter -t 111380 -n ifconfig
此命令将 return 您在容器化应用程序的网络命名空间中列出网络设备(您的容器不应该有 ifconfig
工具,只能在您的 node/machine )
例如,您需要使用以下命令捕获接口 eth2
上的流量并将其过滤到 tcp 目标端口 80(当然可能有所不同):
sudo nsenter -t 111380 -n tcpdump -nni eth2 -w nginx_tcpdump_test.pcap 'tcp dst port 80'
请记住,在这种情况下,您不需要在容器中安装 tcpdump
工具。
然后,在捕获数据包后,.pcap
文件将在您的 machine/node 上可用,并使用您喜欢的任何工具读取它 tcpdump -r nginx_tcpdump_test.pcap
方法的优点:
- 容器内不需要网络工具,只在docker节点上
- 无需在容器和节点中搜索网络设备之间的映射
缺点:
- 您需要拥有 node/machine 到 运行
nsenter
工具 的特权用户
来自@pbaranski 的解决方案的一行
num=$(docker exec -i my-container cat /sys/class/net/eth0/iflink | tr -d '\r'); ip ad | grep -oE "^${num}: veth[^@]+" | awk '{print }'
如果您需要在不包含 cat
的容器上查找,请尝试使用此工具:https://github.com/micahculpepper/dockerveth
您还可以通过 /proc/PID/net/igmp 读取接口名称,例如(容器名称作为参数 1):
#!/bin/bash
NAME=
PID=$(docker inspect $NAME --format "{{.State.Pid}}")
while read iface id; do
[[ "$iface" == lo ]] && continue
veth=$(ip -br addr | sed -nre "s/(veth.*)@if$id.*//p")
echo -e "$NAME\t$iface\t$veth"
done < <(</proc/$PID/net/igmp awk '/^[0-9]+/{print " " ;}')