在 Docker Compose 中将 Gluetun VPN 与单个容器结合使用,同时仍访问相关服务

问题描述 投票:0回答:1

为了简单和概括而编辑问题,因为我找到了答案。

我正在尝试将 Gluetun VPN 容器合并到我现有的应用程序中,该应用程序可以执行大量网络繁重的任务。我想连接一个容器(例如特定的队列工作人员)以仅使用 VPN 执行单个任务,从而大大提高可靠性。我在弄清楚它的网络方面以及如何做到这一点时遇到了很多麻烦,因为当您使用

network_mode: service:gluetun"
将容器连接到 Gluetun 时,它会失去 docker-compose 的 DNS 功能以及解析其他服务名称的能力,从而连接到 Redis 容器或数据库容器等时出现应用程序错误。

我希望现有的网络保持原样,只有特定容器使用 VPN 进行外部连接,而其他容器则像往常一样使用主机服务器的网络。如何解决这个问题并以这种方式设置?

docker networking docker-compose redis vpn
1个回答
0
投票

有两种方法可以解决这个问题,但只有一种方法可以按照我想要的方式解决它。

最好的方法

为了完全解决我的问题,我最终给了我的依赖服务一个静态IP,并使用

extra_hosts:
Docker-compose 标签将这些服务添加到gluetun容器的/etc/hosts文件中,这允许gluetun容器解析服务名称,其他容器使用 Docker 的 DNS。我还将
FIREWALL_OUTBOUND_SUBNETS
环境变量添加到与网络具有相同子网的gluetun 容器中。我不能 100% 确定是否需要这样做,但我是根据帮助我解决答案的评论这样做的,并且它有效。这是 docker-compose 文件:

version: '3'
services:
  redis-service:
    image: redis
    ports:
    - "6379:6379"
    networks:
      primary-network:
        ipv4_address: 172.10.0.2 # Static IP address for service in subnet 

  default-queue-service:
    image: queue
    depends_on:
      - redis-service
    environment:
      CONTAINER_ROLE: Default-Queue-worker
    networks:
      - "primary-network" # Uses primary network, External requests use host/server

  vpn-queue-service:
    image: queue
    depends_on:
      - redis-service
    environment:
      CONTAINER_ROLE: VPN-Queue-worker
    network_mode: "service:gluetun" # Uses Gluetun's network, external requests use VPN

  gluetun-service:
    image: qmcgaw/gluetun
    hostname: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - 8888:8888/tcp # HTTP proxy
      - 8388:8388/tcp # Shadowsocks
      - 8388:8388/udp # Shadowsocks
#    volumes:
#      - /yourpath:/gluetun
    environment:
      # See https://github.com/qdm12/gluetun-wiki/tree/main/setup#setup
      - VPN_SERVICE_PROVIDER=<PROVIDER>
      - VPN_TYPE=openvpn
      # OpenVPN:
      - OPENVPN_USER=<REDACTED>
      - OPENVPN_PASSWORD=<REDACTED>
      # Wireguard:
      # - WIREGUARD_PRIVATE_KEY=<REDACTED>
      # - WIREGUARD_ADDRESSES=<REDACTED>
      # Timezone for accurate log times
      - TZ=
      # Server list updater
      # See https://github.com/qdm12/gluetun-wiki/blob/main/setup/servers.md#update-the-vpn-servers-list
      - UPDATER_PERIOD=
      - SERVER_COUNTRIES=
      - SERVER_REGIONS=
      - FIREWALL_OUTBOUND_SUBNETS=172.10.0.0/16 # Required for accessing subnet ips (i think)
    depends_on:
      - redis-service
    extra_hosts:
      - "redis-service:172.10.0.2" # Adds redis-service now static ip to gluetun's /etc/hosts for name resolution instead of DNS
    networks:
      - "primary-network" # Gluetun needs to be on the same network as other services
networks:
  primary-network:
    ipam:
      config:
        - subnet: 172.10.0.0/16 # Defined static subnet ip. Make sure other docker networks do not conflict or it will error.

其他方式

这是我在搜索时最常找到的标准答案。该方法包括:

  1. 连接
    network_mode: "service:gluetun"
    至所有服务
  2. 将所有端口映射从服务移至gluetun容器中。
  3. 将应用程序环境主机名变量从“redis-service”更改为“localhost”或“127.0.0.1”

基本上,这将所有服务视为在单个主机(即gluetun容器)上运行,因此所有服务都位于同一本地主机上,并且可以通过每个服务各自的端口进行访问。这很有效,但是所有容器的外部流量都通过 VPN。如果这就是您想要的,那很好,但如果您像我一样只想拥有一条集装箱路线,那就不行了。这也更具侵入性,因为它需要主机名的应用程序级别环境变量更改。在这种情况下,您不需要定义显式网络。这里的 docker-compose 文件是:

version: '3'
services:
  redis-service:
    image: redis
    depends_on:
    - gluetun
    network_mode: "service:gluetun" # Uses Gluetun container's network
# NOTE ports cannot be defined here when using network_mode, Must define ports in the gluetun service instead.

  default-queue-service:
    image: queue
    depends_on:
      - redis-service
    environment:
      CONTAINER_ROLE: Default-Queue-worker
      REDIS_HOST: localhost # This would be defined in your app env file
    network_mode: "service:gluetun" # Uses Gluetun container's network, External requests use VPN

  vpn-queue-service:
    image: queue
    depends_on:
      - redis-service
    environment:
      CONTAINER_ROLE: VPN-Queue-worker
      REDIS_HOST: localhost # This would be defined in your app env file
    network_mode: "service:gluetun" # Uses Gluetun container's network, External requests use VPN

  gluetun-service:
    image: qmcgaw/gluetun
    hostname: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - 8888:8888/tcp # HTTP proxy
      - 8388:8388/tcp # Shadowsocks
      - 8388:8388/udp # Shadowsocks
      - "6379:6379" # Redis , Redis Container uses Gluetun container's network so ports must be defined here, Cannot be defined in service.
#    volumes:
#      - /yourpath:/gluetun
    environment:
      # See https://github.com/qdm12/gluetun-wiki/tree/main/setup#setup
      - VPN_SERVICE_PROVIDER=<PROVIDER>
      - VPN_TYPE=openvpn
      # OpenVPN:
      - OPENVPN_USER=<REDACTED>
      - OPENVPN_PASSWORD=<REDACTED>
      # Wireguard:
      # - WIREGUARD_PRIVATE_KEY=<REDACTED>
      # - WIREGUARD_ADDRESSES=<REDACTED>
      # Timezone for accurate log times
      - TZ=
      # Server list updater
      # See https://github.com/qdm12/gluetun-wiki/blob/main/setup/servers.md#update-the-vpn-servers-list
      - UPDATER_PERIOD=
      - SERVER_COUNTRIES=
      - SERVER_REGIONS=

这里,两个队列worker都使用VPN网络进行外部请求(所有服务网络模式定义为gluetun服务,包括依赖服务Redis),因此除了应用程序级别之外,它们之间没有任何区别。这些服务可以通过本地主机访问 Redis,因为它们都在同一网络上(所有容器都使用相同的 IP 地址),仅通过端口来区分服务。

© www.soinside.com 2019 - 2024. All rights reserved.