【笔记】WSL 的架构、互操作与使用边界
WSL 不是一种固定实现,而是 Windows 提供的 Linux 运行与集成环境。WSL 1 通过系统调用转换运行 Linux binary;WSL 2 在受管理的轻量虚拟机中运行真实 Linux kernel。二者给用户暴露相近的发行版和命令体验,但 kernel、文件、网络与资源边界完全不同。
1. 中心模型:WSL 统一了体验,没有消除边界
flowchart TB
U[Windows User]
W[wsl.exe / WSL Service]
D1[Linux Distribution A]
D2[Linux Distribution B]
K[Microsoft-maintained Linux Kernel]
VM[Managed Utility VM]
WIN[Windows Kernel / Files / Network]
U --> W
W --> D1
W --> D2
D1 --> K
D2 --> K
K --> VM
VM <--> WIN
在 WSL 2 中,Windows 负责 VM 生命周期、kernel 更新、资源与集成;发行版提供自己的 Linux userspace、package、用户和 root filesystem。多个发行版不是多台需要分别配置硬件的传统 VM,但也不是同一个 userspace。
需要始终区分:
- Windows process 与 Linux process;
- Windows filesystem 与发行版 Linux filesystem;
- Windows shell 语法与 Linux shell 语法;
- WSL 全局配置与单个发行版配置;
- WSL managed VM 与发行版实例。
2. WSL 1:系统调用转换层
WSL 1 没有运行真实 Linux kernel。Linux binary 发起 system call 后,由 WSL translation layer 将其映射到 Windows kernel 能力。
1
2
3
4
Linux ELF process
→ Linux system call ABI
→ WSL translation layer
→ Windows kernel
它的优势是没有独立 VM 内存与虚拟磁盘边界,访问 Windows filesystem 的路径通常更直接。限制也来自同一处:Linux kernel ABI 必须由转换层实现,新的或复杂的 kernel feature 不会自动获得完整兼容。
因此 WSL 1 不是“运行一个被精简的 Linux kernel”,也不是传统意义上的硬件虚拟机。它更接近 Windows kernel 上的 Linux ABI compatibility subsystem。
3. WSL 2:真实 Linux kernel + managed utility VM
WSL 2 使用 Microsoft 维护的开源 Linux kernel,并借助虚拟化技术运行在轻量 utility VM 中。Linux system call 由真实 Linux kernel 处理,不再逐项翻译到 Windows system call。
1
2
3
4
5
Linux process
→ Linux system call
→ WSL Linux kernel
→ virtualized CPU / memory / device boundary
→ Windows / Hyper-V platform
3.1 它是真 VM,但不是传统 VM 产品体验
WSL 2 具有 Guest kernel、虚拟 CPU、内存、虚拟磁盘和网络边界,因此属于硬件辅助虚拟化。但用户通常不需要选择固件、手工挂载 ISO、创建虚拟网卡或管理快照。
WSL service 负责按需启动、空闲回收、kernel servicing、发行版挂载和 Windows 集成。与 VMware Workstation、Parallels Desktop 等通用 VM 产品相比,区别首先是产品抽象和控制面收窄,而不是“一个是真虚拟化、另一个不是”。
3.2 发行版不是一台独立配置的 VM
一个 WSL distribution 主要是一套 Linux userspace、root filesystem、用户配置与发行版状态。WSL 2 distributions 由 WSL 管理并共享底层 VM/kernel 资源,同时通过 process、mount、user 等 namespace 隔离各自 userspace。
这解释了两个现象:
wsl -l -v列出的是发行版实例,不是传统 Hyper-V Manager 中的一组完整 VM;.wslconfig的 CPU、内存、swap、kernel 等配置作用于整体 WSL 2 VM,而不是某一个发行版。
3.3 看不到 VirtIO 不代表没有虚拟化
VirtIO 是一种虚拟设备规范,不是 Hypervisor 的必选项。Hyper-V 使用 VMBus 和 synthetic devices 等自己的虚拟化接口。WSL kernel 中常见的 Hyper-V driver 名称与 VirtIO 不同,不能通过“没有 virtio-net”推出 WSL 2 没有 I/O 虚拟化。
4. 文件系统有两个存储世界
4.1 Linux root filesystem
WSL 2 发行版的 Linux filesystem 通常存放在虚拟磁盘中,保留 Linux inode、permission、symlink、case sensitivity 等语义。开发时涉及大量 Linux 小文件操作的项目,放在发行版 filesystem 中通常更合适。
Linux 中使用类似路径:
1
~/code/project
Windows 可以通过受支持的 WSL 文件入口访问,例如:
1
\\wsl$\Ubuntu\home\<user>\code
不应绕过 WSL 集成,直接用 Windows 工具修改发行版虚拟磁盘内部文件。
这条 Windows → Linux 入口与 Linux 侧的普通 mount 不是同一个抽象。部分 WSL 实现资料会提到 Plan 9/9P file server,但它属于跨边界文件服务的实现细节,不能由此推出两个方向都只是“挂载同一种 9P 文件系统”。笔记和排障应优先依赖 Microsoft 支持的路径与行为。
4.2 Windows drives
Windows drive 会挂载到 Linux 中,默认常见入口是:
1
2
/mnt/c
/mnt/d
这条路径便于 Windows/Linux 工具共享文件,但跨越 OS filesystem 边界。metadata、permission、case sensitivity、文件监听和性能不必然等同于原生 Linux filesystem。
4.3 项目放在哪里取决于主要工具
- 主要由 Linux compiler、package manager、container tooling 操作:优先放 Linux filesystem;
- 主要由 Windows 应用操作,偶尔调用 Linux 命令:可以放 Windows filesystem;
- 同一目录由两侧高频并发修改:先明确 owner、watch、permission 和性能边界,不要假设完全透明。
WSL 1 与 WSL 2 的跨 OS 文件性能特征不同。Microsoft 当前仍指出,某些高频访问 Windows filesystem 的场景下 WSL 1 可能更快;不能把“WSL 2 整体更新”误写成所有文件路径都更快。
5. Windows 与 Linux 命令互操作
5.1 从 Windows 调 Linux
wsl.exe 是 Windows 侧入口:
1
2
3
wsl --distribution Ubuntu --user root
wsl ls -la /proc/cpuinfo
wsl ls -la "/mnt/c/Program Files"
不指定命令时启动默认 shell;指定命令时由选定发行版执行 Linux binary。
5.2 从 Linux 调 Windows
在 WSL shell 中可以直接调用 Windows executable:
1
2
3
notepad.exe .bashrc
ipconfig.exe
cmd.exe /c dir
.exe 后缀是 Windows executable 名的一部分。在 PowerShell/CMD 中输入 wsl 通常可以解析到 wsl.exe;在 Linux shell 中调用 Windows binary 时,保留 .exe 最清楚。
5.3 管道由外层 shell 先解析
以下命令在 PowerShell 中执行时:
1
wsl cat a.txt | Select-String keyword
| 由 PowerShell 解析:左侧是 WSL process,右侧是 PowerShell command。
1
wsl cat a.txt | wsl grep keyword
管道仍由 PowerShell 创建,但两侧 process 都通过 WSL 执行 Linux command。
要让整个 pipeline、redirect、glob 和 quoting 都由 Bash 解释,应显式进入 Linux shell:
1
wsl bash -lc 'cat a.txt | grep keyword'
判断一个符号在哪边生效,先看是谁启动并解析整行命令,而不是看管道左侧程序属于哪个 OS。
6. WSL 网络:只承诺公开行为,不猜内部流表
6.1 NAT 是默认模型
WSL 2 默认使用 NAT-based networking。Windows Host 与 Linux VM 有不同网络边界,外部访问、Host/Guest 地址和防火墙行为不能简单按同一协议栈理解。
WSL 会提供 localhost forwarding 等集成,让 Windows 访问 WSL 服务时不必总是手工查询 Guest IP。但产品便利入口不表示 Windows 与 Linux 共享同一个 kernel TCP/IP stack。
6.2 Mirrored mode 是更深的 Host 集成
当前 Microsoft 文档推荐在支持的平台上使用 mirrored networking mode,以改善:
- IPv6;
- VPN compatibility;
- Windows 与 WSL 之间的 localhost 访问;
- 从局域网直接连接 WSL;
- multicast 等网络行为。
配置属于 Windows 用户目录下的 .wslconfig:
1
2
[wsl2]
networkingMode=mirrored
mirrored mode 仍然是 Windows 与 Linux 两套协议栈的集成,不应写成“两边共享同一个 socket table”。公开行为也不足以证明 Linux listen() 一定通过 hv_netvsc 上报、Windows 维护某种固定“虚拟端口表”,或由名为 Anubis 的组件分流。这些具体断言缺少一手设计或源码依据。
6.3 DNS、proxy 与 firewall 是独立问题
WSL networking 还涉及 DNS tunneling、auto proxy、Windows firewall/Hyper-V firewall 和企业 VPN。出现网络故障时分层检查:
1
2
3
4
5
6
Linux listen address
→ WSL network mode
→ localhost/LAN exposure
→ Windows/Hyper-V firewall
→ DNS/proxy/VPN
→ application policy
“能解析但连不上”和“IP 能通但域名不通”属于不同边界,不能统一归因于 NAT 或 mirrored mode。
7. 配置文件作用域
7.1 .wslconfig:全局 WSL 2 VM
位置:
1
%UserProfile%\.wslconfig
用于控制所有 WSL 2 distributions 共享的 VM 层配置,例如:
1
2
3
4
5
[wsl2]
memory=8GB
processors=4
swap=4GB
networkingMode=mirrored
修改后通常需要:
1
wsl --shutdown
让 WSL VM 完全停止后再重新启动。具体支持项随 WSL/Windows 版本变化,应以当前 wsl --version 和 Microsoft 文档为准。
7.2 /etc/wsl.conf:单个发行版
/etc/wsl.conf 位于某个 distribution 内,只影响该实例,例如:
- automount;
- network 配置生成;
- interop;
- boot/systemd;
- default user。
1
2
3
4
5
[boot]
systemd=true
[user]
default=example
不要把 /etc/wsl.conf 当成给某个发行版分配独立 vCPU/内存的配置;这类 VM 资源属于 .wslconfig。
8. 发行版生命周期与 wsl.exe
8.1 查看状态
1
2
3
wsl --list --verbose
wsl --status
wsl --version
--list --verbose 显示发行版名称、运行状态和 WSL version。星号表示默认 distribution,不代表 Docker Desktop 必须与它共用 daemon 或 userspace。
8.2 安装和选择版本
1
2
3
4
wsl --list --online
wsl --install --distribution Ubuntu-24.04
wsl --set-default-version 2
wsl --set-version Ubuntu-24.04 2
发行版名称、可用版本和命令参数会随当前 WSL 版本变化;执行前用 wsl --help 与 wsl --list --online 核对。
8.3 启停与默认发行版
1
2
3
4
wsl --distribution Ubuntu-24.04
wsl --terminate Ubuntu-24.04
wsl --shutdown
wsl --set-default Ubuntu-24.04
--terminate停止一个 distribution;--shutdown停止整个 WSL 2 managed VM 和所有 distributions;--set-default只改变默认入口,不迁移数据。
8.4 导出、导入与改名
WSL distribution 的“改名”通常通过导出、导入新实例名完成:
1
2
wsl --export Ubuntu old.tar
wsl --import Ubuntu-Main D:\WSL\Ubuntu-Main old.tar --version 2
确认新实例的数据、用户和启动正常后,再考虑清理旧实例。导入实例的 default user 处理方式与 Store-installed distribution 可能不同,应以当前 WSL 命令帮助和 /etc/wsl.conf 为准。
8.5 --unregister 是破坏性操作
1
wsl --unregister Ubuntu
它会注销发行版并删除其数据。重装、改名或迁移前必须先成功导出,并实际确认备份文件可用;不能把 --unregister 当成普通 stop/remove shortcut。
9. Docker 与 WSL 的边界
Docker Desktop 的 WSL integration 与“在个人 Ubuntu distribution 中安装 Docker Engine”是两种模式:
- Desktop integration:Windows 上的 Docker Desktop 管理 daemon/VM backend,并把 Docker CLI/socket 能力暴露给所选 WSL distributions;
- native Engine:daemon、image、container 和配置由该 Linux distribution 自己维护。
它们可以提供相似的 docker CLI 体验,但 daemon 生命周期、storage、network、代理和升级责任不同。不要因为某个 distribution 能执行 docker ps,就推断 daemon 一定运行在该 distribution 中。
若选择 native Engine,需要自行处理 systemd/service 启动、权限、升级、代理和数据备份;若选择 Docker Desktop,应按 Desktop 的 WSL integration 边界排障。两套方案不要在同一 context 下混用而不确认 docker context 与 server 信息。
10. 开发环境的实际选择
对于 Java、Go、Node/React 等后端或全栈开发,WSL 2 通常更适合需要真实 Linux kernel 行为、container、systemd 和现代 tooling 的场景。
一个稳定工作方式是:
1
2
3
4
源码与 Linux build cache 放在 WSL filesystem
→ Git/compiler/package manager 在 WSL 中执行
→ Windows IDE 通过 WSL/remote integration 访问
→ 浏览器和桌面工具仍在 Windows
选择 WSL 1 的理由应是具体边界,例如项目必须主要存放在 Windows filesystem 且跨 OS 文件访问性能更重要,而不是笼统认为 WSL 1“更轻”。
11. 易混点
| 说法 | 更准确的理解 |
|---|---|
| WSL 就是在 Windows 上运行 Linux VM | 只适用于 WSL 2;WSL 1 是 system call translation |
| 每个 WSL distribution 是一台完整 VM | distribution 主要是独立 userspace/rootfs,WSL 2 共享 managed VM/kernel 资源 |
| WSL 2 不是传统 VM,所以不是全虚拟化 | 它使用真实 Guest kernel 和硬件虚拟化,只是控制面被产品隐藏 |
| 看不到 VirtIO,所以不是虚拟机 | Hyper-V 使用自己的虚拟设备接口,VirtIO 不是唯一规范 |
wsl cat a | grep x 整条都在 Linux | 管道先由启动命令的外层 shell 解析 |
/mnt/c 和 ~/code 只是不同路径 | 二者跨越不同 filesystem 与语义/性能边界 |
| mirrored networking 合并了两个协议栈 | 它增强两套协议栈的集成,不代表共享同一个 socket table |
wsl --shutdown 只停默认发行版 | 它停止整个 WSL 2 VM 与全部发行版 |
wsl --unregister 等于卸载入口 | 它会删除发行版数据,必须先验证备份 |
| 能运行 Docker CLI 就说明 daemon 在当前 Ubuntu | CLI、socket 与 daemon 可以跨 distribution/VM 集成 |
12. 复习索引
- WSL 1 是 Linux system call translation;WSL 2 是真实 Linux kernel + managed utility VM;
- WSL 2 distributions 主要隔离 userspace/rootfs,并共享 WSL 管理的 kernel/VM 资源;
- Linux filesystem 与
/mnt/c代表不同存储边界,项目位置应服从主要工具; - Windows/Linux 命令可以互调,但 pipeline、redirect 和 quoting 由外层 shell 决定;
- NAT 是默认网络模型,mirrored mode 改善集成但不合并两套协议栈;
.wslconfig管全局 WSL 2 VM,/etc/wsl.conf管单个 distribution;--terminate、--shutdown、--unregister的作用域与破坏性不同;- Docker Desktop integration 与 distribution 内 native Docker Engine 是两套生命周期。
13. 核验入口
- Microsoft:What is WSL?:WSL 2 utility VM、kernel 与 distributions;
- Microsoft:Comparing WSL 1 and WSL 2:translation layer、Linux kernel、性能与兼容性边界;
- Microsoft:Accessing network applications with WSL:NAT、mirrored mode、localhost 与 DNS;
- Microsoft:Advanced settings configuration in WSL:
.wslconfig与wsl.conf; - Microsoft:Basic commands for WSL:发行版安装、列表、启停、导入导出与注销;
- Microsoft:Working across Windows and Linux file systems:两侧路径和项目位置;
- Microsoft:Set up a WSL development environment:Windows executable interop 与开发环境。