WSL2 优化与管理

太阳作者太阳
原创内容采用 CC-4.0 协议发布,转载请注明出处

官方文档

官方文档已经写得很完整,这里只记录我自己会反复使用的命令。

管理发行版

# 查看已安装和可安装的发行版
wsl --list --verbose
wsl --list --online

# 安装、更新和设置默认发行版
wsl --install --distribution Debian
wsl --update
wsl --set-default Debian

# 停止全部 WSL 实例
wsl --shutdown

修改 Ubuntu 镜像地址

通过 WSL 安装 Ubuntu 后,我会把默认软件源换成 USTC 镜像。下面的路径适用于使用 ubuntu.sources 的 Ubuntu 版本:

sudo sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/ubuntu.sources
sudo sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/ubuntu.sources

导出 tar 适合备份或迁移,WSL2 也可以直接导出 VHDX:

wsl --export Ubuntu Ubuntu.tar
wsl --import Ubuntu C:\app\wsl\Ubuntu Ubuntu.tar --version 2

wsl --export Debian Debian.vhdx --vhd
wsl --import-in-place Debian-VHD Debian.vhdx

wsl --unregister Ubuntu 会直接删除发行版及其中的数据。我只在确认导出文件可用后执行。

Mirrored 网络失败后,Docker 看起来像坏了

我的 Docker Engine 装在 Ubuntu 中,PowerShell 里的 docker 也会转发为 wsl docker。因此第一次执行 Docker 命令时,往往也会启动 WSL。2026 年 8 月的一次排查中,拉取任何镜像都失败,最初看起来像镜像站或 Docker DNS 的问题:

lookup docker.1ms.run on [::1]:53: connection refused

继续检查才发现 Ubuntu 只剩回环地址,没有默认路由,/etc/resolv.conf 指向的文件也不存在。真正有用的错误出现在 WSL 启动阶段:

wsl: 出现了内部错误。
错误代码: CreateInstance/CreateVm/ConfigureNetworking/0x8007054f
wsl: 无法配置网络 (networkingMode Mirrored),回退到 networkingMode None。

Mirrored 初始化失败后回退到 None,发行版仍然可以启动,却没有可用网络。此时更换 Docker 镜像、重启 Docker 服务或修改 Linux DNS 都碰不到问题所在。

这次故障查了很久。执行 wsl --shutdown、重启 HNS 和 vmcompute,以及暂时关闭 Clash、解绑 VMware Bridge Protocol 和 Npcap,都没有稳定恢复网络。机器上的 TCP 动态端口范围曾被扩大到 1024–65534,同时 HypervisorPlatform 处于关闭状态;恢复 Windows 默认端口范围、启用该组件并完整重启 Windows 后,Mirrored 才恢复。对应的 WSL Issue #41251记录了相同错误和排查过程,但也保留了一个重要边界:无法证明某一个设置就是唯一根因,完整重启也可能顺便重建了 HNS/FSE 状态。

当时确认有效的恢复命令需要在管理员 PowerShell 中执行:

netsh int ipv4 set dynamic tcp start=49152 num=16384
netsh int ipv6 set dynamic tcp start=49152 num=16384
dism.exe /online /enable-feature /featurename:HypervisorPlatform /all /norestart
Restart-Computer

这里最后一条不是可有可无。那次故障中,只关闭 WSL 或重启网络服务都不够,最终只能重启 Windows。执行前应先用下面的命令检查当前值,不要因为看到相同错误码就直接覆盖一台正常机器的端口配置:

netsh int ipv4 show dynamicport tcp
netsh int ipv6 show dynamicport tcp
dism.exe /online /Get-FeatureInfo /FeatureName:HypervisorPlatform

改用 Consomme 后,TUN 不再触发故障

后来我把 %UserProfile%\.wslconfig 的网络模式改成了 Consomme

[wsl2]
networkingMode=Consomme
dnsTunneling=true
autoProxy=true

修改后关闭全部 WSL 实例,再重新启动:

wsl --shutdown
wsl --version
wsl -e sh -lc "ip route; cat /etc/resolv.conf; docker info"

截至 2026 年 9 月 9 日,这台机器使用 WSL 2.9.11.0。Windows 上开启代理软件的 TUN 后,再由 Docker 命令启动 WSL,之前的 ConfigureNetworking/0x8007054f 没有复现,路由、DNS 和 Docker 联网都正常。

WSL 的 Consomme 技术说明显示,它为虚拟机提供 virtio-net 适配器,由 Windows 上的用户态 NAT 把 Linux 以太网帧转换成普通主机 Socket。流量因此沿用 Windows 的防火墙、VPN、代理和路由策略,不再依赖 Mirrored 的同一套接口镜像路径。这能解释本机为什么在 TUN 开启时也恢复稳定,但只能说明 Consomme 绕开了旧故障路径,不能反过来证明 Mirrored 的底层问题已经修复。

Consomme 目前仍是预览能力。微软在 WSL Containers 公开预览公告中把它称为面向 VPN、代理等复杂环境的实验性网络模式,而常规 .wslconfig 配置表暂时还没有列出它。首次使用前需要确认 WSL 版本支持;稳定版环境不识别时,不应把它当成通用修复命令。SmartScope 对这次预览的分析也提醒,WSL Containers 的 API 和 Compose 兼容范围仍有限。我这里只采用新的网络模式,Docker Engine 与 Compose 的使用方式没有改变。

启用 systemd

我的 /etc/wsl.conf 配置如下。公开文章里把实际用户名写成 TARGET_USER,使用时替换为发行版中已有的用户:

[boot]
systemd=true

[user]
default=TARGET_USER

[interop]
enabled=false
appendWindowsPath=false

我不需要从 WSL 调用 Windows 程序,所以关闭了互操作。这样会导致 powershell.exeexplorer.exe 等命令无法在 WSL 中运行。修改后回到 PowerShell 执行 wsl --shutdown,重新进入发行版即可生效。

zram 压缩交换

我使用过下面这组命令创建 zram swap,大小取 WSL 可见内存的一半:

sudo zramctl /dev/zram0 --algorithm lzo-rle --size "$(($(grep -Po 'MemTotal:\s*\K\d+' /proc/meminfo) / 2))KiB"
sudo mkswap -U clear /dev/zram0
sudo swapon --discard --priority 100 /dev/zram0

swapon --show

这要求当前 WSL2 内核已经提供 /dev/zram0 和对应压缩算法。它适合减少换页 I/O,但压缩数据仍然占用内存,不等于释放 Windows 磁盘空间。

关闭 zram:

sudo swapoff /dev/zram0

相关笔记