12

我有 2 个 docker 容器,桥是这样的:

# docker ps
CONTAINER ID        IMAGE                                         COMMAND                CREATED             STATUS              PORTS                      NAMES
ef99087167cb        images.docker.sae.sina.com.cn/ubuntu:latest   /bin/bash -c /home/c   2 days ago          Up 21 minutes       0.0.0.0:49240->22223/tcp   night_leve3         
c8a7b18ec20d        images.docker.sae.sina.com.cn/ubuntu:latest   /bin/bash -c /home/c   2 days ago          Up 54 minutes       0.0.0.0:49239->22223/tcp   night_leve2 

#brctl show cbr0
bridge name bridge id       STP enabled interfaces
docker0     8000.72b675c52895   no      vethRQOy1I
                                        vethjKYWka

我怎样才能得到哪个容器匹配veth*

ef99 => vethRQOy1I or ef99 => vethjKYWka

//------------------------------------------------ ----------

我知道它的工作原理ethtool,但有没有更好的方法?

4

8 回答 8

15

这是上面提到的 ethtool 技巧的一个变体,没有实际使用 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}"
}
于 2015-02-19T17:57:01.227 回答
6
于 2014-02-14T18:28:42.210 回答
3

试试这个脚本:

get_network_mode() {
    docker inspect --format='{{.HostConfig.NetworkMode}}' "$1"
}


created_by_kubelet() {
    [[ $(docker inspect --format='{{.Name}}' "$1") =~ ^/k8s_ ]]
}


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',
    # but do NOT skip the container created by kubelet.
    if [[ "${network_mode}" == "host" || \
          $(! created_by_kubelet "${container_id}") && "${network_mode}" == "none" ]]; then
        echo "${container_id} => ${network_mode}"
        continue
    fi

    # 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:/}")
        # skip the containers whose network_mode is 'host' or 'none',
        # but do NOT skip the container created by kubelet.
        if [[ "${network_mode}" == "host" || \
              $(! created_by_kubelet "${container_id}") && "${network_mode}" == "none" ]]; then
            echo "${container_id} => ${network_mode}"
            continue 2
        fi
    done

    # 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 |grep -oP '(?<=eth0@if)\d+(?=:)')

    # get the 'name' of veth device in the 'docker0' bridge (or other name),
    # which is the peer of veth device in the container.
    veth_name=$(ip link show |sed -nr "s/^${veth_id}: *([^ ]*)@if.*/\1/p")

    echo "${container_id} => ${veth_name}"
done

解释:

  • 避免在container.
  • 避免创建临时文件夹和文件。
  • NetworkMode最重要的是host,避免为none, 或container:<name|id>(network stack与另一个容器共享。例如:kubernetesuser's中的一个容器与容器共享)的容器得到不正确的答案podnetwork stackpause podnetwork stack
于 2017-06-08T05:19:43.947 回答
1

如果还有人对此感兴趣。我在 docker 邮件列表中找到了这个:http: //permalink.gmane.org/gmane.comp.sysutils.docker.user/3182

您可以通过传递 lxc-conf 参数“lxc.network.veth.pair”自己定义 veth 的名称。例如:

docker run -rm -i -t --lxc-conf="lxc.network.veth.pair=foobar" ubuntu /bin/bash

创建一个带有名为“foobar”的 veth 接口的容器。

有关更方便的 lxc-conf 参数,请参阅此页面:http: //manpages.ubuntu.com/manpages/precise/man5/lxc.conf.5.html

于 2014-06-12T11:00:34.943 回答
1

据我所知,您需要与容器关联的虚拟网络设备吗?

您可以通过以下方式获得:

1:

docker exec -it <container> cat /sys/class/net/<physical-device>/iflink
# the output looks like this -> 20  

然后

2:

# ip ad | grep <the output, like 20>:
 ip ad | grep 20:
# the output looks, like this:
# 20: vetha5531eb@if19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-0595ab5d7c95 state UP group default qlen 1000
# where vetha5531eb is what I think you're looking for.
于 2021-05-20T12:19:14.480 回答
0

我不知道如何正确获取它,但是您使用 hack:您可以在运行容器后扫描 syslog 以查找添加的接口:

#!/bin/sh

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"
于 2014-02-13T05:04:25.043 回答
0

这只是 Joel Dice 在“2015 年 2 月 19 日”给出的答案的更新

原始代码(2015年有效)

# 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/"

结果是:

$ index=$(sudo ip netns exec "ns-4012085" ip link show eth0 | head -n1 | sed s/:.*//)
$ echo $index
3

$ let index=index+1
$ echo $index
4

$ sudo ip link show | grep "^${index}:" | sed "s/${index}: \(.*\):.*/\1/"
cbr0

然而 :

index=$(sudo ip netns exec "ns-4012085" ip link show type veth | grep eth0 | sed s/.*@if// | sed s/:.*// )
$ echo $index
14

$ ip link show | grep "^${index}:" | sed "s/${index}: \(.*\):.*/\1/"
veth240a8f81@if3

希望这会帮助某人。:)

PS我是从这个线程到这里的。

于 2020-06-04T12:45:49.100 回答
0
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
do
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)
echo "GEVONDEN $IPADDRESS MET NAAM : $NAME en INTERFACE: $FOUND" | grep NAAM
done < <(docker ps -a -q)
于 2015-08-03T11:44:31.047 回答