0%

WSL 2 完全指南:从工作原理到三个真实场景

WSL 2 完全指南:从工作原理到三个真实场景

引子:为什么你需要 WSL 2

很多人对 WSL 的印象还停留在”在 Windows 里开个 Linux 命令行玩玩”。如果只是这样,它不值得专门写一篇文章。

WSL 2 真正改变的,是 Windows 开发者获取 Linux 环境的成本。在它之前,你想在 Windows 上用一套像样的 Linux,只有三条路:

  • 装双系统:环境干净、性能最好,但每次切换要重启,两个世界的文件互不相通,做做停停的开发体验很差。
  • 开虚拟机(VMware / VirtualBox):能同时运行,但开机慢、常驻吃内存、和宿主机共享文件要靠笨重的共享文件夹,还和 Hyper-V 冲突。
  • 用 Git Bash / Cygwin 这类兼容层:轻,但它不是真 Linux,稍微复杂一点的工具(容器、systemd、内核特性)就跑不起来。

WSL 2 把这三条路的优点收拢到了一起:它在后台跑一台你几乎感觉不到的轻量虚拟机,里面是一个真正的 Linux 内核。开机以秒计,空闲时几乎不占资源,文件和 Windows 双向互通,甚至能把你显卡直通进去做机器学习。对绝大多数”我只是想要个 Linux 来写代码、跑容器、做实验”的需求,它已经是默认答案。

这篇文章会按这个顺序展开:先讲清楚它到底解决了什么、靠什么原理做到的,再讲怎么装(包括不走应用商店、用独立安装包部署 Ubuntu / AlmaLinux / RHEL 的方法),然后给出三个真实场景,最后是系统化的命令清单和故障排查

本文所述均默认指 WSL 2。写作时的稳定版本为 WSL 2.6.3,截止至发稿实践2026年6月5日,WSL最新版本为2.7.3,命令与配置项以WSL 2.6.3版本为准。


一、WSL 2 到底解决了什么

一句话定位:WSL 2 让你在不重启、不维护虚拟机、不牺牲文件互通的前提下,拿到一个系统调用完全兼容的真实 Linux 环境。

把它和传统虚拟机摆在一起对比,差异会很直观:

维度 传统虚拟机 WSL 2
启动 几十秒到几分钟,需要手动开关机 第一条命令触发,秒级,用完自动休眠
资源占用 预先划走固定内存/CPU,常驻 动态借还,空闲时几乎归零
文件互通 靠共享文件夹,慢且别扭 双向直通:Windows 里 \\wsl$ 访问 Linux,Linux 里 /mnt/c 访问 Windows
与 Windows 集成 基本是两台独立机器 命令行、端口、GPU、甚至 GUI 程序都能贯通
维护成本 要自己管内核、快照、网络 内核由微软维护并随 WSL 更新

需要强调的是,WSL 2 解决的是”内环开发(inner-loop development)”这一类问题——写代码、跑测试、调容器、做实验。它不是为了取代生产环境的服务器,也不是为了取代你需要完整桌面的那台 Linux 工作站(这两类场景见文末附录 B)。把定位摆正,后面所有取舍都好理解。

二、工作原理:它凭什么这么轻

这一节是全文的地基。理解了原理,后面安装时遇到的代理警告、故障排查时”为什么我有好几个 WSL”这类问题,都会变得理所当然。

2.1 WSL 1 与 WSL 2 是两套完全不同的东西

2016 年的初代 WSL(现称 WSL 1)走的是系统调用翻译路线:在 Windows 内核里实现一个兼容层,把 Linux 程序发出的 openforkread 实时翻译成 Windows NT 内核调用。好处是启动极快、和 Windows 互通极好;坏处是没有真正的 Linux 内核,凡是依赖 cgroups、namespaces 的工具(Docker 是典型)都跑不了,跨文件系统的 I/O 性能也差。

2019 年的 WSL 2 推倒重来,换成了虚拟化路线:在 Windows 里跑一台经过精简的 Hyper-V 轻量级工具虚拟机(utility VM),里面装一个由微软自行维护、源码开源的真实 Linux 内核。从此 WSL 里运行的是货真价实的 Linux,系统调用完全兼容,Docker、systemd、各类内核特性都能正常用。代价是跨 OS 文件访问(比如在 Linux 里频繁读 /mnt/c 下的 Windows 文件)会变慢——所以项目文件要放在 Linux 这一侧,这是性能上最重要的一条经验。

两者可以并存,单个发行版也能随时在 WSL 1 / WSL 2 之间切换(见后文 wsl --set-version)。但今天新装的发行版默认就是 WSL 2。

2.2 一台虚拟机,一个内核,多个发行版

这是 WSL 2 架构里最容易被误解、也最关键的一点:

无论你装了多少个发行版,它们都运行在同一台工具虚拟机里,共享同一个 Linux 内核。

按微软官方文档的说法,各发行版共享同一份网络命名空间、设备树(/dev/pts 除外)、CPU/内核/内存/Swap 以及 /init;但各自拥有独立的 PID、Mount、User、Cgroup 命名空间和独立的 init 进程。换句话说,发行版之间更像是同一台虚拟机里互相隔离的”容器”,而不是各自独立的虚拟机

下面这张图把两侧的组件和它们之间的桥梁画清楚了:

WSL 2 用的是 Hyper-V 的虚拟机监控程序/虚拟化平台那一层,启用它靠的是 Windows 的 “虚拟机平台”(Virtual Machine Platform) 这个可选功能;它不等于控制面板里那个完整的 “Hyper-V” 功能(带 Hyper-V 管理器那一套)。

2.3 答疑:一个内核,多个发行版

上一节那句”一台虚拟机、一个内核、多个发行版”,初次接触时很容易冒出两个疑问。这两个问题问得都对,但都卡在同一个误解上——把”发行版”和”内核”当成了一回事。把这层捅破,疑惑就化开了。

先记住下面这张图的一句话:各发行版不同的是”用户态”,共用的是同一个内核。

问一:wsl -l -o 里 Ubuntu 22.04 / 24.04 / 26.04 的内核版本都不一样,怎么可能都装进同一套 WSL?

答:因为前提不成立——这几个版本真正不同的,并不是内核。

一个 Linux 发行版,专属于它自己、各版本不同的东西,是用户态(userland):那套根文件系统——glibc、coreutils、apt/dpkg、各种库、/etc 配置、默认软件包集合等等。Ubuntu 22.04、24.04、26.04 之间的区别,主要就是这套用户态不同(库和软件的版本不同),而不是内核不同。内核在一套系统里是一个可以单独替换的部件,不是发行版的”身份证”。

而 WSL 2 做的事,恰恰就是把内核从发行版里”摘”了出来:你装 Ubuntu-24.04 时,WSL 只取了它的用户态 rootfs,Ubuntu 镜像里自带的那个内核包根本没被用上。三个 Ubuntu 跑起来,底下是同一个微软维护的内核。所以 wsl -l --online 那张列表,本质是一张**”用户态镜像清单”,而不是”内核清单”**——它们之所以都能装,正因为内核不在里头,由微软统一供给。

那换了内核为什么还能跑? 靠的是 Linux 内核对用户态的 ABI 向后兼容(Linus 那条著名铁律:”绝不破坏用户态”):为较老内核写的用户态程序,放到更新的内核上照样能跑。老版本 Ubuntu 的用户态所期望的那些系统调用,微软那个更新的内核全都支持;于是新老 Ubuntu 的用户态,都能稳稳跑在同一个内核上。

一个你熟悉的类比:容器。 你能在同一台主机上同时跑 ubuntu:22.04ubuntu:24.04centos 三个容器,正是因为容器共享宿主机内核,只是用户态镜像不同。WSL 2 的多发行版就是这个模型:一个内核(微软的)+ 多套用户态(各发行版的)

问二:既然 Ubuntu-26 和 Ubuntu-24 共用一个内核,那还装不同版本干嘛?有什么意义?

答:因为内核恰恰是你最不常打交道的那部分——你日常真正在用的东西几乎全在用户态里,而用户态正是各版本不同的地方。 所以”共用内核”完全不影响你为什么要挑某个版本。装哪个版本,你实际在选的是这些(全是用户态的事,与内核无关):

  1. 软件和工具链的版本。 不同 LTS 自带的 glibc、Python、GCC、OpenSSL、systemd 版本都不一样。最好记的例子是 Python:22.04 自带 3.10,24.04 自带 3.12。你要某个版本的工具链,就得选对应的 Ubuntu。
  2. 和生产环境保持一致(做基础设施的人,这通常是头号理由)。 服务器跑 22.04,你就在 WSL 里也装 22.04 来开发,glibc、库版本都对得上,”在我机器上能跑”才能真正搬到服务器上不出幺蛾子。换个版本 glibc 一变,编出来的东西可能就不兼容了。
  3. 支持周期不同。 每个 LTS 有各自的安全更新截止时间(EOL)。选哪个,决定了这套用户态还能领多久的安全补丁。
  4. 并存测试。 你可以同时装 22.04、24.04、26.04,把同一个软件分别在三套用户态上编译/运行验证兼容性——而这一切不用开三台虚拟机,因为它们共用同一个内核、各自只是一份用户态,极其轻量。

还是那个容器类比:你在一台主机上同时跑 ubuntu:22.04ubuntu:24.04 两个镜像,也是共享宿主机内核的,但你照样会认真挑用哪个镜像——因为镜像(用户态)才是你的程序真正依赖的东西

所以”共用内核”不但不让多版本变得多余,反而正好说明:区分发行版版本的从来不是内核,而是它那套用户态。 内核被微软统一接管后,你挑版本时反而可以纯粹按”我要哪套库、哪个工具链、对齐哪个生产环境”来决定。

怎么选很简单: 没有特殊要求就装最新的 LTS(工具最新、支持最久);要对齐线上服务器就装和服务器一样的版本;有老软件依赖老 glibc,就装对应的老 LTS

自己动手验证

装两个不同版本的 Ubuntu,分别执行:

1
2
uname -r              # 内核版本 —— 两个发行版显示【完全相同】的微软内核
cat /etc/os-release # 发行版信息 —— 这里才看到 22.04 / 24.04 的【不同】

uname -r 一致、os-release 不同——这就是”一个内核、多个发行版”最直接的铁证:内核共用,用户态各异。

补一个边界:就算你想换内核,也是在 .wslconfig 里用 kernel=整台虚拟机指定一个自定义内核、所有发行版一起用,仍然是”一台虚拟机、一个内核”。WSL 里不存在”每个发行版各带各的内核”这回事。

2.3 关键组件:两侧各干什么

Windows 这一侧:

  • wsl.exe:命令行入口,你敲的每一条 wsl ... 都由它接收。
  • wslservice.exe:核心服务进程。负责拉起、管理、关闭那台工具虚拟机,是整个 WSL 的”大脑”。wsl.exewslg.exe 等都通过 COM 调用它。
  • p9rdr.sys:一个特殊的重定向驱动。当你在资源管理器里访问 \\wsl$\Ubuntu 时,正是它把请求转给虚拟机里的文件服务。

下图是我们典型的windows资源管理器的wslservice.exe进程

虚拟机这一侧:

  • 真实 Linux 内核:微软维护、开源(仓库 microsoft/WSL2-Linux-Kernel),所有发行版共用。
  • init / mini_init:负责虚拟机和各发行版的启动。
  • gns:管理虚拟机内的网络配置。
  • plan9 / VirtioFS:文件共享服务。plan9 用的是贝尔实验室的 9P 协议(较老);VirtioFS 是更新、性能更好的方案。Windows 访问 Linux 文件(\\wsl$)就是通过它们实现的。

两侧之间靠 hvsocket 通信——这是 Hyper-V 提供的、专门用于宿主机与虚拟机之间通信的套接字。文件、网络状态、端口转发都走它。

2.4 文件为什么能双向互通

  • 从 Windows 看 Linux:访问 \\wsl$\<发行版名>\\wsl.localhost\<发行版名>,由 p9rdr.sys + 虚拟机里的 plan9/VirtioFS 服务一起完成。
  • 从 Linux 看 Windows:Windows 的盘符被挂载在 /mnt/c/mnt/d 下(这套机制叫 DrvFs)。

值得一提的是:WSL 2 不是把显卡”直通”给 Linux,而是靠微软的 GPU 半虚拟化:内核里的 dxgkrnl 驱动经 /dev/dxg 和 VMBus 把 GPU 请求转给主机执行;NVIDIA 的 Windows 驱动则把 CUDA 用户态库映射进 /usr/lib/wsl/lib/,因此 WSL 里无需再装显卡驱动

三、安装所需环境

开始安装前,确认两项前置条件,否则后续步骤可能卡住。

Windows 版本:按 Win+R 调出运行窗口,输入 winver 回车查看版本号。Windows 10 需为 2004 版(Build 19041)或更高,Windows 11 全部版本均支持。版本过低请先通过 Windows Update 升级。

虚拟化已开启:打开任务管理器(Ctrl+Shift+Esc),切到”性能”标签页,CPU 一栏下方会显示”虚拟化:已启用 / 已禁用”。

正确的虚拟化开启界面详见下图

若显示”已禁用”,需重启进入 BIOS 启用相关选项(Intel 平台叫 VT-x,AMD 平台叫 AMD-V 或 SVM)。各品牌主板进入 BIOS 的方式不同,请按自己主板型号查询。

四、在线安装

4.1 标准安装

以管理员身份打开 PowerShell(开始菜单上右键 →”终端(管理员)”),执行:

1
wsl --install

即可。该命令会自动启用所需的 Windows 功能、下载 WSL 主程序,并安装默认的 Ubuntu 发行版。

如果想只装 WSL、不要默认发行版,用 wsl --install --no-distribution参数

输出大致如下:

1
2
3
4
5
6
7
8
9
10
正在下载: 适用于 Linux 的 Windows 子系统 2.6.3
正在安装: 适用于 Linux 的 Windows 子系统 2.6.3
已安装 适用于 Linux 的 Windows 子系统 2.6.3。
操作成功完成。
正在下载: Ubuntu
正在安装: Ubuntu
已成功安装分发。可以通过 "wsl.exe -d Ubuntu" 启动它
正在启动 Ubuntu...

wsl: 检测到 localhost 代理配置,但未镜像到 WSL。NAT 模式下的 WSL 不支持 localhost 代理

过程中出现的 localhost 代理警告暂可忽略,后面”配置 .wslconfig”一节会统一处理。

安装完成后 Ubuntu 会自动启动,提示创建 Linux 用户名与密码。两点注意:

  • 这里的用户名密码仅用于 Linux 子系统内部,和 Windows 登录账号无关。
  • 输入密码时屏幕不回显星号或圆点,这是正常现象,照常输入即可,不是键盘失灵。

4.2 安装指定发行版

不想用 Ubuntu,先看可用清单:

1
2
3
wsl --list --online  
# 或
wsl -l -o

会列出多种可选发行版(Ubuntu 各版本、Debian、Kali、AlmaLinux、Oracle Linux、openSUSE、Fedora、Arch 等)。然后用 -d 指定:

1
2
wsl --install -d Debian
wsl --install -d AlmaLinux-9

4.3 验证

1
wsl -l -v

输出类似:

1
2
  NAME      STATE           VERSION
* Ubuntu Running 2

STATERunningVERSION2 即表示装好了。行首星号是默认发行版。

五、离线安装

wsl --install -d <name> 走的是微软的在线分发。但在很多真实场景里这条路走不通或不合适:内网/离线环境需要特定企业发行版(RHEL)要把一份定制好的镜像批量分发给团队。这时就要用独立安装包/镜像来部署。

先把三种镜像格式和对应命令理清楚,这是这一节的总纲:

格式 本质 安装命令 适用
.wsl 带配置的根文件系统 tar 包(WSL 原生格式) 双击,或 wsl --install --from-file xxx.wsl 官方/社区发布的现代镜像,最省事
.tar / .tar.gz 纯根文件系统归档 wsl --import <名> <安装目录> <文件> 从容器导出、厂商提供的 tar 镜像
.vhdx 已格式化为 ext4 的虚拟硬盘 wsl --import-in-place <名> <文件.vhdx> 迁移、就地挂载已有磁盘

.wsl 格式与 --from-file 需要 WSL 2.4.4 及以上;先 wsl --update 升级。

下面按发行版给出具体做法。

5.1 Ubuntu

Ubuntu 既在商店里,也提供独立的 .wsl

地址;https://ubuntu.com/download/wsl
拿到 .wsl 文件后,最简单的方式是双击,或:

1
wsl --install --from-file ubuntu-24.04.wsl

5.2 AlmaLinux

AlmaLinux 官方在 GitHub 上提供 .wsl 镜像:github.com/AlmaLinux/wsl-images/releases。下载后双击安装,或:

1
2
# 离线安装:直接喂给 WSL 一个本地 .wsl 文件
wsl --install --from-file AlmaLinux-9.wsl

这对内网部署特别友好:把 .wsl 文件拷进内网机器即可装,全程不依赖应用商店。

5.3 RHEL(Red Hat Enterprise Linux)

RHEL 的情况和社区发行版不同,值得单独说:

  • 应用商店里没有 RHEL,但从 2025 年起红帽官方支持把 RHEL 跑在 WSL 上。
  • 你需要一个有效的 RHEL 订阅——红帽开发者订阅是免费的(个人开发用途,有效期一年可续),足够学习和开发。
  • 取得镜像有两条路:① 在红帽客户门户的下载区直接下预构建的 WSL 镜像(.tar.gz);② 用红帽的 Image Builder 定制一份镜像,选择目标环境为 “WSL”,构建后下载 .tar.gz

拿到 .tar.gz 后用 --import 导入(也是所有 tar 镜像的通用方法):

1
2
3
4
5
6
7
8
9
# 先建好存放目录
mkdir C:\WSL\RHEL10

# 导入:<发行版名> <安装目录> <tar 文件>
wsl --import RHEL10 C:\WSL\RHEL10 "C:\Users\<你>\Downloads\rhel-10.0-x86_64-wsl2.tar.gz" --version 2

# 进入并注册订阅
wsl -d RHEL10
subscription-manager register # 用红帽账号注册后即可用 dnf 拉包

--import 导入的发行版,默认以 root 登录。需要改默认用户的话,可在镜像内 /etc/wsl.conf[user]\ndefault=<用户名>,或对 Ubuntu 这类用 ubuntu config --default-user <user>

5.4 从任意容器镜像造一个 WSL 发行版

如果某个发行版连 tar 包、.wsl 包都找不到,还有一条万能路:从容器镜像导出根文件系统,再导入 WSL。这并不是什么野路子——它正是微软官方文档推荐的”导入任意发行版”做法:只要某个发行版有对应的容器镜像,就能把它搬进 WSL。

官方依据
微软官方文档《Import any Linux distribution to use with WSL》开篇即说明,你可以在 WSL 里使用任何 Linux 发行版,”even if it is not available in the Microsoft Store”(哪怕它不在 Microsoft Store 里),方法就是用一个 tar 文件把它导入。该文以 CentOS 为例,并指出”此流程可套用于导入任何发行版”。
原文链接:https://learn.microsoft.com/en-us/windows/wsl/use-custom-distro(示例用 CentOS,最后更新 2024-07-16)

核心就两步:先在一个已有的 Linux 环境(比如现成的某个 WSL 发行版)里,把容器的根文件系统导出成 tar;再回到 PowerShell 用 wsl --import 导入。

第一步:导出 rootfs(在已有 Linux 环境里执行)

关键:用 export,不要用 save
export 导出的是容器的扁平根文件系统(单层 tar,丢掉镜像分层与元数据),正是 wsl --import 想要的;save 保留的是镜像的分层和元数据,wsl --import 读不了。

1
2
3
4
# 以 podman 为例(docker 命令同理,把 podman 换成 docker 即可)
podman create --name tmp <some-image> # 从镜像建容器,自动拉取,无需启动
podman export -o /mnt/c/wslsources/mydistro.tar tmp # 导出 rootfs(注意:export,不是 save)
podman rm tmp # 清理临时容器

微软官方原文里的等价命令(用 Docker),可对照参考

第二步:导入 WSL(在 PowerShell 里执行)

1
2
3
4
5
6
7
8
9
# 先建好存放目录
mkdir C:\WSL\MyDistro

# wsl --import <发行版名> <安装目录> <tar 文件> [选项]
wsl --import MyDistro C:\WSL\MyDistro C:\wslsources\mydistro.tar --version 2

# 验证并进入
wsl -l -v
wsl -d MyDistro

导入后要做的事:建普通用户

--import 导入的发行版**默认以 root 登录、没有普通用户、没有 /etc/wsl.conf**。按官方建议,进去建好用户并设为默认登录用户即可(装 sudo/passwd 的命令因发行版而异:Debian/Ubuntu 用 apt,RHEL 系用 dnf/yum;加入 sudo 组时 Debian 系用 sudo 组、RHEL 系用 wheel 组):

1
2
3
4
5
# 在导入的发行版内执行(以 RHEL 系、用户名 ethan 为例)
yum install -y passwd sudo
useradd -G wheel ethan
passwd ethan
printf '[user]\ndefault=ethan\n' >> /etc/wsl.conf

改完在 PowerShell 里 wsl --terminate MyDistrowsl -d MyDistro 重进,即可看到默认用户已切换为 ethan

几点提示

  • export 会丢掉镜像的 ENVCMD、暴露端口等元数据(WSL 用不到,无影响),但有些精简镜像缺 sudo、locale 等,需要自行补装。
  • tar 文件名里不能含冒号 :(podman/docker 的限制)。
  • 这套”容器导出 → wsl --import“的方法,几乎能把任何有容器镜像的 Linux 发行版搬进 WSL,对内网/离线和需要定制镜像的场景尤其好用。

六、配置 .wslconfig

首先说明的是:.wslconfig 是可选的,装完 WSL 不碰它也能正常用,大多数人自始至终都不需要它。

6.1 它是什么、改完怎么生效

.wslconfig 管的是整台工具虚拟机的全局参数(内存、CPU、网络等),作用于所有发行版。注意和它区分:每个发行版内部的 /etc/wsl.conf 只管单个发行版(默认用户、是否启用 systemd 等)。

  • 位置:C:\Users\<你的Windows用户名>\.wslconfig,默认不存在,需手动创建
  • 生效时机:只在虚拟机启动时读取一次。所以改完必须 wsl --shutdown 关掉虚拟机,下次启动才生效。

创建时的坑:文件名以英文句点开头、没有扩展名。资源管理器默认隐藏扩展名,看似 .wslconfig 的文件实际可能是 .wslconfig.txt。建议先在资源管理器里勾选”文件扩展名”显示,确认无误。

6.2 先了解默认值——多数情况下你根本不用改

在动手加配置前,先知道”不配的时候是什么样”,你会发现绝大多数项保持默认就挺好:

  • 内存:默认上限约为主机物理内存的 50%,且会动态借还,空闲时归还给 Windows。
  • Swap:默认约为可用内存的 **25%**。
  • 处理器:默认使用全部逻辑核心。
  • 网络模式:默认是 NAT(不是镜像模式)。
  • 内存自动回收 / DNS 隧道:在当前版本的 WSL 里,autoMemoryReclaim(默认 gradual)和 dnsTunneling 已是默认开启——所以再手动写这两项多半是冗余。

换句话说,原先那种”装完就抄一大段 .wslconfig“的做法,一半的项是在重复默认值,另一半(比如写死 memory=8GB)反而可能帮倒忙。

6.3 按问题查:真正可能用到的几个开关

只在你确实遇到对应问题时,才加下面对应的一项:

你遇到的问题 加这个 代价 / 注意
WSL 里访问不了 Windows 的 localhost 服务 / 代理,或连 VPN 后网络异常 [wsl2]
networkingMode=mirrored
非默认。镜像模式能改善 localhost、VPN、代理互通,但有兼容性取舍——某些端口绑定场景会报 “Address already in use”(如 VS Code Remote 容器),遇到再回退 NAT 排查。
WSL 跑大型构建/多容器,把宿主机内存吃光,想设上限 [wsl2]
memory=<按你机器填>
不要照抄数字。 取决于你这台机器有多少内存:16G 机器写 memory=8GB 偏激进,64G 机器写 8G 又太抠。不确定就别写,保持默认动态分配。
想限制/解除 CPU、Swap [wsl2]
processors=N / swap=<大小>
同上,默认通常够用。把 swap 设为 swap=0 可关闭交换文件。
ext4.vhdx 删了文件却不缩小,C 盘越用越满 [experimental]
sparseVhd=true
让新建发行版的虚拟磁盘可动态收缩。是否默认开启各版本有出入,要确保开启就显式写;对已存在的发行版用 wsl --manage <名> --set-sparse true
WSL 空闲时还占着内存不放 [experimental]
autoMemoryReclaim=gradual
当前版本通常已默认 gradual,一般不用写。Docker 用户例外:可设为 dropcachedisabled 以免干扰容器。

关于 firewallautoProxy 这类网络集成项:它们在受支持的 Windows 11 上往往已经默认生效,是否需要显式写、当前默认值如何,各版本不一。与其照抄,不如用 wsl --status 看一眼,或查官方文档 Advanced settings configuration in WSL 确认后再决定。

七、三个典型场景

光会装没用,下面三个是 WSL 2 最有代表性、也最能体现”它解决了什么”的场景。

7.1 场景一:容器开发——Docker / Podman Desktop 的后端

这是 WSL 2 最主流的用途。Docker Desktop 和 Podman Desktop 在 Windows 上都把 WSL 2 当作运行后端:容器并不是直接跑在 Windows 上,而是跑在 WSL 2 的那台轻量虚拟机里。

  • Docker Desktop:启用 WSL 2 后端后,它会自己创建一个名为 docker-desktop 的发行版作为引擎(旧版本还会有 docker-desktop-data)。在 Settings → Resources → WSL Integration 里可以把你常用的发行版(如 Ubuntu)勾上,这样在 Ubuntu 终端里就能直接敲 docker 命令。
  • Podman Desktop:在 Windows 上同样依赖 WSL 2——它创建的 “Podman machine” 本质就是 WSL 2 里的一台 Linux 虚拟机,容器在这台机器里运行。安装 Podman Desktop 时会检查并提示你装好 WSL 2。

理解了第二节的”单虚拟机 + 多容器”模型,你就明白为什么这些工具能这么轻:它们没有再去开一台独立虚拟机,而是复用了 WSL 2 的体系。

7.2 场景二:GPU 直通——在 Windows 上做机器学习

过去想在 Windows 上用 GPU 训练模型很折腾:TensorFlow 早已放弃 Windows 原生 GPU 支持,PyTorch 体验也不如 Linux。WSL 2 提供了官方的 GPU 直通

  • 在 Windows 装好最新的 NVIDIA 驱动(驱动本身已包含对 WSL 的支持,WSL 里不要再单独装显卡驱动)。
  • NVIDIA 驱动会把 CUDA 库暴露进 WSL 的 /usr/lib/wsl/lib/,Linux 侧通过标准的 libcuda.so 访问,应用程序就像跑在原生 Linux 上一样。
  • 在 WSL 的 Ubuntu 里装 CUDA Toolkit、cuDNN,再装 PyTorch / TensorFlow,即可用本机显卡跑训练;nvidia-smi 能看到你的显卡。

如果再叠加场景一,把容器也用上(Podman/Docker + NVIDIA Container Toolkit),就能在容器里跑 GPU 工作负载——比如本地起一个带 GPU 加速的 Ollama 跑大模型。这条链路的 GPU 直通要打通两层:Windows → WSL 2 虚拟机,再 WSL 2 虚拟机 → 容器。

7.3 场景三:VS Code 远程开发——Remote - WSL

这是日常写代码最顺手的一种用法,也是 WSL 体验的招牌。装上 VS Code 的 WSL(Remote - WSL)扩展后,在 WSL 里切到项目目录执行:

1
code .

Windows 端的 VS Code 会自动连接到 WSL:IDE 跑在 Windows,文件存储与编译过程全部在 Linux,几乎没有延迟。你在 Windows 上享受 VS Code 的完整生态(插件、调试器、图形界面),代码却始终待在性能最好的 Linux 文件系统里——前面讲过,项目文件放 Linux 侧是性能关键,这个工作流天然就做对了。

八、常用命令:系统化清单

下面六组覆盖了日常 95% 的需求。

8.1 查询与状态

1
2
3
4
5
6
wsl -l -v                 # 列出所有发行版及状态/版本(最常用)
wsl -l -o # 列出可在线安装的发行版
wsl -l --all # 列出全部,包括处于异常状态的
wsl --list --running # 只列出正在运行的
wsl --status # WSL 整体状态:默认发行版、默认版本、内核版本
wsl --version # WSL、内核、WSLg 等组件的版本号

8.2 进入与运行

1
2
3
4
wsl                       # 进入默认发行版
wsl -d <name> # 进入指定发行版
wsl -d <name> -u root # 以 root 进入指定发行版
wsl -d <name> -- <命令> # 不进入交互式 shell,直接在该发行版里跑一条命令

8.3 生命周期

1
2
3
4
wsl --shutdown            # 关闭所有发行版和整台虚拟机(改 .wslconfig 后用它生效)
wsl --terminate <name> # 只关闭某一个发行版(不影响虚拟机和其他发行版)
wsl --set-default <name> # 设置默认发行版(也可写 wsl -s <name>)
wsl --unregister <name> # 注销发行版(⚠ 数据全删,不进回收站,不可恢复)

wsl --unregister 要格外谨慎,它会永久删除整个发行版及其全部数据

wsl --shutdown 关掉整台虚拟机(所有发行版一起停);wsl --terminate <名称> 只停指定的那一个发行版,虚拟机和其他发行版照常运行。

8.4 备份与迁移

先理解一个概念:ext4.vhdx
每个 WSL 2 发行版的全部数据(你的文件、装的软件、容器镜像……)都存放在一个名为 ext4.vhdx 的虚拟硬盘文件里,默认位于 C:\Users\<你>\AppData\Local\wsl\...\ 下。它就是这个发行版的”活动磁盘”。本组命令本质上都是围绕这个文件做文章——理解了它,下面四条就都好懂了。(它”只增不减、删文件不自动缩小”的特性,见第九节磁盘回收。)

我电脑中一个AlmaLinux10发行版的镜像文件在windows中的存储位置如下:

① 备份 / 恢复 / 克隆(通过 tar)

1
2
3
4
# 把发行版导出成一个 tar 归档(备份)
wsl --export <name> D:\backup\ubuntu.tar
# 从 tar 恢复,或克隆一份到新位置/新名字
wsl --import <name> D:\WSL\ubuntu D:\backup\ubuntu.tar --version 2

注:省略 --version 2 时,你拿到的是 1 还是 2 是不确定的,取决于这台机器的默认设置,建议保留这个参数

这一对走的是 tar 归档:跨机器搬家、留存快照、克隆一份做实验,都用它。tar 通用、好压缩、与平台无关。
也可以改用 vhd 格式导出/导入(保留磁盘本身而非打包文件系统):

1
2
wsl --export <name> D:\backup\ubuntu.vhdx --vhd
wsl --import <name> D:\WSL\ubuntu D:\backup\ubuntu.vhdx --vhd

② 就地挂载一个已存在的 ext4.vhdx

1
wsl --import-in-place <name> D:\WSL\ubuntu\ext4.vhdx

这条和 ① 不一样:它不解包、不复制,而是把一个已经存在的 ext4.vhdx 文件直接注册回 WSL,原样挂载使用。
典型场景:你把旧机器上的 ext4.vhdx 整个拷了过来,或者之前 --unregister 时保留了这个 vhdx 文件,现在想原样挂回来继续用。
注意:这里的 vhdx 必须是 WSL 自己那种 ext4 格式的磁盘,不是随便一个虚拟硬盘文件。

③ 整体移动到另一个盘

1
wsl --manage <name> --move D:\WSL\ubuntu

C 盘告急时最实用:把发行版连同它的 ext4.vhdx 一起搬到 D 盘,WSL 会自动更新登记的位置,不用你手动 export 再 import。

这三者的关系: 是”打包成文件搬来搬去”, 是”已有的磁盘文件挂回来”, 是”原地换个盘存放”。前两者面向”分发/恢复”,第三者面向”腾挪空间”。

8.5 配置与维护

1
2
3
4
wsl --update                          # 更新 WSL 自身
wsl --manage <name> --set-sparse true # 让该发行版的 ext4.vhdx 启用稀疏,删文件后能回收空间
wsl --manage <name> --resize 64GB # 调整该发行版 ext4.vhdx 的容量上限
ubuntu config --default-user <user> # 设置 Ubuntu 默认登录用户

--set-sparse--resize 操作的都是 8.4 里说的那个 ext4.vhdxubuntu config 是 Ubuntu 启动器专有的命令;用 --import 导入、没有启动器的发行版,改默认用户要在其内部的 /etc/wsl.conf 里写 [user]default=<用户名>

8.6 版本转换(WSL 1 ↔ WSL 2)

1
2
wsl --set-version <name> 2   # 把某发行版转为 WSL 2
wsl --set-default-version 2 # 之后新装的发行版默认用 WSL 2

转换会就地重建该发行版的磁盘,数据量大时耗时较长,转换前最好先用 8.4 的 --export 备份一份。

九、故障排查

9.1 “我怎么有好几个 WSL?”——单虚拟机模型与验证

这是最常见的困惑。你只装了一个 Ubuntu,wsl -l -v 却列出来一堆:

1
2
3
4
5
  NAME                   STATE       VERSION
* Ubuntu Running 2
docker-desktop Running 2
docker-desktop-data Stopped 2
rancher-desktop Stopped 2

这不是”装了好几个 WSL”,更不是”开了好几台虚拟机”。 回到第二节的原理:

  1. 全机只有一台工具虚拟机。 你看到的所有条目都是同一台虚拟机里互相隔离的发行版(容器),共享同一个内核。
  2. 多出来的那些是工具自己建的后端docker-desktopdocker-desktop-datarancher-desktop 分别是 Docker Desktop、Rancher Desktop 创建的引擎/数据卷,并不是你手动装的”真发行版”。卸掉对应工具,它们就消失。

怎么验证”确实只有一台虚拟机”:

  • 看内核版本:分别进几个发行版执行 uname -r,会发现内核版本号完全一致——因为它们共用同一个内核。

    1
    2
    wsl -d Ubuntu         -- uname -r
    wsl -d docker-desktop -- uname -r # 输出与上面相同
  • 看进程:打开任务管理器,整台 WSL 虚拟机在 Windows 侧只对应一个 Vmmem / vmmemWSL 进程,而不是每个发行版一个。

  • 看谁在跑wsl --list --running 只列出当前真正运行的发行版,区分”装了”和”在跑”。

想确认哪些是你需要的、哪些是工具残留,对照名字即可。确实不需要的,用 wsl --unregister <name> 清理(注意数据会删)。

9.2 磁盘只增不减

WSL 2 每个发行版用一个 ext4.vhdx 虚拟磁盘存数据。这个文件会随数据增长,但删了数据它不会自动缩小——于是 C 盘越用越满,删了文件也不见好转。容器镜像、构建产物是常见的”吃盘大户”。

处理办法(按推荐顺序):

  1. 先在 Linux 里清理并释放

    1
    2
    3
    sudo apt clean        # 或 dnf clean all
    docker system prune # 用容器的话,清无用镜像
    sudo fstrim -av # 把已删除块标记为可回收
  2. 开启稀疏磁盘自动回收(一劳永逸,需 WSL 2.0+):

    1
    2
    wsl --shutdown
    wsl --manage Ubuntu --set-sparse true

    或在 .wslconfig 里写 [experimental]\nsparseVhd=true,让新建发行版默认启用。

  3. 手动压紧 vhdx(彻底回收,操作前务必 wsl --shutdown 让文件不被占用):用 Hyper-V 的 Optimize-VHD(Pro/企业版有 Hyper-V)或 diskpartcompact vdisk 对那个 ext4.vhdx 压缩。

9.3 网络与代理问题

  • WSL 里访问不了 Windows 上的代理 / localhost 服务:检查 .wslconfig 是否启用了 networkingMode=mirroredautoProxy,改完别忘 wsl --shutdown
  • 连企业 VPN 后 DNS 解析失败:开启 dnsTunneling=true
  • 镜像网络下个别服务端口冲突:临时去掉 networkingMode=mirrored 回到 NAT 模式定位问题。

9.4 GUI / 显示问题

WSL 2 自带 WSLg,可直接在 Windows 桌面上显示 Linux GUI 程序。如果图形程序起不来,先 wsl --update 升级(WSLg 随 WSL 更新),再 wsl --shutdown 重启虚拟机。注意 WSL 适合偶尔跑跑 GUI 工具,不适合当主力桌面环境(见附录 B)。

9.5 通用排查手段

  • wsl --status:看整体状态(默认发行版、版本、内核)。
  • 进入发行版后 dmesg:看内核日志。
  • wsl --update + wsl --shutdown:很多疑难杂症,”升级到最新 + 重启虚拟机”能解决一大半。

附录 A:WSL 的演进

简要交代 WSL 能保持轻量的技术背景。

  • 2016 年,微软首次推出 WSL(现称 WSL 1),核心是系统调用翻译:在 Windows 内核里实现兼容层,实时把 Linux 系统调用翻译成 NT 调用。启动快、互通好,但没有真内核,Docker 这类工具跑不了,文件 I/O 也慢。
  • 2019 年,微软推倒重来,改用虚拟化:在 Windows 里跑一台精简的 Hyper-V 虚拟机,装上微软自维护、源码开源的真实 Linux 内核。系统调用完全兼容,Docker、systemd 等都能用。
  • 2025 年 Build 大会,微软宣布 WSL 正式开源(仅文件系统接口的少量驱动如 p9rdr.sys 仍闭源),关掉了 WSL 仓库九年前的第一条 Issue:”这会开源吗?”。同年 WSL 2.6 成为首个开源后的功能版本。
  • 如今,WSL 已从 Windows 系统组件中独立出来,成为可通过 Microsoft Store 单独安装与更新的开源项目,迭代速度明显加快。

附录 B:不适用 WSL 的场景

WSL 并非万能。以下几类仍建议用传统虚拟机或物理机:

  • 需要完整 Linux 桌面环境(GNOME、KDE)。WSL 虽能跑 GUI 程序,但不适合当主力桌面。
  • 内核开发,或对安全沙箱有严格要求。WSL 用的是微软定制内核,用户无法自由替换。
  • 运行与 Windows 网络栈高度耦合、频繁改防火墙规则的工具——这类工具容易和 WSL 冲突。

参考资料

  • Microsoft Learn:What is WSL / Comparing WSL Versions / Open Source WSL
  • WSL 开源技术文档站:wsl.dev
  • Microsoft Learn:Basic commands for WSL、How to manage WSL disk space
  • Red Hat Developer:Getting started with RHEL on WSL
  • AlmaLinux Wiki:AlmaLinux WSL
  • Docker Docs:Docker Desktop WSL 2 backend
  • Podman Desktop:GPU container access
  • NVIDIA:CUDA on WSL User Guide