无法从WSL2 Docker容器连接到WSL2本地服务器 [英] Can't connect to WSL2 localhost server from WSL2 docker container

查看:498
本文介绍了无法从WSL2 Docker容器连接到WSL2本地服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 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问题中的说明设置在登录时运行的脚本(请参阅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:

  1. Backing up your existing distro (from PowerShell or cmd, use wsl --export <DistroName> <FileName>
  2. 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本地服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆