docker-compose:指定哪个接口将连接到每个网络(当有多个网络时)

tgo*_*gos 10 networking nic docker docker-compose

docker-compose.yaml我在里面定义了4个不同的网络:

networks:
  vpp-nw:
  vpp-client:
  vpp-server:
  vpp-db:
Run Code Online (Sandbox Code Playgroud)

它分别使用以下网络地址:

172.20.0.x
172.21.0.x
172.22.0.x
172.23.0.x
Run Code Online (Sandbox Code Playgroud)

我使用的其中一个容器连接到所有4个网络(具有相同的顺序):

# part of docker-compose.yaml

services:
  my_tool:
    build: ./my_tool
    image: tgogos/my_tool
    container_name: my_tool_docker_comp
    hostname: my_tool
    privileged: true
    links:
      - my_db
    networks:
      - vpp-nw
      - vpp-client
      - vpp-server
      - vpp-db
    ports:
      - "8888:8888"
Run Code Online (Sandbox Code Playgroud)

有没有办法定义哪个接口将连接到每个网络?例如,我想:

  • eth0 连接到第一个(vpp-nw)
  • eth1 连接到第二个(vpp-client)
  • eth2 连接到第三个(vpp-server)
  • eth3 连接到第四个(vpp-db)

您可以在下面看到ifconfig此容器的输出.每次I docker-compose down|时,NIC似乎都以任意方式连接到每个网络 docker-compose up...

eth0  Link encap:Ethernet  HWaddr 02:42:ac:15:00:03  
      inet addr:172.21.0.3  Bcast:0.0.0.0  Mask:255.255.0.0

eth1  Link encap:Ethernet  HWaddr 02:42:ac:17:00:03  
      inet addr:172.23.0.3  Bcast:0.0.0.0  Mask:255.255.0.0

eth2  Link encap:Ethernet  HWaddr 02:42:ac:14:00:02  
      inet addr:172.20.0.2  Bcast:0.0.0.0  Mask:255.255.0.0

eth3  Link encap:Ethernet  HWaddr 02:42:ac:16:00:03  
      inet addr:172.22.0.3  Bcast:0.0.0.0  Mask:255.255.0.0
Run Code Online (Sandbox Code Playgroud)

编辑:

进一步阅读,github问题:

lar*_*sks 5

这不是答案,而是对您所报告的行为以及可用于提交错误报告的完整重现器的确认。

我能够重现你的行为。我认为这是一个错误docker-compose,因为networks您的服务的密钥是一个有序列表。我希望网络按照文件中列出的顺序分配给接口。

使用它docker-compose.yml(在名为 的目录中nwtest):

version: "2"

services:
  server:
    image: alpine
    command: sleep 999
    networks:
      - nw0
      - nw1
      - nw2
      - nw3

networks:
  nw0:
  nw1:
  nw2:
  nw3:
Run Code Online (Sandbox Code Playgroud)

这个 shell 脚本:

#!/bin/sh

docker-compose up -d

for nw in 0 1 2 3; do
    nw_cidr=$(docker network inspect -f '{{ (index .IPAM.Config 0).Subnet }}' \
        nwtest_nw${nw})
    if_cidr=$(docker exec -it nwtest_server_1 ip addr show eth${nw} |
        awk '$1 == "inet" {print $2}')

    nw_net=$(ipcalc -n $nw_cidr | cut -f2 -d=)
    if_net=$(ipcalc -n $if_cidr | cut -f2 -d=)

    echo "nw${nw} $nw_net eth${nw} ${if_net}"

    if [ "$if_net" != "$nw_net" ]; then
        echo "MISMATCH: nw${nw} = $nw_net, eth${nw} = $if_net" >&2
    fi
done

docker-compose stop
Run Code Online (Sandbox Code Playgroud)

您可以快速验证问题:

$ sh runtest.sh 
Starting nwtest_server_1
nw0 192.168.32.0 eth0 192.168.32.0
nw1 192.168.48.0 eth1 192.168.48.0
nw2 192.168.64.0 eth2 192.168.80.0
MISMATCH: nw2 = 192.168.64.0, eth2 = 192.168.80.0
nw3 192.168.80.0 eth3 192.168.64.0
MISMATCH: nw3 = 192.168.80.0, eth3 = 192.168.64.0
Stopping nwtest_server_1 ... 
Run Code Online (Sandbox Code Playgroud)

此外,这个问题似乎特定于docker-compose;如果您使用多个网络创建 Docker 容器docker run,然后附加多个网络,它们总是会按照您的预期按顺序分配给接口。其测试脚本是:

#!/bin/sh

docker rm -f nwtest_server_1
docker run -d --name nwtest_server_1 --network nwtest_nw0 \
    alpine sleep 999

for nw in 1 2 3; do
    docker network connect nwtest_nw${nw} nwtest_server_1
done

for nw in 0 1 2 3; do
    nw_cidr=$(docker network inspect -f '{{ (index .IPAM.Config 0).Subnet }}' \
        nwtest_nw${nw})
    if_cidr=$(docker exec -it nwtest_server_1 ip addr show eth${nw} |
        awk '$1 == "inet" {print $2}')

    nw_net=$(ipcalc -n $nw_cidr | cut -f2 -d=)
    if_net=$(ipcalc -n $if_cidr | cut -f2 -d=)

    echo "nw${nw} $nw_net eth${nw} ${if_net}"

    if [ "$if_net" != "$nw_net" ]; then
        echo "MISMATCH: nw${nw} = $nw_net, eth${nw} = $if_net" >&2
    fi
done

docker rm -f nwtest_server_1
Run Code Online (Sandbox Code Playgroud)