问题描述
我正在 https://0.0.0.0:4000 上运行一个简单的Web服务器(也可以通过 https://local.phx-cd.shoepping.at:4000 并映射到127.0.在我的WSL2 Ubuntu上的Ubuntu主机文件中为0.1).我可以从Ubuntu和Windows主机都连接到它-到目前为止一切顺利.但是,此外,在与WSL2集成的Docker for Win中,我运行了一个selenium chrome容器,该容器正在连接和测试该Web服务器上的内容(使用网桥),但无法连接!
我已连接到容器,并尝试卷曲到Web服务器-连接被拒绝.由于我的计算机具有双重引导功能,因此我尝试切换到Linux发行版,在其中运行Web服务器,并在Linux Docker中运行Selenium,并成功连接到本地Web服务器.因此,我认为这与WSL2有关.
我的docker-compose.yaml(我省略了硒集线器配置)
selenium-chrome-local:图片:selenium/node-chrome-debug:3.141.59重启:总是端口:-5901-5902:5900数量:-/dev/shm:/dev/shm-../../temp:/home/seluser/下载取决于:-硒毂本地环境:-SCREEN_WIDTH = 1920-SCREEN_HEIGHT = 1080extra_hosts:-"local.phx-cd.shoepping.at:10.99.99.1"网络:-瑟格里德-dockerhost网络:selgrid:dockerhost:司机:桥ipam:配置:-子网:10.99.99.0/24
让我知道您是否需要更多配置.谢谢.
您确定Ubuntu WSL2实例正在桥接运行吗?默认情况下,WSL2实例运行NAT(而WSL1实例桥接).因此,虽然可以,但Docker网络是桥接的,但是如果不做一些额外的工作,它仍然无法访问NAT的WSL2 VM.
我相当确定您遇到了 WSL问题#4150中描述的根本问题.如果是这样,请尝试以下操作...
选项#1-端口转发到WSL2实例
在该Github问题中建议了几种解决方法,但是适用于您的情况的基本知识归结为将端口4000从Windows主机接口转发到WSL2实例的私有IP地址.在PowerShell中:
netsh接口portproxy delete v4tov4 listenport ="4000"#删除任何现有的端口4000转发$ wslIp =(wsl -d Ubuntu -e sh -c" ip addr show eth0 | grep'inet \ b'| awk'{print`$ 2}'| cut -d/-f1")#获取WSL2实例netsh接口portproxy add v4tov4 listenport ="4000"connectaddress ="$ wslIp";connectport ="4000"
请注意,您需要在每次重新启动后执行此操作,否则请按照Github问题中的说明设置在登录时运行的脚本(请参阅此评论).
选项#2-WSL1
我还建议,假设它适合您的工作流程,并且如果您的Web应用程序在其上运行,则可以简单地使用WSL1而不是WSL2.您可以通过以下方法进行尝试:
- 备份现有发行版(从PowerShell或cmd,使用
wsl --export< DistroName>< FileName>
- 使用
wsl --import< NewDistroName>将备份导入到新的WSL1实例中.< InstallLocation>< FileNameOfBackup>--version 1
可以简单地更改版本,但是我倾向于在执行备份之前先进行备份,只要您进行备份,就可以将原始版本保留在原处.
可能的选项3- socat
转发或隧道
虽然我还没有直接测试您的特定用例,但是我成功地在WSL2中试用了 socat
.从外观上看, socat
可以用于从WSL2到(至少)Windows主机的端口转发(Docker容器可以访问它).请参见此评论和有关Github的与您的用例相似的示例.
可能的选项4-桥接模式下的WSL2
上面引用的Github线程还具有一些有关如何使用Hyper-V在WSL2接口上启用桥接模式的详细信息.我相信这需要Windows 10专业版或企业版.与选项1一样,它也必须在每次重新启动后执行.同样,如果端口转发或WSL1可以完成您需要的操作,则在这种情况下可能会过大.
I am running a simple web server on https://0.0.0.0:4000 (accessible also as https://local.phx-cd.shoepping.at:4000 with mapping to 127.0.0.1 in Ubuntu hosts file) on my WSL2 Ubuntu. I can connect to it from both Ubuntu and Windows host - so far so good. But additionally, in my Docker for Win with WSL2 integration, I run a selenium chrome container which is connecting and testing stuff on that web server (using bridge), but it can't connect to it!
I connected to the container and tried to curl to the web server - connection refused. Since I have dual boot on my computer, I tried to switch to my Linux distro, run web server there and selenium in Linux Docker and connection to the local web server worked. So I think it has something to do with the WSL2.
My docker-compose.yaml (I left out my selenium hub config)
selenium-chrome-local:
image: selenium/node-chrome-debug:3.141.59
restart: always
ports:
- 5901-5902:5900
volumes:
- /dev/shm:/dev/shm
- ../../temp:/home/seluser/Downloads
depends_on:
- selenium-hub-local
environment:
- SCREEN_WIDTH=1920
- SCREEN_HEIGHT=1080
extra_hosts:
- "local.phx-cd.shoepping.at:10.99.99.1"
networks:
- selgrid
- dockerhost
networks:
selgrid:
dockerhost:
driver: bridge
ipam:
config:
- subnet: 10.99.99.0/24
Let me know if you need more config. Thanks.
Are you sure that the Ubuntu WSL2 instance is running bridged? By default, WSL2 instances run NAT'd (whereas WSL1 instances ran bridged). So, while yes, the Docker network is bridged, it still can't access the NAT'd WSL2 VM without some extra work.
I'm fairly sure that you are running into the root problem described in WSL issue #4150. If so, here are some things to try ...
Option #1 - Port forwarding to the WSL2 instance
There are several workarounds suggested in that Github issue, but the basics that would work for your case boil down to forwarding port 4000 from the Windows host interface to the WSL2 instance's private IP address. In PowerShell:
netsh interface portproxy delete v4tov4 listenport="4000" # Delete any existing port 4000 forwarding
$wslIp=(wsl -d Ubuntu -e sh -c "ip addr show eth0 | grep 'inet\b' | awk '{print `$2}' | cut -d/ -f1") # Get the private IP of the WSL2 instance
netsh interface portproxy add v4tov4 listenport="4000" connectaddress="$wslIp" connectport="4000"
Note that you'll need to do this after each reboot, or else set up a script that runs at logon as described in the Github issue (see this comment).
Option #2 - WSL1
I would also propose that, assuming it fits your workflow and if your web app runs on it, you can simply use WSL1 instead of WSL2. You can try this out by:
- Backing up your existing distro (from PowerShell or cmd, use
wsl --export <DistroName> <FileName>
- Import the backup into a new WSL1 instance with
wsl --import <NewDistroName> <InstallLocation> <FileNameOfBackup> --version 1
It's possible to simply change versions in place, but I tend to like to have a backup anyway before doing it, and as long as you are backing up, you may as well leave the original in place.
Possible Option #3 - socat
forwarding or tunnel
While I haven't tested your particular use-case directly, I have played around with socat
in WSL2 with success. From the looks of it socat
could be used for port forwarding from WSL2 to (at the least) the Windows host (which would be accessible to the Docker container. See this comment and example on Github about a similar use-case as yours.
Possible Option #4 - WSL2 in bridge mode
The Github thread referenced above also has some details on how to enable bridge-mode on the WSL2 interface using Hyper-V. I believe this requires Windows 10 Professional or Enterprise. It also has to be done after each reboot, as with Option 1. Again, probably overkill for this case, if port forwarding or WSL1 can accomplish what you need.
这篇关于无法从WSL2 Docker容器连接到WSL2本地服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!