运行 systemctl start openvpn-client@office 却收到“系统不是由 systemd 引导”的提示,看起来像是服务故障。其实这根本不是服务故障:你调用的 systemctl 找不到可通信的运行中的管理器,所以 OpenVPN 这边什么都没被检查。 sudo 不会创建管理器,安装 unit 文件同样不会。命令和机器来自两个不同的世界,而这个错误是唯一暴露出这一点的地方。

先问一句:命令运行的这个地方,PID 1 归哪个进程?这个答案决定了 unit 到底存不存在。

这个错误说的是环境,不是 OpenVPN

systemctl 是客户端,不是管理器。它通过套接字连接系统管理器,另一端没有管理器时,它就打印出大家贴到论坛上的那句话。 ps -p 1 -o pid=,comm= 显示真正在充当 PID 1 的是什么,答案往往是某个 shell、init 包装器,或者容器自己的入口程序。这种情况下,unit 文件可能完全正确,却永远不会被读取。用 root 重跑命令,改变的只是客户端的凭据。

读完整条信息再读第一行。如果错误来自管理器本身,比如缺少 unit 或条件不满足,说明你已经连上了;而这条错误说明你根本没有连上。

WSL:启用 systemd 是改配置

WSL 在较新的版本里支持 systemd,但该功能要按发行版分别开启,而且只在已安装的 WSL 版本支持时才有效。 wsl --version 可以在 Windows 侧看到你的版本,发行版的 /etc/wsl.conf 里则有 [boot] 一节,其中写着 systemd=true。编辑该文件时不要删掉已有的段落,然后重启 WSL 实例让改动生效。 wsl --shutdown 会停掉所有正在运行的发行版,所以先保存工作。

重新打开之后,先确认管理器,再去碰 OpenVPN 的 unit: ps -p 1 -o comm= 应该输出 systemd。启用 systemd 并不会提供配置文件、凭据或实例名,所以下一个报错会是关于这些东西之一,而不是 PID 1。

容器运行的是入口程序,不是 unit

普通容器启动的是入口程序或命令指定的东西,无论你装什么软件包,它都不是由 systemd 引导的机器。把 systemctl 加进镜像,得到的只是一个无处可连的客户端。对 Community OpenVPN 来说,受支持的做法通常是前台进程,即 openvpn --config /path/to/client.conf,由入口程序启动并在外部监管。这个属主负责启动、信号和关闭,也应该是唯一管理隧道的东西。

不要在一个已经管理该隧道的入口程序旁边再启动一个交互副本,因为 两个进程会争抢设备与路由。容器里最小的 init 进程会回收子进程并转发信号,但它不会把镜像变成一台拥有 unit 的主机。

如果某次部署确实需要在容器里用 systemd,那它需要的是专门为此设计的镜像,而不是不断加权限直到 systemctl 不再报怨。

管理器存在之后,再读下一个错误

真正能启动服务的管理器一到位,有用的报错才开始出现。设备权限失败、配置解析错误、凭据缺失和对端不可达,是四个不同的问题,PID 1 那条信息一个都没测过。按 unit 产生它们的顺序读,可以借助 journalctl -u openvpn-client@office -n 50(在 systemd 主机上),或者在没有管理器的环境里直接前台运行客户端。前台运行也是确认配置本身能否工作的最快办法。

在你的笔记里把两套环境分开记:运行隧道的主机,以及你敲命令的地方。

相关文章