docker-compose中如何实现app流量走VPN且可访问同环境其他服务
解决方案
核心问题原因
你之前遇到的问题本质是两点:
- 当
app使用network_mode: service:vpn共享网络栈时,端口映射仅对网络栈所属的vpn服务生效,app自身的ports配置会被Docker忽略 - VPN客户端启动后默认会覆盖容器的DNS配置为VPN侧DNS,同时修改默认路由让所有流量走VPN隧道,导致Docker内网服务名无法解析、同栈服务的访问流量被导到VPN侧无法到达。
最终配置方案
第一步:修改docker-compose.yml配置
# docker-compose.yml version: "3.7" services: app: build: ./app depends_on: - db - vpn network_mode: "service:vpn" # 保留共享vpn网络栈 db: image: postgres vpn: build: ./vpn cap_add: - NET_ADMIN ports: - "3001:3000" # 端口映射移到vpn服务下 dns: - 127.0.0.11 # 优先使用Docker内置DNS,保证内部服务名可解析 - 114.114.114.114 # 可替换为你常用的公共DNS或VPN侧DNS depends_on: - db
第二步:修改VPN容器启动脚本,添加内网路由规则
在VPN连接建立逻辑执行前后添加以下路由规则,保证Docker内网网段流量不走VPN隧道:
# 提取当前容器的Docker网关地址 DOCKER_GATEWAY=$(ip route list default | awk '{print $3}' | head -n 1) # 添加Docker常用私有网段路由,走原生Docker网关 ip route add 172.16.0.0/12 via ${DOCKER_GATEWAY} dev eth0 ip route add 192.168.0.0/16 via ${DOCKER_GATEWAY} dev eth0 ip route add 10.0.0.0/8 via ${DOCKER_GATEWAY} dev eth0
如果使用OpenVPN作为VPN客户端,也可以直接在OpenVPN配置文件中添加以下规则,无需修改启动脚本:
route 172.16.0.0 255.240.0.0 net_gateway route 192.168.0.0 255.255.0.0 net_gateway route 10.0.0.0 255.0.0.0 net_gateway
验证方式
启动服务后进入app容器执行以下命令验证:
- 执行
ping db,可正常解析并连通即内部服务访问正常 - 执行
curl ifconfig.me,返回IP为VPN出口IP即公网流量走VPN隧道正常 - 宿主机访问
http://localhost:3001可正常打开app服务即端口映射正常
内容的提问来源于stack exchange,提问作者fiedl
相关产品推荐
相关产品推荐

