您确定 Ubuntu WSL2 实例正在桥接运行吗?默认情况下,WSL2 实例运行 NAT(而 WSL1 实例运行桥接)。因此,虽然 Docker 网络是桥接的,但如果不进行一些额外的工作,它仍然无法访问 NAT 的 WSL2 VM。
我相当确定您遇到了中描述的根本问题WSL 问题 #4150 https://github.com/microsoft/WSL/issues/4150。如果是这样,这里有一些可以尝试的事情......
选项 #1 - 端口转发到 WSL2 实例
该 GitHub 问题中建议了几种解决方法,但适合您的情况的基础知识可以归结为将端口 4000 从 Windows 主机接口转发到 WSL2 实例的私有 IP 地址。在 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"
请注意,您需要在每次重新启动后执行此操作,或者设置一个在登录时运行的脚本,如 GitHub 问题中所述(请参阅这条评论 https://github.com/microsoft/WSL/issues/4150#issuecomment-504209723).
选项 #2 - WSL1
我还建议,假设它适合您的工作流程,并且您的 Web 应用程序在其上运行,您可以简单地使用 WSL1 而不是 WSL2。您可以通过以下方式尝试一下:
- 备份现有发行版(从 PowerShell 或 cmd,使用
wsl --export <DistroName> <FileName>
- 将备份导入到新的 WSL1 实例中
wsl --import <NewDistroName> <InstallLocation> <FileNameOfBackup> --version 1
可以简单地更改版本,但我倾向于在执行此操作之前先进行备份,并且只要您进行备份,您也可以将原始版本保留在原处。
可能的选项#3 -socat
转发或隧道
虽然我没有直接测试您的特定用例,但我已经尝试过socat
在 WSL2 中取得成功。从它的外观来看socat
可用于从 WSL2 到(至少)Windows 主机(Docker 容器可以访问)的端口转发。看这条评论 https://github.com/microsoft/WSL/issues/4619#issuecomment-601429273GitHub 上有一个与您类似的用例的示例。
可能的选项 #4 - WSL2 处于桥接模式
上面引用的 GitHub 线程还提供了有关如何使用 Hyper-V 在 WSL2 接口上启用桥接模式的一些详细信息。我相信这需要 Windows 10 专业版或企业版。与选项 1 一样,它还必须在每次重新启动后完成。同样,如果端口转发或 WSL1 可以满足您的需要,那么对于这种情况可能有点过分了。