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

21

docker-compose.yaml文件中,我定义了4个不同的网络:

networks:
  vpp-nw:
  vpp-client:
  vpp-server:
  vpp-db:

分别使用以下网络地址:

172.20.0.x
172.21.0.x
172.22.0.x
172.23.0.x

我使用的其中一个容器连接了所有四个网络 (按照相同的顺序):

# 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"
有没有一种方法来定义哪个接口将连接到每个网络?例如,我想要:
  • eth0连接到第一个(vpp-nw)
  • eth1连接到第二个(vpp-client)
  • eth2连接到第三个(vpp-server)
  • eth3连接到第四个(vpp-db)

下面是此容器的ifconfig输出。每次我docker-compose down|docker-compose up时,NICs似乎会以任意方式连接到每个网络...

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

编辑:

更多阅读和Github问题:


你能展示一下你的 docker-compose.yml 文件中相应的 services 条目吗? - larsks
我添加了我的.yml文件的一部分。 - tgogos
这与我尝试的非常相似,只是我希望在主机上编辑网络,并尝试在compose up上运行在主机上运行的脚本。问题是:https://dev59.com/vVgQ5IYBdhLWcg3wLQuW - Ilhicas
3个回答

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:

并且这个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

您可以快速验证问题:

$ 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 ... 

此外,这个问题似乎只出现在docker-compose上;如果您使用docker run创建一个Docker容器,然后附加多个网络,它们总是按顺序分配到接口上,就像您所期望的那样。测试脚本如下:
#!/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

我在 GitHub 上开了一个问题 4645。让我们看看会有什么进展! - larsks
谢谢你,larsks! - tgogos

3

谢谢!我会去查看的。 - tgogos
2
正在等待 https://github.com/docker/cli/issues/1372 中的网络优先级支持在v3中实现。 - pd40

1
你可以尝试挂载配置文件,例如针对基于 RH 的镜像:
/etc/sysconfig/network-scripts/ifcfg-eth0

所以,你的yml文件看起来应该像下面这样:

# 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
    volumes:
     - ./conf/eth0:/etc/sysconfig/network-scripts/ifcfg-eth0
     - ./conf/eth1:/etc/sysconfig/network-scripts/ifcfg-eth1
     - ./conf/eth2:/etc/sysconfig/network-scripts/ifcfg-eth2
     - ./conf/eth3:/etc/sysconfig/network-scripts/ifcfg-eth3
    ports:
      - "8888:8888"

这与我的问题有关。https://dev59.com/vVgQ5IYBdhLWcg3wLQuW因此,如果我以特权模式运行容器,我能否更改主机上的当前网络配置。如何确保它们在主机上生效,就像我在主机上调用shell一样:ifconfig eth0 10.0.0.100 netmask 255.255.255.0或设置网关route add default gw 10.0.0.1 eth0 - Ilhicas
抱歉问题有点多,如果我想与脚本共享一个卷,而不将其映射到容器路径, 例如: 在特权模式下运行./path_to_script.sh,它会在主机上运行还是在容器中运行? - Ilhicas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接