【问题标题】:Use docker container as network gateway使用 docker 容器作为网络网关
【发布时间】:2023-03-30 18:12:01
【问题描述】:

我想配置一个网关来连接两个容器。下面是一个示例 compose 文件,它创建了三个容器——一个 test_client、一个 test_server 和一个代理。代理服务器应充当从 test_client 到 test_server 的所有流量的默认网关。我正在使用 compose 文件格式 v2,因为 v3 不支持 IPAM 网关配置。

version: "2"
services:
  proxy:
    build: .
    cap_add:
      - NET_ADMIN
    expose:
      - 8080
      - 80
      - 443
    networks:
      client_network:
          ipv4_address: '192.168.0.5'
      server_network: null
    stdin_open: true
    tty: true
  test_server:
    build: ./test_server
    expose:
      - 8000
    networks:
      - server_network
  test_client:
    build: ./test_client
    networks:
      - client_network
    stdin_open: true
    tty: true

networks:
  client_network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: "192.168.0.0/24"
          gateway: "192.168.0.5"
  server_network:
    driver: bridge

当我运行docker-compose up 时,我收到以下错误:

ERROR: for 28e458cec9ac_network_proxy_1  b'user specified IP address is supported only when connecting to networks with user configured subnets'

我已阅读以下资源:

SO: docker container as gateway between two docker bridges Docker forums

但他们似乎没有帮助我回答我是如何获得这个设置的。我不致力于任何特定的网络结构 - 我唯一想要的就是配置一个容器充当其他两个容器之间的网络级网关的东西。

【问题讨论】:

  • 好吧,我真的不确定这一点,但考虑到你的 docker-compose 文件中唯一的网络是“用户指定的”,因为你明确定义了它,你的问题可能吗?是您正在使用主机网络已使用的子网吗?也许切换到192.168.5.0/24 看看它是否改变了什么?
  • 遇到了同样的问题。您的 docker-compose 文件对我来说看起来不错。我猜,您尝试在没有子网配置的情况下创建内容,现在 docker 不会将网络配置更新为指定子网的配置...请检查 docker network inspect client_network。如果是这种情况,请不要使用“docker network rm”将其删除,否则您会破坏很多东西(刚刚发现很难),似乎您应该通过 docker-compose down 删除网络......请参阅:github.com/docker/compose/issues/5745#issuecomment-370031631 (这个没测试过,选错方式了)

标签: docker docker-compose docker-networking


【解决方案1】:

不幸的是,桥接网络(或任何其他类型的 docker 网络)并不真正支持此用例。问题是桥接网络使用您的主机作为网关。它通过在桥接网络上为您的主机创建一个虚拟接口并进行一些主机配置来实现必要的路由来实现这一点。 gateway 选项仅配置将分配给此虚拟接口的 IP 地址。

这似乎没有很好的记录,我认为它被认为是 docker 网络的实现细节。我是从几个论坛帖子中发现的:source 1source 2

编辑:这是我的工作 docker-compose 文件。这有两个专用网络,每个都有自己的网关,即alice <-> moon <-> sun <-> bob。神奇之处在于每个容器运行的command: 块内的ipiptables 命令。忽略tail -f /dev/null,它只是一个永远不会完成的命令,这意味着容器会一直运行直到你杀死它。

version: "3.3"

services:

  alice:
    image: ubuntu-with-tools
    cap_add:
      - NET_ADMIN
    hostname: alice
    networks:
      moon-internal:
        ipv4_address: 172.28.0.3
    command: >-
      sh -c "ip route del default &&
      ip route add default via 172.28.0.2 &&
      tail -f /dev/null"

  moon:
    image: ubuntu-with-tools
    cap_add:
      - NET_ADMIN
    hostname: moon
    networks:
      moon-internal:
        ipv4_address: 172.28.0.2
      internet:
        ipv4_address: 172.30.0.2
    command: >-
      sh -c "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE &&
      iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE &&
      iptables -A FORWARD -i eth1 -j ACCEPT &&
      iptables -A FORWARD -i eth0 -j ACCEPT &&
      ip route add 172.29.0.0/16 via 172.30.0.4 &&
      tail -f /dev/null"


  sun:
    image: ubuntu-with-tools
    cap_add:
      - NET_ADMIN
    hostname: sun
    networks:
      sun-internal:
        ipv4_address: 172.29.0.4
      internet:
        ipv4_address: 172.30.0.4
    command: >-
      sh -c "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE &&
      iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE &&
      iptables -A FORWARD -i eth1 -j ACCEPT &&
      iptables -A FORWARD -i eth0 -j ACCEPT &&
      ip route add 172.28.0.0/16 via 172.30.0.2 &&
      tail -f /dev/null"

  bob:
    image: ubuntu-with-tools
    cap_add:
      - NET_ADMIN
    hostname: bob
    networks:
      sun-internal:
        ipv4_address: 172.29.0.5
    command: >-
      sh -c "ip route del default &&
      ip route add default via 172.29.0.4 &&
      tail -f /dev/null"


networks:
  moon-internal:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16
  sun-internal:
    driver: bridge
    ipam:
      config:
        - subnet: 172.29.0.0/16
  internet:
    driver: bridge
    ipam:
      config:
        - subnet: 172.30.0.0/16

要试用它,请运行 docker exec -it ipsec-playground_bob_1 tcpdumpdocker exec -it ipsec-playground_alice_1 ping 172.29.0.5。您应该会看到来自 alice 的 ping 信号到达 bob。

ubuntu-with-tools 是一个简单的 ubuntu 映像,其中包含我想要安装的一些东西,这里是 Dockerfile:

FROM ubuntu
RUN apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y iproute2 inetutils-ping curl host mtr-tiny tcpdump iptables \
    && rm -rf /var/lib/apt/lists/*

【讨论】:

  • 这看起来棒极了!谢谢。我在这方面工作了一段时间,但希望很快有机会对其进行测试。试一试后,我会将其标记为已接受的答案。
猜你喜欢
  • 1970-01-01
  • 2018-11-18
  • 2017-12-03
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多