如何优雅地使用 WSL2.

这是一个 WSL2 的使用指南,以及本人在安装和使用 WSL2 所遇到的各种问题的解决办法整理。

为什么是 WSL2?

最开始使用 WSL2,纯粹是想尝试一下这个“世界上最好的 Linux 发行版”,然后便一发不可收拾,慢慢地将自己的开发环境也转移到了 WSL2 上。WSL2 毕竟是微软的亲儿子,其在各种软件以及环境的适配方面十分出色(相比于其他的虚拟机),VSCode、J 系软件等都能够很好地自动检查和适配 WSL 的相关配置,大部分的配置都能够做到自动化,摆脱了传统虚拟机繁琐的操作,这显著降低了 Linux on Windows 这一体系的使用难度和入门门槛。

在使用 WSL2 的这几个月的时间里,我也充分地了解了 WSL2 的运行机制和使用方法。在过程中也发现很多的 WSL2 坑在中文互联网上并没有特定的解决方法,只能通过 StackOverflow 和 GitHub Issue 中找到,因此我把这一部分的内容集中了起来,勉强算作一个较为完备的流程。

我后续踩到的坑也会持续更新至这篇文章中。

什么是 WSL2

WSL2 是 WSL 的“升级版”,相比于 WSL 只提供了一层类 Linux 的接口,WSL2 是在虚拟硬件层(Hyper-V)上运行了完整的 Linux 系统,与 Windows10 平级;且 Windows 和 WSL 之间可以通过 wsl 命令进行访问,也可以当成一个远程机进行维护。同时,从 Linux 的角度看,Windows10 的文件系统和 Linux 的文件系统直接挂载到了 /mnt 上,所以跨文件系统访问十分方便。

相比于 WSL1,WSL2 的启动速度会更快、内存占用更少,同时性能也更高。

注意:因为 Windows10 和 Linux 属于两种不同的文件系统,且目前 WSL2 在文件系统的兼容性上还存在问题——系统间进行 IO 走的网络协议,所以如果经常进行跨文件系统 IO 的话会有肉眼可见的性能损失(见官方对比)。对此建议将文件移至 Linux 系统的根目录(/mnt/wsl)内再进行操作。

WSL2 安装速览

命令均需要在 PowerShell(Admin) 中运行

  1. 安装前需要确定 Windows 10 的版本在 1903(X86) / 2004(ARM) 或以上;
  2. dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart 启用”适用于 Linux 的 Windows 子系统“可选功能;
  3. dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart 启用“虚拟机平台”可选功能;
  4. 下载并安装 Linux 更新包
  5. wsl --set-default-version 2 将 WSL2 设置为默认版本;

运行命令后如果看到此消息:WSL 2 requires an update to its kernel component. For information please visit https://aka.ms/wsl2kernel,则仍需要安装 MSI Linux 内核更新包(见第 4 步)。

  1. 打开 Microsoft Store,选择自己要使用的发行版;
  2. 安装完成后,打开对应发行版进行系统的初始化安装和设置

至此 WSL2 的安装配置流程结束,接下来对不同 Linux 发行版的个性化以及开发环境配置与平常使用无异,按照使用习惯进行即可。

WSL2 网络配置和 IDE 开发环境远程部署

J 系的 IDE 在 2020 年 9 月分的更新才加入 WSL 相关的支持,其实与通过 SSH 与 WSL2 进行远程连接的体验无异,有一些地方的配置甚至更繁琐(比如 Pycharm 在 WSL 下的不同 Python 的环境配置)

因此还是建议直接用 Remote 的方式来进行开发,为此需要先打开 WSL 的 sshd 监听。我用的一键脚本如下:

#!/bin/bash
SSHD_PORT=2222
SSHD_FILE=/etc/ssh/sshd_config
SUDOERS_FILE=/etc/sudoers

# 0. update package lists
sudo apt-get update

# 0.1. reinstall sshd (workaround for initial version of WSL)
sudo apt remove -y --purge openssh-server
sudo apt install -y openssh-server

# 1.2. configure sshd
sudo cp $SSHD_FILE ${SSHD_FILE}.`date '+%Y-%m-%d_%H-%M-%S'`.back
sudo sed -i '/^Port/ d' $SSHD_FILE
sudo sed -i '/^UsePrivilegeSeparation/ d' $SSHD_FILE
sudo sed -i '/^PasswordAuthentication/ d' $SSHD_FILE
echo "# configured by CLion"      | sudo tee -a $SSHD_FILE
echo "Port ${SSHD_PORT}"          | sudo tee -a $SSHD_FILE
echo "UsePrivilegeSeparation no"  | sudo tee -a $SSHD_FILE
echo "PasswordAuthentication yes" | sudo tee -a $SSHD_FILE
# 1.3. apply new settings
sudo service ssh --full-restart

# 2. autostart: run sshd 
sed -i '/^sudo service ssh --full-restart/ d' ~/.bashrc
echo "%sudo ALL=(ALL) NOPASSWD: /usr/sbin/service ssh --full-restart" | sudo tee -a $SUDOERS_FILE
cat << 'EOF' >> ~/.bashrc
sshd_status=$(service ssh status)
if [[ $sshd_status = *"is not running"* ]]; then
  sudo service ssh --full-restart
fi
EOF

# 3. install basic dependencies
sudo apt install -y cmake gcc clang gdb valgrind build-essential

# summary: SSHD config info
echo 
echo "SSH server parameters ($SSHD_FILE):"
echo "Port ${SSHD_PORT}"
echo "UsePrivilegeSeparation no"
echo "PasswordAuthentication yes"

配置好后就可以直接用了,运行后可自动配置 sshd 以及监听端口(默认 2222,可在脚本中修改 SSHD_PORT 更换端口)。但此时容易遇见一个问题,WSL2 毕竟还是虚拟机,在重启后并不会自动开启 sshd;且服从 Windows10 的内存调配,长时间不用会冻结连接不上。

解决方法也很简单,运行命令 wsl sudo /etc/init.d/ssh start 即可打开监听端口;如果嫌麻烦的话,也可以将该命令写入脚本,然后开机自动运行。

WSL2 和 Windows 的网络问题

WSL2 和 Windows10 的网络不是共享的,WSL2 会单独虚拟出来一个网卡(cmd 中通过 ipconfig 可以查出来)。这样的配置经过测试,WSL 搭建的 web 服务在 Windows10 里面可以直接通过 localhost 来访问,WSL2 中的需要获取 Windows10 的 IP 进行连接。

IP 获取方式:cat /etc/resolv.conf;如果挂代理,Linux 需要通过该 IP 来进行。

wsl 的更多操作

  • –-list,列出已经安装的所有 WSL 系统镜像

对镜像(Distribution)的备份、恢复以及迁移

  • –-user,使用特定用户运行 WSL
  • -–export <Distro> <Filename>,将 WSL 中的系统镜像输出为一个 .tar 文件,文件名 - 则为默认
  • -–import,将 .tar 文件导入 WSL 中生成新的镜像,文件名 - 则为默认
  • -–terminate,删除特定的镜像