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

Posted

技术标签:

【中文标题】docker-compose:指定哪个接口将连接到每个网络(当有多个网络时)【英文标题】:docker-compose: specify which interface will connect to each network (when having multiple networks) 【发布时间】:2017-08-13 01:41:47 【问题描述】:

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

我使用的一个容器,连接到所有 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"

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

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

您可以在下面看到此容器的ifconfig 输出。每次我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

编辑:

进一步阅读,github问题:

The order in which networks are assigned to interfaces does not match the order they are listed in compose file #4645 17.06 L4 ingress network not accessable #34003 Control interface name in docker multiple networking #25181

【问题讨论】:

您能告诉我们您的docker-compose.yml 中对应的services 条目吗? 我添加了我的 .yml 文件的一部分。 这与我尝试的非常相似,只是我希望编辑主机中的网络,并且我试图在主机上运行一个脚本。问题是:***.com/questions/43208979/… 【参考方案1】:

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

我能够重现您的行为。我认为这是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。让我们看看这是否会发生! 谢谢你!【参考方案2】:

您可以使用 Docker compose 参考中的 priority 属性来指定将网络附加到容器的顺序。

https://docs.docker.com/compose/compose-file/compose-file-v2/#priority

...

services:
  foo:
    image: foo:latest
    restart: always
    networks:
      network1:
        priority: 1000 # eth0
      network2:
        priority: 900 # eth1
      network3: # Default priority is 0, eth2

...

【讨论】:

谢谢!我去看看? 等待github.com/docker/cli/issues/1372 在 v3 中获得网络优先级支持【参考方案3】:

你可以尝试挂载配置文件

即对于基于 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"

【讨论】:

这与我的问题有关。 ***.com/questions/43208979/… 所以如果我以特权模式运行容器,我是否能够更改主机上的当前网络配置。如何确保它们在主机上生效,就好像我要在主机上调用 shell 例如: ifconfig eth0 10.0.0.100 netmask 255.255.255.0 或设置网关路由 add default gw 1​​0.0.0.1 eth0 对不起,垃圾邮件问题,如果我要与脚本共享一个卷,而不是将其映射到容器路径,例如: ./path_to_script.sh 在特权模式下,它会在主机上运行,还是在容器中?

以上是关于docker-compose:指定哪个接口将连接到每个网络(当有多个网络时)的主要内容,如果未能解决你的问题,请参考以下文章

XAMPP 将连接到启动页面,但没有其他链接可用

如何将连接到网络的所有IP地址保存在文本文件中

docker-compose编排最佳实战(多服务)

python 这将连接到Claymore矿工并获取统计数据并自动进行一些转换。将忽略任何次要硬币。

使用 docker-compose 连接到 RabbitMQ 容器

连接到本地 docker-compose 容器 Windows 10