Docker容器和主机之间的网络VPN

70

我正在尝试在打开VPN(TUN设备)的MacOS上运行Docker镜像。 Docker容器可以访问互联网,但无法访问VPN后面的资源。 使Docker进入VPN网络的正确方法是什么?

我试过使用docker run --net host使Docker共享主机网络,但没有帮助。 主机可以访问VPN资源,但Docker容器无法解析它们的名称。


1
我最近构建了一个VPN容器,需要使用--privileged,在我的情况下不需要--net host - schmunk
3
针对 Ubuntu 用户:在 NetworkManager 处理 VPN 连接的 Ubuntu 上,使用 --net host 参数足以共享 VPN 连接。@schmunk 因为 --privileged 会打开所有功能,从而在安全方面存在巨大弊端,您应该尝试仅识别关键功能(如 NET_ADMIN?),并只启用此功能。更多阅读资料:Docker 文档 - 引擎 - 运行时特权和 Linux 功能 - Murmel
@Murmel,你应该将这个评论发布为Ubuntu用户的答案,这对我来说是解决方案(Ubuntu 18.04)。 - solujic
这里提到的解决方案对我有用:https://dev59.com/91cP5IYBdhLWcg3wr74G#52885161 - sandeepkunkunuru
相关的Docker问题请参考https://github.com/docker/for-mac/issues/4751。 - ks1322
11个回答

43
我在将主机连接到 VPN 后不得不重新启动 Docker。
sudo systemctl restart docker
docker start {name-of-container}

这是正确的解决方案。 - jhchnc
你救了我的一天,谢谢! - Yerke

20

不确定这是否是最佳解决方案。

我使用连接到VPN后出现在我的主机上的DNS。

scutil --dns | grep 'nameserver\[[0-9]*\]'
nameserver[0] : xxx.xxx.xxx.xxx

修改后的 Docker 运行命令:

docker run --cidfile="docker.pid" --dns=xxx.xxx.xxx.xxx --publish-all

现在 Docker 容器可以访问 VPN 后面的资源了... 它能工作,但我不知道这是好事还是坏事...


10

我曾经遇到过这个问题。我尝试了其他在这里提出的解决方案,但它们对我没有起作用。经过多次尝试和错误,这个解决方案非常好用:

将“bip”:“192.168.1.5/24”添加到daemon.json配置文件中。该文件可以在docker桌面设置下的docker引擎或/etc/docker/daemon.json中找到。BIP是桥接IP地址的设置,将更改docker分配其子网中的IP地址。通过更改此设置,我避免了VPN和docker IP地址之间的冲突。

重新启动docker守护程序。

停止所有容器。

运行“docker network prune”以删除未使用的网络。

重新启动所有容器。这将使用新的IP地址重新创建它们的网络。

您仍然可能需要在将来连接VPN后重新启动docker。请参见此线程获取其他解决方案和想法: https://github.com/docker/for-mac/issues/2820


6

5

我在Mac上运行docker版本3.6.0(67351)时遇到了这个问题。

对我有用的方法是将@Sheridan Rea和@Marco发布的解决方案结合起来:

  1. 将Docker子网更改为192.168.65.0/28。它之前设置为192.168.63.0/24。单击“应用并重启/重新启动Docker”

  2. 运行 docker network prune

  3. 运行 docker compose up

仅仅更改Docker子网对我来说不起作用。

现在我可以ping通VPN后面的IP地址了。


4
我的解决方法是将Docker的子网掩码从/24更改为/28,然后重新启动,现在我可以在我的VPN网络上ping、telnet和其他操作了。文档说默认值是/28,但Docker桌面版默认是/24。也许这是个打字错误,我不确定。

1
不确定为什么,但正如其他人在这里建议的那样,更改Docker子网是有效的。 唯一的区别是,在Windows版Docker桌面v4.14.0上,将子网设置为/28无效。

screeshot of error message

但仅仅将子网IP地址从192.168.65.0/24改为192.168.66.0/24就解决了问题。

1

对于那些遇到类似超时问题,但是当使用--network host时可以正常工作的人:可能是MTU不匹配(特别是在WireGuard默认情况下)。

查看ip link的输出。 docker0wg0mtu是多少?如果前者大于后者(例如1500比1420),则来自容器的数据包可能会被丢弃,因为它们太大了。

这可以帮助解决问题(在您的docker-compose.yaml中,或者只需创建类似的外部网络):

networks:
  default:
    driver: bridge
    driver_opts:
      com.docker.network.driver.mtu: 1420

还可以查看有关此特定问题来源的文章:https://sylwit.medium.com/how-we-spent-a-full-day-figuring-out-a-mtu-issue-with-docker-4d81fdfe2caf

(我真希望在自己解决问题之前能找到那篇文章...让这成为另一个通往解决方案的途径吧)。


1
谢谢你指出MTU的问题,解决了我的困扰 :) - undefined
@derflocki 哎呀!谢谢你告诉我,我很高兴我的帖子对你有用 ☺️ - undefined

1

之前发布的解决方案在我使用MacOS和OpenVPN客户端时都无法奏效。我发现我只需要像这样定义extra_hosts:

version: "3.9"
services:
    app:
        extra_hosts:
            - "something.vpn:192.168.196.3"

现在在Docker容器中访问something.vpn会导致IP地址变成192.168.196.3,无需更改Docker子网或其他任何内容。

0

对我来说,使用docker run --net nat解决了问题。 这是在Docker for Desktop(Windows)上运行的Windows容器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接