考虑这个 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
描述
- 通过 http://localhost:3001 从 docker 主机访问
app
。 app
需要连接到 postgresdb
,这是第二个容器。- 另外,
app
需要连接到一个 api,它只能通过 vpn 访问。这就是第三个容器vpn
建立所需 vpn 连接的原因。
目标
app
容器应该能够访问此 docker-compose 环境中的其他服务,即 db
,并通过 vpn
容器,这样它就可以访问vpn隧道后面的api。
我尝试过的
我已尝试设置
app
的network_mode
:services: app: network_mode: "service:vpn"
这会通过
vpn
路由app
容器的所有流量。这样,我就可以从app
容器访问 vpn 隧道后面的 api。但这与ports: - "3001:3000"
不兼容。此外,db
容器无法再从app
访问:ping: bad address 'db'
。我还尝试从
vpn
容器链接db
容器,希望这将使db
服务可用到应用
。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
端口。但这也行不通。
有没有人知道如何实现这一点?
最佳答案
我终于找到了解决方案,但它需要三个步骤:
第 1 步:网络模式:服务
为了通过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
&& ..."
关于docker-compose:通过 vpn 路由流量,但与其他服务的连接除外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69228372/