我有一个通过 VPN 容器 (vpn) 连接到 Internet 的应用程序容器 (app)。虽然该连接有效,但应用容器现在无法连接到数据库容器 (db)。
有没有办法让 app
容器连接到本地容器(或任何 RFC1918 地址),同时还通过 vpn
连接?我会简单地将 db
添加到同一个 network_mode
中,但是 db
非常特别需要被另一个未通过 vpn
连接的容器访问(第二个应用程序将从db
).
VPN 容器正在运行 bubuntux/nordvpn
,我的 docker-compose.yml 如下:
version: "3.9"
services:
app:
build: app/
depends_on:
- db
network_mode: service:vpn
depends_on:
- vpn
db:
image: postgres:alpine
restart: always
network_mode: service:vpn
environment:
POSTGRES_USER: PASSWORD
POSTGRES_PASSWORD: PASSWORD
POSTGRES_DB: PASSWORD
vpn:
image: bubuntux/nordvpn
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.conf.all.rp_filter=2
devices:
- /dev/net/tun
environment:
- USER=EMAIL@EMAIL.COM
- "PASS=PASSWORD"
- CONNECT=United_States
- TECHNOLOGY=NordLynx
ulimits:
memlock:
soft: -1
hard: -1
我尝试使用 link
,如下所示:
app:
links:
- db
但是,我收到启动错误,特别是 container type network can't be used with links.
重申这个问题:如何将容器通过 VPN 容器(在本例中为 bubuntux/nordvpn)连接到互联网,该容器也可由非 VPN 连接的容器访问?
谢谢!
答案 0 :(得分:0)
根据 documentation,这应该有效:
version: "3.9"
services:
app:
build: app/
links:
- vpn:db
depends_on:
- db
db:
image: postgres:alpine
depends_on:
- vpn
restart: always
network_mode: service:vpn
environment:
POSTGRES_USER: PASSWORD
POSTGRES_PASSWORD: PASSWORD
POSTGRES_DB: PASSWORD
vpn:
image: bubuntux/nordvpn
network_mode: bridge
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.conf.all.rp_filter=2
devices:
- /dev/net/tun
environment:
- USER=EMAIL@EMAIL.COM
- "PASS=PASSWORD"
- CONNECT=United_States
- TECHNOLOGY=NordLynx
ulimits:
memlock:
soft: -1
hard: -1
ports:
- 5432:5432
你应该从你的机器上访问 localhost:5432 的 postgres
更新:
我做这个模拟是因为我无法访问付费的 nordvpn acciut,所以 vpn 服务只是一个休眠 36000 秒的 ubuntu 并且 db 服务正在使用该网络,但是这样我不知道什么是真正的vpn 服务在具有这些附加功能(NET_ADMIN、SYS_MODULE)的主机上执行,但请尝试尝试此设置。
使用此设置应用程序服务(即 adminer,db admin gui)正在侦听我的机器 localhost:8080,我可以登录它并使其连接到具有主机名 db(服务器名称设置为gui) 正在侦听其默认的 5432 postgres 端口。此外,我可以从我的机器 localhost:54320 地址访问 postgres,因为它被转发到应用服务 5432 端口,该端口与使用 vpn 服务网络的 db 服务使用相同的网络,这可能意味着使用 nordvpn 网络。< /p>
version: "3"
services:
app:
image: adminer
restart: always
ports:
- 8080:8080
- 54320:5432
links:
- vpn:db
depends_on:
- db
db:
image: postgres:alpine
depends_on:
- vpn
restart: always
network_mode: service:vpn
environment:
- POSTGRES_USER=root
- POSTGRES_PASSWORD=root
- POSTGRES_DB=mydb
vpn:
image: ubuntu
command: ["/bin/sh","-c","echo started && sleep 36000"]
答案 1 :(得分:0)
这里的问题是 network_mode: service:$name
的工作原理:
它创建了从您的 app
服务到您的 vpn
服务的隐式依赖关系,因此 docker-compose
将首先启动 vpn
容器并连接其自己的网络命名空间和虚拟网络接口到虚拟网络(在本例中为 <project>_default
创建的 docker_compose
网络)。
然后它将启动app
容器与vpn
服务具有相同的网络命名空间,即localhost
容器中的vpn
是与 localhost
容器中的 app
相同 - 到目前为止,这实际上是您想要的。
现在,由于您也在 network_mode: service:vpn
服务上设置了 db
,它也将添加到相同的网络命名空间 - 这不是 strong> 您想要什么,因为容器现在无法通过 DNS 作为 db
被发现,因为它附加到 vpn
的网络命名空间而不是它自己的命名空间。
通过以下方式之一实现您想要的:
network_mode: service:vpn
中删除 db
,这样服务将获得自己的网络命名空间/内部 IP 地址,可以通过 DNS 解析 - 即您可以使用“db
”作为数据库连接的主机名localhost
”作为数据库连接的主机名,因为 app
和 db
共享相同的网络命名空间,即 localhost
是指一样对于第一个选项,docker-compose.yml
将如下所示:
version: "3.9"
services:
app:
build: app/
depends_on:
- db
network_mode: service:vpn
db:
image: postgres:alpine
restart: always
environment:
POSTGRES_USER: PASSWORD
POSTGRES_PASSWORD: PASSWORD
POSTGRES_DB: PASSWORD
vpn:
image: bubuntux/nordvpn
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.conf.all.rp_filter=2
devices:
- /dev/net/tun
environment:
- USER=EMAIL@EMAIL.COM
- "PASS=PASSWORD"
- CONNECT=United_States
- TECHNOLOGY=NordLynx
ulimits:
memlock:
soft: -1
hard: -1
另请注意:
links
已弃用,不应用于新应用程序depends_on
将确保依赖服务在依赖服务之前启动 - 但它不是 必需 DNS 解析工作,因此您可以省略它aliases
有关更多信息,请参阅 Networking in Compose。
答案 2 :(得分:0)
当您在 network_mode: service:vpn
的配置中使用 app
时,app
和 vpn
服务似乎运行在同一个容器网络中(具体来说,它们在相同的网络命名空间)。它们共享接口、路由规则、端口等。值得注意的是,它们还共享 /etc/resolv.conf
和 /etc/hosts
。由于 links
只是将相关条目添加到 /etc/hosts
,您可以通过(违反直觉)将 app
链接添加到 db
链接到 db
{1}} 项服务。
尝试以下配置:
vpn