本文已于 2020/05/26 更新,过时的信息已用删除线标注。

我是真没想到这都快过半年了 20H1 还没释出稳定版

早在今年上半年的 Build 2019 上,微软宣布了 wsl2,使得 wsl 不再只是 system call 的翻译,而是切切实实跑在一个真正的 Linux 内核之上。这样一来,wsl 将不再受内核的局限,能够运行 docker 等与 Linux kernel 密切相关的软件。

自宣布以来,wsl2 的开发很快提上日程,并将在 Windows 10 20H1 版本中可用。~~但想要升级至此版本,目前还需进入预览体验计划,而 Windows 10 目前的 bug 数量使我对 insider fast ring 望而却步。~~最近在经过了很长时间的心理斗争之后,我最终还是进入了快速预览版,开始体验 wsl2,下面是途中遇到的一些坑,留存至此,以备后来者避坑。

首先需要说明的是,wsl1 与 wsl2 各有优劣,两者之间并非常规意义上的「升级」,更像是一种并行。如果并非是涉及内核等问题,仅仅是执行一些上层程序,我个人建议继续使用 wsl1,这样更加节省内存等资源。(当然可以 wsl1 与 wsl2 各安装一个/多个,按需启动)

安装

安装过程参考官方的 WSL 2 的安装说明 即可。

首先滚入 20H1 的预览版,升级系统,而后开启 hyper-v 平台,跑一个命令将原本的 wsl1 转为 wsl2 即可。更改的过程可能要花几分钟时间,等待就好。

之后就能开始使用 wsl2 啦!

各种坑

……当然,路途不宗是一帆风顺的,而是伴随着艰难险阻。

虚拟机

由于 VMware 暂未支持嵌套虚拟化,所以开启了 hyper-v 之后,将无法继续使用 VMware 虚拟机。虽然 hyper-v 本身也能装个虚拟机应个急,但体验确实是远远不如 VMware 的。

VMware 20H1 技术预览版已支持嵌套虚拟化,可以与 hyper-v 共存,更多信息与下载链接等请 点击此处

terminal

另外就是终端问题了。

我在 wsl1 时期一直使用的终端 wsl-terminal 由于很久没有更新,所以并没有支持 wsl2,但见鬼的是我升级完之后 wsl1 也没办法用了……不过好在还有 windows terminal 这个官方的终端可以使用(虽然现在还不能输入中文有点难受)。

有一个方法则是可以先启动 powershell,然后通过命令行启动 wsl2。

wsl-terminalwsl-tty 均已支持 wsl2。但由于 windows terminal 的卓越体验(现已支持中文输入),我更为推荐使用 windows terminal 作为 wsl 的终端。感兴趣的可以参考一下 我的 windows terminal 配置

代理

安装了 hyper-v 之后,会将一系列端口划入保留端口之中,其中就包括了某软件的默认端口 1080。解决方法也很简单,换一个高位端口即可。(各种配置里的更改就是一项大工程了)

但真正吊诡则是,在我最初试用 hyper-v 时并未出现这个情况,开始使用 wsl2 后才发生……

此外,wsl2 与 windows 之间存在着网络隔离,虽然 wsl 团队已全力优化但还存在着一些可能会影响体验的问题。如在 windows 中可用 localhost 直接访问 wsl2 的 localhost,但反之则不行。

如果想要在 wsl 中利用 windows 本身的代理,可以在 ~/.zshrc~/.bashrc 中写入以下配置(我并不熟悉 fish 所以请 fish 用户自己改改用吧):

# wsl 2 用户请启用下面这一行
# export hostip=$(cat /etc/resolv.conf | grep -oP '(?<=nameserver\ ).*')
# wsl 1 用户请启用下面这一行
# export hostip="127.0.0.1"
# 请将 1080 换为自己代理软件的端口
alias socks="http_proxy=http://${hostip}:1080 https_proxy=http://${hostip}:1080 "

source ~/.zshrc 之后即可通过 socks command params 来在 shell 中临时使用代理。

systemd

警告:作者本人已不在 wsl 2 中使用 docker 与 genie,本部分可能存在不可预知的错误,请审慎阅读

由于 wsl2 的第一个(PID=1)进程是维持 windows 与 wsl2 通信等所需的 init,因此 systemd 无法以 PID=1 启动,直接无法使用。

但是,人民群众造轮子的热情是不可磨灭的(误,我们可以用 genie 来使用 systemd。

genie 的安装过程不再赘述,紧随官方文档或者使用 aur 即可。需要注意的是,genie 需要 dotnet 被引入环境变量,只需在你正使用的 shell 的配置文件(如 zsh 的 ~/.zshrc )中加入 export DOTNET_ROOT=/opt/dotnetsource 以应用即可。

此外,由于其实现原理,最好将宿主机上自定义的 hosts 文件清空,以防出现问题。

安装成功之后,只需执行 genie -s ,systemd 即可正常使用。

docker

在 systemd 这一问题解决之后,docker 的安装与使用非常简单。

yay docker 安装之后,只需通过 systemctl 启用其服务即可,换源等不再赘述。

after

其实在这一套安装下来之后,甚至感觉有点没啥用(?