首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从MongoDB连接到WSL2

如何从MongoDB连接到WSL2
EN

Stack Overflow用户
提问于 2022-07-24 15:58:59
回答 1查看 255关注 0票数 1

我在本地MongoDB机器上启动了一个mongod.exe服务器,并希望从WSL2中连接到pymongo (从WSL2中启动的朱庇特笔记本;从下面ifconfig获取的ip地址):

代码语言:javascript
复制
import pymongo as pm
import datetime as dt

host = 'mongodb://192.168.72.32'
port = 27017
client = pm.MongoClient(host, port)
client.admin.command('ismaster')

我不断地得到一个ServerSelectionTimeoutError: 192.168.72.32:27017: [Errno 111] Connection refused错误。

问题是如何将服务器/端口从Windows公开到WSL2。我已经在netsh中打开了端口(如官方文档这里中所描述的)。ifconfig在WSL2端的输出:

代码语言:javascript
复制
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.72.32  netmask 255.255.240.0  broadcast 192.168.79.255
        inet6 fe80::215:5dff:fe96:9d57  prefixlen 64  scopeid 0x20<link>
        ether 00:15:5d:96:9d:57  txqueuelen 1000  (Ethernet)
        RX packets 662495  bytes 168890186 (168.8 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 170242  bytes 369162848 (369.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 99019  bytes 163040786 (163.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 99019  bytes 163040786 (163.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

我做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-24 16:59:28

要从WSL2访问在Windows中运行的任何网络应用程序/服务,(至少)需要做好以下三件事:

  • *将服务配置为侦听正确的(不是localhost),即a.k.a。“绑定地址”。
  • 打开必要的防火墙端口
  • 使用来自WSL2的正确地址(同样,不是localhost__)

您可能只是缺少了第一部分,因为默认情况下MongoDB绑定到本地主机。根据文档

默认情况下,MongoDB二进制文件mongodmongos绑定到本地主机。如果为二进制文件设置了net.ipv6配置文件设置或--ipv6命令行选项,则二进制文件还会绑定到本地主机IPv6地址。

下面提供了更多关于这些需求的详细信息(大部分是复制的,对您的特定用例进行了一些细微的修改,来自我对超级用户的相关回答):

绑定地址

许多应用程序或服务默认绑定到localhost,这(显然)意味着您只能从运行服务的主机连接到它们。因为WSL2运行在“单独的网络”上,所以您将无法访问仅在localhost上侦听的服务。您可能希望绑定到0.0.0.0 (对于IPv4)和/或:: (用于IPv6)来侦听所有接口。

当然,配置服务的方法会因不同的应用程序而有所不同,但通常您会发现标记为“绑定地址”、“侦听”或类似设置的设置。上面具体地链接了关于MongoDB的说明。

更改此设置后,请确保重新启动应用程序/服务。

附带注意:可以只绑定到WSL2接口,就像我在这个答案中描述的那样(埋在中间的某个地方),但这可能是过分的,因为如果需要,防火墙可以更容易地用于阻止来自非WSL网络的连接。

防火墙配置

默认情况下,Windows Defender防火墙(和其他)将阻止从另一个网络到主机的传入连接。由于我们已经确定WSL2在一个单独的网络中运行,所以您需要为您的服务打开一个防火墙端口。

您可以有选择地从PowerShell (在管理shell中)执行以下操作:

代码语言:javascript
复制
New-NetFirewallRule -DisplayName "MongoDB from WSL2" -InterfaceAlias "vEthernet (WSL)" -Direction Inbound -Protocol TCP -LocalPort 27017 -Action Allow 

当然,您可以放弃以下两种方法:

  • InterfaceAlias,在这种情况下,它将从所有网络打开8545。
  • 或者LocalPort,在这种情况下,它的作用就像上面的“禁用”选项,并且总是接受来自WSL网络接口的传入流量。

从WSL2查找要使用的正确Windows地址

您可以使用几种方法(和IP地址)。如果您知道的话,最简单的方法就是使用Windows主机的IP地址。但是,如果它是动态分配的,并且更改频繁(我相信,这是非常不寻常的),那么您可能需要在每次重新启动时更改您的WSL2代码。

在您的示例中,您可能在192.168.0.0/32的私有地址空间中有一个静态地址,因此您可能不需要以下内容。

然而,无论如何,最好的做法是使用mDNS名称,该名称(通常)将正确解析静态或动态地址分配。

假设您没有覆盖WSL生成的默认/etc/resolv.conf,这可以通过使用Windows名称并简单地附加.local来完成。例如,如果您的计算机名为bubblegum,那么bubblegum.local应该是正确的地址。

从Python中,可以通过以下方法获得:

代码语言:javascript
复制
import socket
server = f'{socket.gethostname()}.local' # Generic form
host = f'mongodb://{socket.gethostname()}.local' # For your example

您应该发现这是与以下内容相同的地址:

代码语言:javascript
复制
echo $(ip route list default | awk '{print $3}')

但是,如果您重写了/etc/resolv.conf (在某些情况下由于VPN或其他网络配置是必要的),那么您可能需要一些更复杂的内容,例如:

代码语言:javascript
复制
echo $(host `hostname --long` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r')

(此方法归功于@ChaiAng在问Ubuntu的问题上的回答 )。

但是,请注意,它比mDNS慢得多。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73099941

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档