docker: how to get veth bridge interface pair easily?

i have 2 containers by docker, and bridge like this:

root@venus-166:~# docker ps
CONTAINER ID        IMAGE                                         COMMAND                CREATED             STATUS              PORTS                      NAMES
ef99087167cb   /bin/bash -c /home/c   2 days ago          Up 21 minutes>22223/tcp   night_leve3         
c8a7b18ec20d   /bin/bash -c /home/c   2 days ago          Up 54 minutes>22223/tcp   night_leve2 

bridge name bridge id       STP enabled interfaces
docker0     8000.72b675c52895   no      vethRQOy1I

How can i get which container match veth* ?

  • gcloud preview app setup-managed-vms gives errors - 500 Server Error: Internal Server Error
  • Sed cannot find file while building Docker image
  • How can I get access to tools for debugging, etc., in a docker container?
  • Could not locate Gemfile error by docker compose up
  • How to link docker images to their composing layers on the disk?
  • controlling docker-machine (using NAT) outgoing port
  • ef99 => vethRQOy1I or ef99 => vethjKYWka


    I know it works by ethtool, but is there any better way?

  • volume not getting mounted in nginx container
  • Collect UDP(Gelf) messages and forward with TCP to logstash
  • Jhipster-Logstash does not start correctly
  • Which Tensorflow Docker image to use?
  • bash syntax error while running docker command
  • how to execute docker commands through Java program
  • 6 Solutions collect form web for “docker: how to get veth bridge interface pair easily?”

    Here’s a variation on the ethtool trick mentioned above, without actually using ethtool:

    function veth_interface_for_container() {
      # Get the process ID for the container named ${1}:
      local pid=$(docker inspect -f '{{.State.Pid}}' "${1}")
      # Make the container's network namespace available to the ip-netns command:
      mkdir -p /var/run/netns
      ln -sf /proc/$pid/ns/net "/var/run/netns/${1}"
      # Get the interface index of the container's eth0:
      local index=$(ip netns exec "${1}" ip link show eth0 | head -n1 | sed s/:.*//)
      # Increment the index to determine the veth index, which we assume is
      # always one greater than the container's index:
      let index=index+1
      # Write the name of the veth interface to stdout:
      ip link show | grep "^${index}:" | sed "s/${index}: \(.*\):.*/\1/"
      # Clean up the netns symlink, since we don't need it anymore
      rm -f "/var/run/netns/${1}"

    There are multiple “hackish” ways to do it:

    • scan kernel logs, as mentioned by Jiri (but you have to do it right after starting the container, otherwise it gets messy);
    • check the interface counters (sent/received packets/bytes) in the container, then compare with the interfaces in the host, and find the pair that matches exactly (but with sent and receive directions flipped);
    • use an iptables LOG rule.

    The last option is, IMHO, the more reliable one (and the easiest to use), but it’s still very hackish. The idea is very simple:

    1. Add an iptables rule to log e.g. ICMP traffic arriving on the Docker bridge:

      sudo iptables -I INPUT -i docker0 -p icmp -j LOG

    2. Send a ping to the container you want to identify:

      IPADDR=$(docker inspect -format='{{.NetworkSettings.IPAddress}}' 0c33)

      ping -c 1 $IPADDR

    3. Check kernel logs:

      dmesg | grep $IPADDR

      You will see a line looking like this:

      […] IN=docker0 OUT= PHYSIN=vethv94jPK MAC=fe:2c:7f:2c:ab:3f:42:83:95:74:0b:8f:08:00 SRC= …

      If you want to be fancy, just extract PHYSIN=… with awk or sed.

    4. Remove the iptables logging rule (unless you want to leave it there because you will regularly ping containers to identify them).

    If you need a bullet-proof version, you can install ulogd and use the ULOG target. Instead of just writing packet headers to the kernel log, it will send them through a netlink socket, and a userland program can then process them properly.

    If anyone is still interested in this. I found this on the docker mailing list:

    You can define the name of the veth yourself by passing the lxc-conf parameter “”. E.g.:

    docker run -rm -i -t –lxc-conf=”” ubuntu /bin/bash

    Creates a container with a veth interface named “foobar”.

    See this page for more handy lxc-conf parameters:

    I don’t know how to get it properly, but you use a hack: you can scan the syslog for added interfaces after you run your container:

    JOB=$(sudo docker run -d ...)
    sleep 1s
    INTERFACE=$(grep "docker0: port" /var/log/syslog | tail -n 1 |  sed -r s/^.*\(veth[^\)]+\).*$/\\1/)
    echo "job: $JOB interface: $INTERFACE"
    dmesg --clear
    for i in $(docker inspect $(docker ps -a -q) | grep IPAddress | cut -d\" -f4); do ping -c 1 -w 1 $i >/dev/null; done
    while read line
    IPADDRESS=$(docker inspect $line | grep IPAddress | cut -d\" -f4)
    NAME=$(docker inspect $line | grep Name | cut -d/ -f2 | cut -d\" -f1)
    FOUND=$(dmesg | grep $IPADDRESS | grep -Po 'vet[A-Za-z0-9]+' | sort -u)
    done < <(docker ps -a -q)

    Try this script:

    get_network_mode() {
        docker inspect --format='{{.HostConfig.NetworkMode}}' "$1"
    for container_id in $(docker ps -q); do
        network_mode=$(get_network_mode "${container_id}")
        # skip the containers whose network_mode is 'host' or 'none'.
        if [[ "${network_mode}" = "host" || "${network_mode}" = "none" ]]; then
        # if one container's network_mode is 'other container',
        # then get its root parent container's network_mode.
        while grep container <<< "${network_mode}" -q; do
            network_mode=$(get_network_mode "${network_mode/container:/}")
            # if one of its parent container's network_mode is 'host' or 'none'
            # then skip the current container.
            if [[ "${network_mode}" = "host" || "${network_mode}" = "none" ]]; then
                 continue 2
        # get current container's 'container_id'.
        pid=$(docker inspect --format='{{.State.Pid}}' "${container_id}")
        # get the 'id' of veth device in the container.
        veth_id=$(nsenter -t "${pid}" -n ip link show eth0 |sed -nr 's/.*eth0@if([0-9]+).*/\1/p')
        # get the 'name' of veth device in the 'docker0' bridge,
        # which is the peer of veth device in the container.
        veth_name=$(ip link show |sed -nr "/^${veth_id}/s/.*(veth.*)@if.*/\1/p")
        echo "${container_id} => ${veth_name}"


    • avoid to execute commands in container.
    • avoid to create temporary folders and files.
    • MOST importantly, avoid to get incorrect answers for containers whose NetworkMode is host, none, or container:<name|id> (share network stack with another container’s. For example: user's containers in one pod in kubernetes share the network stack with the pause pod container’s network stack)
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.