[英]Find out which network interface belongs to docker container
Docker creates these virtual ethernet interfaces veth[UNIQUE ID]
listed in ifconfig
. Docker 创建
ifconfig
列出的这些虚拟以太网接口veth[UNIQUE ID]
。 How can I find out which interface belongs to a specific docker container?如何找出哪个接口属于特定的 docker 容器?
I want to listen to the tcp traffic.我想听 tcp 流量。
To locate interface定位接口
In my case getting value from container was like (check eth0
to):在我的情况下,从容器中获取价值就像(检查
eth0
到):
$ docker exec -it my-container cat /sys/class/net/eth1/iflink
123
And then:然后:
$ ip ad | grep 123
123: vethd3234u4@if122: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default
Check with tcpdump -i vethd3234u4
检查
tcpdump -i vethd3234u4
Reference about mysterious iflink
from http://lxr.free-electrons.com/source/Documentation/ABI/testing/sysfs-class-net :来自http://lxr.free-electrons.com/source/Documentation/ABI/testing/sysfs-class-net 的关于神秘
iflink
参考:
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.
Based on the provided answer (which worked for me), I made this simple bash script:根据提供的答案(对我有用),我制作了这个简单的 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
My answer more like improvement on that important topic because it didn't help to " Find out which network interface belongs to docker container ", but, as author noticed, he " want to listen to the tcp traffic " inside docker container - I'll try to help on that one during your troubleshooting of network.我的回答更像是对这个重要主题的改进,因为它对“找出属于 docker 容器的网络接口”没有帮助,但是,正如作者所注意到的,他“想监听docker 容器内的 tcp 流量” - 我'在您对网络进行故障排除期间,我会尽力帮助解决这个问题。
Considering that veth network devices are about network namespaces, it is useful to know that we can execute program in another namespace via nsenter tool as follow (remember - you need a privileged permission (sudo/root) for doing that):考虑到veth网络设备是关于网络命名空间的,知道我们可以通过nsenter工具在另一个命名空间中执行程序如下(请记住 - 您需要特权权限(sudo / root)才能执行此操作)很有用:
Get ID of any container you are interested in capture the traffic, for example it will be 78334270b8f8
获取您有兴趣捕获流量的任何容器的 ID,例如它将是
78334270b8f8
Then we need to take PID
of that containerized application (I assume you are running only 1 network-related process inside container and want to capture its traffic. Otherwise, that approach is hard to be suitable):然后我们需要获取该容器化应用程序的
PID
(我假设您在容器内仅运行 1 个与网络相关的进程并希望捕获其流量。否则,这种方法很难适用):
sudo docker inspect 78334270b8f8 | grep -i pid
For example, output for pid
will be 111380
- that's ID of your containerized app, you can check also it via ps
command: ps aux | grep 111380
例如,
pid
输出将是111380
- 这是您的容器化应用程序的 ID,您也可以通过ps
命令检查它: ps aux | grep 111380
ps aux | grep 111380
just in curiosity. ps aux | grep 111380
只是出于好奇。
Next step is to check what network interfaces you have inside your container:下一步是检查您的容器内有哪些网络接口:
sudo nsenter -t 111380 -n ifconfig
This command will return you list of network devices in network namespace of the containerized app (you should not have ifconfig
tool on board of your container, only on your node/machine)此命令将返回容器化应用程序网络命名空间中的网络设备列表(您的容器上不应有
ifconfig
工具,只能在您的节点/机器上)
For example, you need to capture traffic on interface eth2
and filter it to tcp destination port 80 (it may vary of course) with this command:例如,您需要使用以下命令捕获接口
eth2
上的流量并将其过滤到 tcp 目标端口 80(当然可能会有所不同):
sudo nsenter -t 111380 -n tcpdump -nni eth2 -w nginx_tcpdump_test.pcap 'tcp dst port 80'
Remember, that in this case you do not need tcpdump
tool to be installed inside your container.请记住,在这种情况下,您不需要在容器内安装
tcpdump
工具。
Then, after capturing packets, .pcap
file will be available on your machine/node and to read it use any tool you prefer tcpdump -r nginx_tcpdump_test.pcap
然后,在捕获数据包后,
.pcap
文件将在您的机器/节点上可用并使用您喜欢的任何工具读取它tcpdump -r nginx_tcpdump_test.pcap
approach's pros:方法的优点:
cons:缺点:
nsenter
toolnsenter
工具One-liner of the solution from @pbaranski来自@pbaranski 的单行解决方案
num=$(docker exec -i my-container cat /sys/class/net/eth0/iflink | tr -d '\r'); ip ad | grep -oE "^${num}: veth[^@]+" | awk '{print $2}'
If you need to find out on a container that does not include cat
then try this tool: https://github.com/micahculpepper/dockerveth如果您需要查找不包含
cat
的容器,请尝试使用此工具: https : //github.com/micahculpepper/dockerveth
You can also read the interface names via /proc/PID/net/igmp like (container name as argument 1):您还可以通过 /proc/PID/net/igmp 读取接口名称,例如(容器名称作为参数 1):
#!/bin/bash
NAME=$1
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.*/\1/p")
echo -e "$NAME\t$iface\t$veth"
done < <(</proc/$PID/net/igmp awk '/^[0-9]+/{print $2 " " $1;}')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.