[英]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
來自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.
根據提供的答案(對我有用),我制作了這個簡單的 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網絡設備是關於網絡命名空間的,知道我們可以通過nsenter工具在另一個命名空間中執行程序如下(請記住 - 您需要特權權限(sudo / root)才能執行此操作)很有用:
獲取您有興趣捕獲流量的任何容器的 ID,例如它將是78334270b8f8
然后我們需要獲取該容器化應用程序的PID
(我假設您在容器內僅運行 1 個與網絡相關的進程並希望捕獲其流量。否則,這種方法很難適用):
sudo docker inspect 78334270b8f8 | grep -i pid
例如, pid
輸出將是111380
- 這是您的容器化應用程序的 ID,您也可以通過ps
命令檢查它: ps aux | grep 111380
ps aux | grep 111380
只是出於好奇。
下一步是檢查您的容器內有哪些網絡接口:
sudo nsenter -t 111380 -n ifconfig
此命令將返回容器化應用程序網絡命名空間中的網絡設備列表(您的容器上不應有ifconfig
工具,只能在您的節點/機器上)
例如,您需要使用以下命令捕獲接口eth2
上的流量並將其過濾到 tcp 目標端口 80(當然可能會有所不同):
sudo nsenter -t 111380 -n tcpdump -nni eth2 -w nginx_tcpdump_test.pcap 'tcp dst port 80'
請記住,在這種情況下,您不需要在容器內安裝tcpdump
工具。
然后,在捕獲數據包后, .pcap
文件將在您的機器/節點上可用並使用您喜歡的任何工具讀取它tcpdump -r nginx_tcpdump_test.pcap
方法的優點:
缺點:
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 $2}'
如果您需要查找不包含cat
的容器,請嘗試使用此工具: https : //github.com/micahculpepper/dockerveth
您還可以通過 /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.