WSL2 记录

  • WSL2 折腾的坑

  • 资料来源:

    <>

  • 更新

    1
    2
    2022.09.23 初始
    2024.02.11 wsl2 镜像网络

导语

一些关于 WSL2 的备忘

Ubuntu 开启 Ssh

需要开个测试环境,就折腾下 wsl2 反正随时删.安装的是 ubuntu 20.04lts 发现无法远程登录 ssh.

需要特别设置一下:

  • 确保 openssh-server 已安装.(ubuntu 自带了)
  • 编辑 /etc/ssh/sshd_config
    • Port 22 ListenAddress xx 几项取消注释.
    • 添加 AllowUsers user
    • 如果是密码登录还需要确保 PasswordAuthentication yes
  • 重启 ssh 服务
  • 搞定.

开启 ssh 服务后,可以通过其分配的 ip 地址访问,也能通过 127.0.0.1:22 访问.

这里有点迷,之前看到过在 wsl2 的网页客户端,只能通过 localhost:80 访问,不能通过 127.0.0.1:80 访问,ssh 怎么能呢,或许有更新吧..留待后续..

Wsl2 占用大量内存

wls2 按道理来说有自动的内存回收,但是时常会直接占用到宿主机的大量内存,尤其是实验室那台只有 8g 的机器…

好在有办法全局限制,创建 %UserProfile%\.wslconfig 写入

1
2
3
4
5
[wsl2]
processors=4
memory=1.0GB
swap=3GB
localhostForwarding=true

大致上限制使用 4 个 CPU, 内存 1G, swap 3G, 允许 localhost:port 转发.

Wsl2 桥接 (这样能支持 ipv6)

wsl2 version >= 0.51.2 支持了 hyper-v 的桥接模式,这意味着 wsl2 终于能当作独立设备联网了,但是 wsl2 吗,肯定有坑…

  • 参考 > Bridged Networking under WSL

新建 hyper-v 的 external switch -> Create a virtual switch for Hyper-V virtual machines

用户下 .wslconfig 文件添加,vmSwitch 指向刚刚新建的交换机.

1
2
3
[wsl2]
networkingMode = bridged
vmSwitch = Bridge

但是到这一步还没有 ipv6 地址

接下来实际上和 wsl2 就没关系了,是配置 Systemd-Networkd 启用 ipv6 支持.

新建 /etc/network/interface/xx.network

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Match]
Name=eth0

[Network]
Description=Virtual switch
DHCP=true
IPv6AcceptRA=true
MulticastDNS=true
LLDP=true
EmitLLDP=true

[DHCP]
CriticalConnection=true
RouteMetric=10
UseDomains=true

sudo systemctl enable systemd-networkd + reboot boom ipv6 来了.

原文说这样会存在两个 ipv4 地址,但是基本不影响使用.

Wsl2 Systemd 支持

这个是最近才支持,需要 version >= 0.67.6,为了保险还是手动下载 msixbundle 安装吧.

启用很简单,写入 /etc/wsl.conf 几行配置

1
2
3
4
sudo cat > /etc/wsl.conf <<EOF
[boot]
systemd=true
EOF

至此我认为 wsl2 算是完全体了.

.VHDX 文件恢复 Wsl2

电脑突然崩了,原因不明.好在虚拟机和 wsl2 都在别的硬盘,只剩下 ext4.vhdx 文件..

从 vhdx 文件恢复 wsl2 -> https://github.com/microsoft/WSL/issues/4762

  • 原理就是注册表重新注册一个,然后指向 vhdx 文件

创建文本文件,并将后缀改为 .reg

1
2
3
4
5
6
7
8
9
Windows Registry Editor Version 5.00

[HKEY_USERS\[SID]\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\{[UUID]}]
"State"=dword:00000001
"DistributionName"="[DISTRO_NAME]"
"Version"=dword:00000002
"BasePath"="\\\\?\\[VHDX_PATH]"
"Flags"=dword:0000000f
"DefaultUid"=dword:000003e8
  • 中括号都得去掉
  • [SID] 是当前用户, whoami /user 命令能找到
  • [UUID] 是 wsl2 发行版的唯一 id ,这里随便生成一个就行 -> this generator
  • [DISTRO_NAME] 发行版名称
  • [VHDX_PATH] vhdx 文件路径, D:\\WSL\\Ubuntu

执行导入到注册表. 此时 windows 终端和 文件资源管理器 已经识别到了导入.

此时还可能有一个问题: Error code: Wsl/Service/CreateInstance/MountVhd/E_ACCESSDENIED

这是 vhdx 文件夹没有给当前用户权限导致的,到 [VHDX_PATH] 文件夹,安全选项,赋予 whoami /user 对应用户完整的权限.

Wsl2 镜像网络

wsl2 升级到 version 2.0 带来了相当多的更新, 其中 网络的镜像模式 “ 几乎解决了 “ wsl2 一直面临的网络问题:

  • wsl2 设置固定 ip
  • wsl2 设置代理
  • wsl2 主机访问

奈何初尝下,一直遇到莫名 bug, 如今 wsl2 2.0 正式版已经发布许久, 是时候开始搞定这些设置了.

1
2
3
4
5
6
7
8
9
10
11
[wsl2]
localhostForwarding=true
[experimental]
#autoMemoryReclaim=disabled # 检测到空闲CPU使用率后自动释放缓存内存。设置gradual为缓慢释放,设置dropcache 为立即释放缓存内存。
# 与 docker 有关暂时用不上 直接 disable 了.
#sparseVhd=true # 任何新创建的 VHD 将自动设置为稀疏。
networkingMode=mirrored # 如果值为mirrored则这将打开镜像网络模式。默认或无法识别的配置会设置为NAT。
dnsTunneling=true
firewall=true
autoProxy=true #强制 WSL 使用 Windows 的 HTTP 代理信息
hostAddressLoopback=true # 仅当 wsl2.networkingMode 设置为 mirrored, 允许容器通过分配给主机的 IP 地址连接到主机,或允许主机通过此方式连接到容器
  • 最主要的 networkingMode=mirrored autoProxy=true hostAddressLoopback=true
  • hostAddressLoopback=true 是 docker 的必选项.

目前是在 wsl 内部使用 docker 此时还需要禁用 iptable /etc/docker/daemon.json 加上一句 "iptables": false

神奇的是 此时 wsl2 内部还可能出现网络请求失败.. 此时就和 wsl 设置无关了,而是 宿主机的网络代理设置了.. 最最常见的问题是: clash 或 其他代理软件的 tun 模式, 默认 mtu 为 9000 必须重新改为 1500.

这个配置下 稳定了 2 月了, 没有遇到镜像网络下的问题, 仅供参考.