使用 WSL + Ubuntu 20.04 LTS 时访问 Docker 容器 IP
Accessing Docker Container IP when using WSL + Ubuntu 20.04 LTS
我目前通过 WSL 在 Windows 10 上使用 docker。我本机在 Linux 中开发了一个应用程序,在那里我能够通过浏览器使用 http://10.5.0.2:8088
之类的东西访问容器。碰巧当我使用 WSL + Ubuntu 做同样的事情时,我唯一能做的就是 http://localhost:8088
.
目前这似乎不是问题,但由于我正在模拟集群,所以最好避免这种情况,以免以后出现端口冲突。
为了说明:我正在用类似
的东西定义一个堆栈
version: "3.7"
services:
spark-master:
image: master
container_name: spark-master
hostname: spark-master
tty: true
depends_on:
- spark-worker-1
- [...]
ports:
- "8088:8088"
- "50070:50070"
- "50030:50030"
- "8080:8080"
- "8042:8042"
- "8888:8888"
- "4040:4040"
networks:
spark-network:
ipv4_address: 10.5.0.2
spark-worker-1:
image: worker
container_name: spark-worker-1
hostname: spark-worker-1
tty: true
ports:
- "8081:8081"
- "6042:8042"
networks:
spark-network:
ipv4_address: 10.5.0.3
networks:
spark-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 10.5.0.0/16
因此,可以将其映射到 Windows 主机,或者 Docker 具有 WSL 后端的桌面根本不支持通过 IP 访问容器?
简答
是的,但通常维护起来太复杂(涉及网络知识,以及iptables和Windows和Linux路由)并且违背了使用docker的目的第一名。您可能应该将 WSL2 虚拟机作为您可以远程访问的单个外部节点来处理。
长答案
Docker 在 WSL2 运行s 在 Hyper-V 内的 VM 中,使用一些技巧将通信从 VM 中的暴露端口转发到 Windows 主机和vice-versa(这就是为什么您可以 运行 docker run --rm -it -p 80:80 containous/whoami
并通过 http://localhost 访问容器数据的原因)。
这就是为什么您不能使用容器 IP 直接访问您的容器的原因:您的容器桥接的网络来自 VM(而不是 Windows 主机),因此 Windows 主机具有不知道在该网络中指向何处进行通信。
但是,如果您曾经弄乱过网络,就会知道如果一切设置正确,您总是可以从一个主机跳到另一个主机。你只需要知道进入网络混乱的方式。 But(总有一个但是)docker 也使用它自己的 iptables
方案来通过外部网络和容器安全进行 NAT 容器通信。这就是为什么简单地添加一条从 Windows 主机到 WSL2 VM 的路由是行不通的:请求将能够到达 VM,但不能到达容器,因为 iptables 规则将禁用它的转发(出于安全原因) , 看起来 here).
所以,总而言之,为了让您能够像在 Ubuntu:
中那样与您的容器通信
- 在您的 Windows 主机中为您的集群在 VM 中设置通信路由,因为 WSL2 VM 不使用静态 IP:
route add <your-cluster-subnet>/<mask> <your-vm-ip>
- 启用来自 Docker
iptables
外部路由规则的转发:iptables -I DOCKER-USER -i src_if -o dst_if -j ACCEPT
- 利润?
请注意,如果您使用 WSL2 的默认设置,则需要多次执行第 1 步,因为默认情况下 WSL2 虚拟机不使用静态 IP。
我个人认为只公开端口更容易:)
参考资料
我目前通过 WSL 在 Windows 10 上使用 docker。我本机在 Linux 中开发了一个应用程序,在那里我能够通过浏览器使用 http://10.5.0.2:8088
之类的东西访问容器。碰巧当我使用 WSL + Ubuntu 做同样的事情时,我唯一能做的就是 http://localhost:8088
.
目前这似乎不是问题,但由于我正在模拟集群,所以最好避免这种情况,以免以后出现端口冲突。
为了说明:我正在用类似
的东西定义一个堆栈version: "3.7"
services:
spark-master:
image: master
container_name: spark-master
hostname: spark-master
tty: true
depends_on:
- spark-worker-1
- [...]
ports:
- "8088:8088"
- "50070:50070"
- "50030:50030"
- "8080:8080"
- "8042:8042"
- "8888:8888"
- "4040:4040"
networks:
spark-network:
ipv4_address: 10.5.0.2
spark-worker-1:
image: worker
container_name: spark-worker-1
hostname: spark-worker-1
tty: true
ports:
- "8081:8081"
- "6042:8042"
networks:
spark-network:
ipv4_address: 10.5.0.3
networks:
spark-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 10.5.0.0/16
因此,可以将其映射到 Windows 主机,或者 Docker 具有 WSL 后端的桌面根本不支持通过 IP 访问容器?
简答
是的,但通常维护起来太复杂(涉及网络知识,以及iptables和Windows和Linux路由)并且违背了使用docker的目的第一名。您可能应该将 WSL2 虚拟机作为您可以远程访问的单个外部节点来处理。
长答案
Docker 在 WSL2 运行s 在 Hyper-V 内的 VM 中,使用一些技巧将通信从 VM 中的暴露端口转发到 Windows 主机和vice-versa(这就是为什么您可以 运行 docker run --rm -it -p 80:80 containous/whoami
并通过 http://localhost 访问容器数据的原因)。
这就是为什么您不能使用容器 IP 直接访问您的容器的原因:您的容器桥接的网络来自 VM(而不是 Windows 主机),因此 Windows 主机具有不知道在该网络中指向何处进行通信。
但是,如果您曾经弄乱过网络,就会知道如果一切设置正确,您总是可以从一个主机跳到另一个主机。你只需要知道进入网络混乱的方式。 But(总有一个但是)docker 也使用它自己的 iptables
方案来通过外部网络和容器安全进行 NAT 容器通信。这就是为什么简单地添加一条从 Windows 主机到 WSL2 VM 的路由是行不通的:请求将能够到达 VM,但不能到达容器,因为 iptables 规则将禁用它的转发(出于安全原因) , 看起来 here).
所以,总而言之,为了让您能够像在 Ubuntu:
中那样与您的容器通信- 在您的 Windows 主机中为您的集群在 VM 中设置通信路由,因为 WSL2 VM 不使用静态 IP:
route add <your-cluster-subnet>/<mask> <your-vm-ip>
- 启用来自 Docker
iptables
外部路由规则的转发:iptables -I DOCKER-USER -i src_if -o dst_if -j ACCEPT
- 利润?
请注意,如果您使用 WSL2 的默认设置,则需要多次执行第 1 步,因为默认情况下 WSL2 虚拟机不使用静态 IP。
我个人认为只公开端口更容易:)
参考资料