版权声明
本文由 ADD-SP 由英文翻译为简体中文。
译文
免责声明
在 WSL2 上使用 snapd 和 snaps 像是小聪明(非贬义)一样的行为,你可能会遇到许多奇怪的事情,不建议在常规情况下使用。
这句话的意思应该是不推荐在类似生产环境这样的环境中使用。
译者注
先决条件
Windows10 家庭版或专业版,Windows Insider Fast ring 或 2019 秋季更新版本。你需要大约 10GB 的磁盘空间来安装 Ubuntu。
请从 Windows 应用商店安装 Ubuntu18.04 ,并确保可以正常地使用 WSL1。网络上有许多教程可以帮助你完成这项工作,我不想重置我的系统去重复提供这些详细的说明。
然后必须按照微软的文档启用 WSL2,点我查看文档。文档中的关键内容是将 WSL1 切换为 WSL2。
您可以通过查看 uname 的输出来检查是否正在运行 WSL2。如果您运行的是基于 4.19 内核的 microsoft standard,那就可以继续进行后续的步骤了。
准备使用 snapd
WSL2 几乎可以运行 snapd 了。唯一缺少的东西就是作为 init system 的 systemd。微软正在使用一个定制的 init 为每个已安装的 WSL2 发行版设置一个有效的容器。init system 是一个最小系统,比起传统的发行版的 init system 的任务,它更多的是处理与 WSL 的集成。
这段的最后一句话译者起初一直不能翻译通顺,后来询问群友之后发现了这篇文章:https://www.lbihua.cn/Share/DeepL.html,文章内推荐了 DeepL 这款翻译工具,它让我可以通顺地翻译出最后一句话,感谢哔哗的帮助。
译者注
systemd 是预装的,但不是活动的。你仍然可以手动运行 systemd,但它会拒绝启动,除非它以 pid 1 的身份被调用。有一个简单的方法,把它放在一个 “容器 “中,容器其实就是一个基于 unshare(1) 实用程序的山寨容器(poor man’s container)。
译者注
poor man's container
直译为“穷人容器”,但是这应该不是真实的意思,译者查询了一些资料后将其翻译为“山寨容器“,点我查看相关资料。
运行下面这行神奇的命令:
sudo daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
这行命令使用 unshare(1) 来创建一个新的 PID 命名空间。PID 命名空间实际上是Linux 状态下看到进程的一部分,如果你观察你的系统,看到 pid 123,这就表示 123 存在于一个 PID 命名空间中。在另一个 PID 命名空间中,它可能是其他的东西,也可能根本不存在。创建一个 PID 命名空间可以让我们再次得到 PID 1。其余的参数告诉 unshared 再次挂载 /proc 和 fork(1),技术上来说,这是 PID 命名空间工作所需要的。
一旦 unshared 完成,我们要求它运行 systemd,目标是 reach basic.target。你可以在 systemd.target(5) 的手册页面上阅读更多的内容。在命令的开头你会看到 sudo daemonize,它的作用是以 root 身份运行整个命令,并将其从我们用来调用的 shell 中分离出来。
注意,在这个阶段,如果你想管理发行版 host 上的部分服务,WSL 将会出现一些奇怪的现象。例如,如果你使用 apt-get 安装了apache2,你将无法启动它,因为服务管理脚本与 systemd 通信失败。
使用 snpad 进入新的世界
现在 systemd 已经运行了,但在我们的山寨容器里如何使用它呢?技术上很简单,我们只需要在 systemd 住在我们使用的 PID 命名空间中,即运行在容器中。我们实现呢?使用 nsenter(1)。
exec sudo nsenter -t $(pidof systemd) -a su - $LOGNAME
这行命令会让 shell 执行sudo(并且会用这个进程替换掉当前 shell),运行 nsenter,它将我们移动到 systemd 进程的所有命名空间中。一旦进入容器, nsenter 将运行 su – $LOGNAME,使得我们在进入容器前后均使用同一个用户登录。
接下来呢?
snap version
如果这条命令正常执行你就可以安装你喜欢的任何东西了。
注意,你不能使用图形应用程序。我用 X server 和 putty 作为 X11 转发桥的实验结果相当糟糕,我不推荐这样做。
如果你打开另一个 WSL shell,你必须重复 sudo nsenter 命令来 “切换 “到运行 systemd 的容器。
这玩意弄坏了我的系统,救命啊!
Systemd 不是 ”持久性 “的。如果你重启 Windows,你将回到你开始的地方。WSL的数据将保持不变。你可以试着一次又一次地运行 systemd。