为了简单和概括而编辑问题,因为我找到了答案。
我正在尝试将 Gluetun VPN 容器合并到我现有的应用程序中,该应用程序可以执行大量网络繁重的任务。我想连接一个容器(例如特定的队列工作人员)以仅使用 VPN 执行单个任务,从而大大提高可靠性。我在弄清楚它的网络方面以及如何做到这一点时遇到了很多麻烦,因为当您使用
network_mode: service:gluetun"
将容器连接到 Gluetun 时,它会失去 docker-compose 的 DNS 功能以及解析其他服务名称的能力,从而连接到 Redis 容器或数据库容器等时出现应用程序错误。
我希望现有的网络保持原样,只有特定容器使用 VPN 进行外部连接,而其他容器则像往常一样使用主机服务器的网络。如何解决这个问题并以这种方式设置?
有两种方法可以解决这个问题,但只有一种方法可以按照我想要的方式解决它。
为了完全解决我的问题,我最终给了我的依赖服务一个静态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.
这是我在搜索时最常找到的标准答案。该方法包括:
network_mode: "service:gluetun"
至所有服务基本上,这将所有服务视为在单个主机(即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 地址),仅通过端口来区分服务。