I have hundreds of containers in various software virtual switches. I would like to know if its possible to find out which vnet# belongs to which docker container. Right now, I am detecting that by watching syslog as each container gets created. In KVM, there is a command "virsh domiflist ", which is exactly what i'm looking for.
4 Answers
The iflink
of the container is the same as the ifindex
of the veth#
.
You can get the iflink
of the container as follows:
docker exec -it <container-name> bash -c 'cat /sys/class/net/eth0/iflink'
Say, that results in 12
, then grep
for that:
grep -l 12 /sys/class/net/veth*/ifindex
That will give a unique result, on my system:
/sys/class/net/veth11d4238/ifindex
Combine that in a script:
#!/bin/bash
for container in $(docker ps -q); do
iflink=`docker exec -it $container bash -c 'cat /sys/class/net/eth0/iflink'`
iflink=`echo $iflink|tr -d '\r'`
veth=`grep -l $iflink /sys/class/net/veth*/ifindex`
veth=`echo $veth|sed -e 's;^.*net/\(.*\)/ifindex$;\1;'`
echo $container:$veth
done
The script was written to be easy to follow.
Sample run:
$ docker ps -q
c4d8096eff43
34ac6e9f1e6e
d5a2aa5f3de3
$ sudo ./vethfinder
c4d8096eff43:veth11d4238
34ac6e9f1e6e:veth7d52cd1
d5a2aa5f3de3:vethe46073d
Reference: https://forums.docker.com/t/relationship-between-interface-vethxxxxx-and-container/12872/20
-
Thank you, but it for some reason doesn't always work. I have 50 containers, and the script above would return 1 or 2 blanks. When I look at the iflink value for both containers, they are not +1 from the value obtained from inside the container. Mar 2, 2017 at 6:20
-
This is a guess: It could be a timing issue. If containers are created too quickly after each other, then assigning the
iflink
values might get out of sync. The system might assign two consecutiveiflink
values to two containers, instead of alternating between the container and the system.– NZDMar 3, 2017 at 0:37 -
This is interesting, I create and run the containers in a for loop, the last container iflink is always very different. For example, the iflink from /sys/class/net/veth###/iflink returns 4205, but the container's /sys/class/eth0/iflink shows 4216 Mar 4, 2017 at 0:27
-
Beats me. I tried a few things: starting a bunch of containers, verified that
iflink
lines up nicely. Stopped a few containers and created a few new ones, verified thatiflink
still lines up nicely. I got 115 containers running and my highestiflink
was 244. How do you get to 4216?– NZDMar 5, 2017 at 5:39 -
1Since many containers don't have a bash-shell ready, I've changed
bash
tosh
in the first line of the for loop. Now it reads: iflink=docker exec -it $container sh -c 'cat /sys/class/net/eth0/iflink'
This works fine in all my containers.– MadMikeJan 15, 2018 at 15:03
searches for all interfaces in containers.
#!/bin/bash
for container in $(docker ps --format '{{.Names}}'); do
iflink=`docker exec -it $container bash -c 'cat /sys/class/net/eth*/iflink'`
for net in $iflink;do
net=`echo $net|tr -d '\r'`
veth=`grep -l $net /sys/class/net/veth*/ifindex`
veth=`echo $veth|sed -e 's;^.*net/\(.*\)/ifindex$;\1;'`
echo $container:$veth
done
done
I am using a different method, which seem to work just fine:
[root@kh1 ~]# docker inspect 6d48e279c5b8 --format '{{.State.Pid}}'
56316
[root@kh1 ~]#
[root@kh1 ~]# ip netns identify 56316
ns-56316
[root@kh1 ~]#
[root@kh1 ~]# ip netns list | grep ns-56316
ns-56316 (id: 6)
[root@kh1 ~]#
[root@kh1 ~]# ip link show | grep -B1 "link-netnsid 6"
330: veth1ce76e2b@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master cni0 state UP mode DEFAULT group default
link/ether de:f8:ce:a2:85:f9 brd ff:ff:ff:ff:ff:ff link-netnsid 6
Have a look here: https://stackoverflow.com/questions/37860936/find-out-which-network-interface-belongs-to-docker-container
There are examples of how one can fetch veth names for running docker containers without root access.
An example shell script can be found here: https://github.com/dicho-usp/dockerveth
#!/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;}')
-
2Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.– Community BotDec 16, 2021 at 13:18