一、背景
WSL2在去年下半年时候更新了2.0的Pre-Relese版本,详细更新内容:https://github.com/microsoft/WSL/releases/tag/2.0.0
总结一下主要是:
- 支持自动回收内存
- 支持自动释放 WSL2 虚拟硬盘空间
- 支持和 Windows 使用相同的网络(镜像网络)
- 支持 DNS Tunneling
- 支持 Windows 设置的代理
- 支持 Windows 防火墙
- 支持 Multicast
终于,WSL2可以和宿主机的Windows共用一套网络端口了。
之前的的方式是使用桥接模式给WSL2配置静态IP,现在可以设置镜像网络,直接通过127.0.01来访问WSL2中的服务。这样也能解决当网络环境变化时候,需要重新配置IP的问题。
Note:
- Windows系统版本需要至少 Windows 11 23H2
- WSL最新正式版本为2.0.14
二、配置过程
1. 在Windows宿主机上修改WSL的config
在当前用户目录(C:\Users\xxx)下修改.wslconfig,内容:
1 | [wsl2] |
Note:
如果你在WSL里使用docker,需要将 autoMemoryReclaim配置为dropcache或者disabled否则无法启动Docker
如果你在WSL里使用docker,需要在/etc/docker/daemon.json 里添加一句 “iptables”: false,否则你可能无法在Windows中连接Docker容器。
2. 在WSL2中增加网络相关的配置
修改下WSL2下/etc/wsl.conf
,修改内容:
1 | [network] |
4. 在WSL2中配置DHCP自动获取IP
修改WSL2下的/etc/network/interfaces
,修改内容:
1 | # The primary network interface |
5. 重新启动WSL2
在powershell中输入:
1 | wsl --shutdown |
再次打开WSL2,使用ip addr
命令查看IP地址,已经和宿主机Windows的IP一致了:
1 | 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 |
已经成功设置完成。
三、端口冲突问题
配置完成后,发现docker中在运行的服务有些挂掉了,重启提示端口冲突,在Windows中使用netstat -aon | findstr "3306"
查看进程,也没有查到相关端口。
1. 原因
查阅资料后发现,这个问题的原因分为两部分:
Windows
中有一个TCP 动态端口范围,处在这个范围内的端口,有时候会被一些服务占用。在Windows Vista
(或Windows Server 2008
)之前,动态端口范围是1025
到5000
;在Windows Vista
(或Windows Server 2008
)之后,新的默认起始端口为49152
,新的默认结束端口为65535
。- 如果安装了
Hyper-V
,那么Hyper-V
会为容器宿主网络服务(Windows Container Host Networking Service)随机保留一些端口号使用。
正常情况下,Hyper-V
虽然会在TCP 动态端口范围中随机挑一些端口号保留(占用),不过保留的端口号普遍比较大,就算保留几百、几千个也影响不大。但是,Windows 自动更新有时会出错,导致这个范围的起始端口被重置为 1024
。这就会导致一些常用端口因为被保留而无法使用。
使用命令 netsh int ipv4 show dynamicport tcp
可以查看目前TCP 动态端口的范围:
1 |
|
这只是一个待选择范围,并不代表其中的所有端口都会被保留,只是有一部分会被 Hyper-V
征用。使用 netsh int ipv4 show excludedportrange protocol=tcp
命令可以查看当前所有已经被征用了的端口:
1 |
|
这些端口有时候会随机到一些常用端口,比如3000、3306、8080等,导致这些常用端口无法使用。
2. 解决方案
可以通过重启网络来重设随机预留的端口,但是这就和开盲盒一样,随机性太高。正确的解决思路,因该是调整TCP 动态端口范围,避开常用的端口区间。
使用管理员权限运行Powershell,执行:
1 | netsh int ipv4 set dynamic tcp start=50000 num=15536 |
把TCP 动态端口范围限定在50000-65535,重启网络,再次查看目前TCP 动态端口的范围:
1 |
|
这样就可以成功避开日常使用的端口,保证不会因为端口冲突导致docker等服务无法运行的问题。