最先接触的 Linux 系统是 Ubuntu,唯一会用的命令是 apt-get,每天打开系统的第一件事是 upgrade 所有软件。那时只会跟着网上教程装装中文输入法,把界面美化一通,折腾累了就回到 Windows。

后来用过多台 OpenWrt 路由器,跟着大神的教程配置自启服务,因为还不会 Shell 脚本,根本看不懂具体内容。

后来学会了更多命令,也能写一些 Shell 脚本,开始在 VPS 上部署自己的服务。此时,主流 Linux 系统都已使用 systemd 作为默认 init 程序,因为对 OpenWrt Init Scripts 的第一印象不好,我很快接受了 systemd 这种基于文件而非编程式的配置方式,所以并没有像资深 Linux 用户一样,对 systemd 感到不满。

当 Windows 支持 WSL 时,我已不再使用 Linux GUI,因为它确实没有许多实用的界面程序。但因为兼容性问题,我还得通过 Hyper-V 上的 VM 跑 Docker 和 Kubernetes。如今,Docker 已经能不借助 Docker Desktop for Windows 运行在 WSL2 上,这节省我许多内存,也提高了些许流畅性。

现在,我倾向将所有服务都跑在 Docker 里,唯一的遗憾是 systemd 的缺失。

➜ LOGI systemctl
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
Reason
WSL 之所以不支持 systemd 是因为微软实现了自己的 init 进程,便于在 Windows 中管理这些虚拟机。

➜ LOGI ps -ef | grep init | grep -v $$
root 1 0 0 16:10 ? 00:00:00 /init
root 7 1 0 16:10 ? 00:00:00 /init
root 8 7 0 16:10 ? 00:00:00 /init
为此,社区大佬提出可以创建新的 PID namespace,让 systemd 的成为 PID 1。

Answer
第一个提出此方案的帖子可能是 Running Snaps on WSL2 (Insiders only for now)。关键命令是

unshare --fork --pid --mount-proc /lib/systemd/systemd
之后衍生项目陆续出现,如:

one-script-wsl2-systemd
ubuntu-wsl2-systemd-script
wsl2-hacks
genie
subsystemd
Angea
这些项目的核心原理并无大异,无非是细节处理的好坏和附加功能的多少,但最重要的一点可能是工作层次不同。

Linux Architecture

前三个脚本都工作在图中的 shell 层,要依赖外置命令执行系统调用。genie 工作在 应用程序 层,它使用 C# 编写,通过 shell 执行系统调用,比前三个还多了一层。最后两个虽然也是 应用程序,但它们由 Rust 编写,不经 shell,而直接由 C system call wrapper 执行系统调用,依赖最少,动态链接编译后只有几百 K。

我使用了最后一个,虽然不尽完美,但足以顺畅运行 k8s。

References
OpenWrt Init Scripts
systemd System and Service Manager
No systemd
Running Snaps on WSL2 (Insiders only for now)
pid_namespaces(7) — Linux manual page
unshare(1) — Linux manual page请输入图片描述

标签: none

仅有一条评论

  1. 表评论4383

添加新评论