记录一个相当坑爹的WSL局域网访问问题

导读

以前从来没有遇到过这样的问题,因为从来都是把东西全部扔到自己的小笔记本上,结果就是性能明显不足开始发烫,手被烤成了猪蹄。结果放到服务器上,局域网不能访问。弄了好几天,终于发现了问题所在。本文给出了解决办法。


WSL开启Docker镜像

目前的需求是要运行基于百度飞桨(paddlepaddle)的DDPG模型,其中CUDA版本和Ubuntu的版本是配置环境中最难的部分。一方面,Ubuntu的版本决定了gcc与g++的版本,进而影响到了CUDA版本的选用,二者直接决定了百度飞桨的版本选用。即使很多人能够注意到CUDA版本对paddlepaddle的影响,但是Ubuntu对CUDA与paddlepaddle的影响其实是相对更大的,却并不容易被注意到,往往会解决了一系列与CUDA相关的问题后,发现实际上是Ubuntu与paddlepaddle不兼容的问题。


所以,在意识到上述问题后,paddlepaddle在Ubuntu中的配置就成为了短时间内并不能快速完美解决的问题。于是放弃了幻想,回到了最熟悉的Windows11+WSL2,并使用Docker开启镜像,彻底依赖于官方给定的镜像:paddlepaddle/paddle:2.3.1-gpu-cuda11.2-cudnn8。


目前市面上可用的稳定编辑器种类相当多,但是相对较为完美的就是VScode,迎合了目前需要根据jupyter一步一个脚印的查看日志与输出的需求。为了能够使得VScode能够实时远程编辑与调试,WSL2中的Docker开启了22 2222端口的映射,在WSL的映射是3000 30003000。


一切似乎都没有问题。


发现问题

在后续的编码过程中,尝试使用VScode远程连接,但是只能使用服务器连接localhost:3000,并不能使用本机IP加端口号的形式访问。


经过大量的调研,发现很多解决方案并没有表述准确,在很多次尝试之后依然是失败的。


官方文档给出的解释

在意识到没有任何可用的参考博客之后,又辗转回到了官方文档中:使用 WSL 访问网络应用程序。官方文档中对WSL1与WSL2中对于防火墙的差别进行了说明:


当使用 WSL 1 分发版时,如果计算机设置为可供 LAN 访问,那么在 WSL 中运行的应用程序也可供在 LAN 中访问。这不是 WSL 2 中的默认情况。 WSL 2 有一个带有其自己独一无二的 IP 地址的虚拟化以太网适配器。 目前,若要启用此工作流,你需要执行与常规虚拟机相同的步骤。 (我们正在寻找改善此体验的方法。)


下图是微软官方给出的图例,说明了WSL2访问本机开启的前端项目需要执行的操作。




即是说,WSL2处于Windows分配的一个虚拟子网中,在逻辑结构上类似于以本机为路由器,连接了一台装有Linux的主机。


所以,在Windows中使用ipconfig查询IP地址后,是可以使用局域网IP加端口号的形式连接到WSL2中。


例如:本机IP是192.168.1.2 192.168.1.2192.168.1.2,而查询了IP地址后,发现实际上还有多出来的172.23.192.1 172.23.192.1172.23.192.1,那么访问WSL2的时候只能使用172.23.192.1 : 3000 172.23.192.1:3000172.23.192.1:3000,而无法使用192.168.1.2 : 3000 192.168.1.2:3000192.168.1.2:3000。


很明显,在这种情况下,相当于WSL2只能使用服务器访问,与服务器同在一个局域网下的所有设备都无法访问。这也对于需要远程办公的需求相悖。


官方当然也给出了解决方案,就是将WSL2的IP与端口号一起通过Windows自带的防火墙转发到物理机上,这样就能够访问了。官方给出的例子是:


netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=172.23.192.1

1

也就是说,将172.23.192.1 : 3000 172.23.192.1:3000172.23.192.1:3000转发到0.0.0.0 : 3000 0.0.0.0:30000.0.0.0:3000上,通过广播,在同一个局域网上的所有设备都可以访问。


实际上,有很多博客都是这么写的,但实际上都是不正确的。


实际解决方案

于是,查询Windows的端口占用:


netstat -ano | findstr 3000

1

于是发现了这个:


协议本地地址外部地址状态PID

TCP127.0.0.1 : 3000 127.0.0.1:3000127.0.0.1:30000.0.0.0 : 0 0.0.0.0:00.0.0.0:0LISTENING10108 1010810108

发现问题了吗?


3000 30003000端口已经被回环地址占用了。


所以,我们需要做的,就是将WSL的3000 30003000端口转发到其他的端口,我这里使用的是3901 39013901。


于是,在监听0.0.0.0 : 3901 0.0.0.0:39010.0.0.0:3901的过程中,防火墙再把3901 39013901的访问转发到3000 30003000,3000 30003000再通过Docker映射跳转到镜像的22 2222端口。


也就是:


netsh interface portproxy add v4tov4 listenport=3901 listenaddress=0.0.0.0 connectport=3000 connectaddress=localhost

1

通过这行命令,就相当于在请求服务器的3901 39013901端口的时候,通过防火墙、Docker两道跳转,终于到了22 2222端口,使用ssh命令访问就能够实现远程连接。


总算是弄明白了。

————————————————

版权声明:本文为CSDN博主「ordinary_brony」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/ordinary_brony/article/details/126044086



原文链接:https://www.laialex.com/post/ji-lu-yi-ge-xiang-dang-keng-die-dewsl-ju-yu-wang-f-tk2.html

相关文章

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

返回顶部