簡體   English   中英

找出哪個網絡接口屬於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


來自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

方法的優點:

  • 容器內無需網絡工具,僅在 docker 節點上
  • 無需在容器和節點中搜索網絡設備之間的映射

缺點:

  • 您需要在節點/機器上擁有特權用戶才能運行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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM