Docker NET_ADMIN 容器的端口无法从主机外部访问

Docker NET_ADMIN container's ports are inaccessible from outside the host machine

我有一个 docker-compose 文件,其中我有一个 VPN 运行 作为 NET_ADMIN,并且一堆其他容器的流量通过 VPN 容器路由。

问题是我只能从主机访问其他容器(通过 VPN 路由)的 Web API。

version: "3.5"
services:
  vpn:
    image: ilteoood/docker-surfshark:latest
    container_name: surfshark
    env_file:
      - .env
    cap_add: 
      - NET_ADMIN
    devices:
      - /dev/net/tun
    ports:
      - 8080:8080
      - 8085:8085
    restart: unless-stopped

当我从主机连接到 http://localhost:8080/ 时,一切正常。当我通过 http://192.168.1.6:8080(主机的 IP)从本地网络上的另一台机器连接到容器时,连接超时。

此问题仅影响 VPN 容器(以及通过它路由的容器)。未通过 VPN 容器路由的同一 docker-compose 文件中的其他容器按预期工作。

主机是 运行 Pop!_OS 22.04,Intel CPU。

编辑:容器内的路由:

# ip route list
0.0.0.0/1 via 10.8.8.1 dev tun0 default via 172.21.0.1 dev eth0  
10.8.8.0/24 dev tun0 proto kernel scope link src 10.8.8.9  
84.17.60.250 via 172.21.0.1 dev eth0  128.0.0.0/1 via 10.8.8.1 dev tun0  
172.21.0.0/16 dev eth0 proto kernel scope link src 172.21.0.4 – 

这里的问题是您的容器正在使用 VPN 作为其默认路由:

  • 请求来自您的本地 192.168.1.0/24 网络
  • 容器内的服务发送回复
  • 内核寻找到达 192.168.1.0/24 网络的适当路由,但未找到,因此选择默认网关。
  • 回复从 VPN 发出,它不知道如何处理 192.168.1.0/24 目的地,所以回复被丢弃

最简单的解决方案是通过常规 Docker 默认网关为本地网络添加显式路由:

# ip route add 192.168.1.0/24 via 172.21.0.1

(这里我从分配给 eth0 的地址推断网关地址。)