【问题标题】:docker-compose: route traffic through vpn except for connections to other servicesdocker-compose:通过 vpn 路由流量,但与其他服务的连接除外
【发布时间】:2021-09-17 19:02:35
【问题描述】:

考虑这个 docker-compose 配置:

# docker-compose.yml
version: "3.7"

services:
  app:
    build: ./app
    depends_on:
      - db
      - vpn
    ports:
      - "3001:3000"
  db:
    image: postgres
  vpn:
    build: ./vpn
    cap_add:
      - NET_ADMIN

说明

  • app 是从 docker 主机通过 http://localhost:3001 访问的。
  • app 需要连接到 postgres db,这是第二个容器。
  • 另外,app 需要连接到 api,该 api 只能通过 vpn 使用。这就是为什么第三个容器 vpn 建立所需的 vpn 连接的原因。

目标

app 容器应该能够访问此 docker-compose 环境中的其他服务,即db,并通过vpn 容器路由其其余流量,以便它可以访问vpn隧道后面的api。

我尝试过的

  • 我尝试设置network_modeapp:

    services:
      app:
        network_mode: "service:vpn"
    

    这会通过vpn 路由app 容器的所有流量。有了这个,我可以从app容器到达vpn隧道后面的api。但这与ports: - "3001:3000" 不兼容。此外,无法再从app 访问db 容器:ping: bad address 'db'

  • 我还尝试从vpn 容器链接db 容器,希望这将使db 服务可用于app

    services:
      app:
        network_mode: "service:vpn"
      vpn:
        links:
          - db
    

    app 仍然找不到db

  • 如果我从vpn 容器链接db 容器但vpn 容器内建立vpn 连接,db 容器可以 > 从app 联系。

  • 并且我已经尝试将127.0.0.1 db 添加到app 容器的/etc/hosts,隐约希望我可以直接到达db 端口。但这也行不通。

有没有人知道如何做到这一点?

【问题讨论】:

    标签: docker-compose vpn docker-networking


    【解决方案1】:

    我终于找到了解决方案,但需要三个步骤:

    第一步:network_mode: service

    为了通过vpn路由app容器的所有流量,在app容器上设置network_mode

    services:
      app:
        network_mode: "service:vpn"
    

    第 2 步:DNS 服务器

    为了解析 vpn 隧道后面的主机名以及本地 docker 服务,vpn 容器需要与两个 DNS 服务器通信:隧道后面的 DNS 服务器以及 docker-compose DNS服务器。

    据我所知,docker-compose DNS 服务器始终为127.0.0.11

    要找出隧道背后的远程 DNS 服务器,请建立隧道,然后运行 ​​cat /etc/resolv.conf。这将在带有“by strongSwan”注释的行中列出隧道后面的 DNS 服务器。

    vpn容器的启动脚本中,将两台DNS服务器添加到vpn容器的resolv.conf

    # vpn-container startup script:
    echo "nameserver <remote dns server ip>" >> /etc/resolv.conf
    echo "nameserver 127.0.0.11" >> /etc/resolv.conf
    

    要对此进行测试,请登录vpn 容器并尝试ping 远程ip 和db 容器:

    docker-compose run vpn /bin/bash
    ping db  # should work
    ping <some-ip-behind-the-vpn-tunnel>  # should also work
    

    第三步:暴露端口

    据我所知,app 容器上有 network_mode: "service:vpn"app 容器不能再将其端口暴露给主机。相反,app 容器和 vpn 容器现在对 docker 主机显示为同一台机器。因此,可以改为在vpn 容器上公开所需的端口。

    services:
      vpn:
        ports:
          - "3001:3000"
    

    然后可以通过 docker 主机上的 http://localhost:3001 访问 app (!)。

    齐心协力:决赛docker-compose.yml

    # docker-compose.yml
    version: "3.7"
    
    services:
      app:
        build: ./app
        depends_on:
          - db
          - vpn
        network_mode: "service:vpn"
      db:
        image: postgres
      vpn:
        build: ./vpn
        cap_add:
          - NET_ADMIN
        ports:
          - "3001:3000"
        command: >
          bash -c "echo 'nameserver <remote dns server ip>' >> /etc/resolv.conf
          && echo 'nameserver 127.0.0.11' >> /etc/resolv.conf
          && ..."
    

    【讨论】:

      猜你喜欢
      • 2021-03-06
      • 2011-08-28
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 2020-11-05
      • 1970-01-01
      • 2014-10-10
      相关资源
      最近更新 更多