我看不到哪个系统正在获取/分配 IP。NetworkManager
和netplan
in都有文件/etc
,但它们似乎都不完整,而且 systemd 未运行。 运行的进程很少,network-manager
init.d
脚本报告它未运行。 没有/etc/network/interfaces
文件。
我的理解是 WSL2 通过 WSL 虚拟交换机具有某种特殊的 DHCP 服务器,但是什么是联系该服务器并获取 IP?
答案1
这是一个老问题,似乎今天被提出了,所以我将尝试回答它。
简短回答: init
负责设置网络(以及其他许多功能)
较长的答案:
init
是所有 WSL(版本 1 和 2)实例上的“PID 1”进程。您会init
在所有 WSL 实例的根目录中找到相同的进程,其大小和时间戳相同。
它负责启动实例,包括:
/etc/wsl.conf
根据该文件的内容读取并配置实例- 设置网络,包括自动生成
/etc/resolv.conf
(假设没有关闭/etc/wsl.conf
- 自动安装所有 Windows 驱动器
/mnt/driveletter
(例如/mnt/c
)(再次假设该功能尚未关闭) - 确定当前用户 - 首先检查标志
-u
,wsl.exe
然后回退到/etc/wsl.conf
设置,检查实例的用户的 Windows 注册表设置,最后root
如果以上均未找到,则回退到。 - 将 Windows 路径附加到 Linux 路径(假设它没有关闭)
- 在实例中设置 WSL 特定的环境变量
- 可能还有其他一些事情,包括设置 Windows 互操作性通过 中的套接字
/run/WSL/
,以便 Windows 可执行文件可以在 WSL Linux 会话中运行。
据我所知,WSLinit
是闭源的,也没有真正的文档记录,所以我在这里只是做了一些猜测,但其中一些可以通过在 WSL Github Issues 仓库中搜索来获得“在里面”。
这也可能是init
WSL 子系统内执行繁重工作的其他进程的代理。例如,WSL2 实例将从 Hyper-V 虚拟 NIC 获取其网络信息,因为这些实例在 Windows NIC 后面进行了“NAT”。这种逻辑可能存在外部 init
init
在 WSL 中“正确”,但它在实例启动期间被调用。
为了测试init
功能,我决定删除一切可以从 WSL 实例中查看在它崩溃之前我可以走多远:
- 我克隆了一个 Alpine WSL 实例,因为这几乎是你可以获得的最基本的实例(默认情况下整个实例约 8MB)并使用 登录到该实例
wsl -u root
。 - 在这个例子中,我删除了除
passwd
/group
/shadow
文件之外的所有内容/etc
- 删除了
/lib
除libc.musl
及其符号链接之外的所有内容 - 已移除
/usr
,/sbin
,/root
,/home
- 对于实例中的可执行基本文件,基本上只剩下
busybox
、groups
、su
和。当然,还有。login
/bin
/init
- 退出会话并
wsl --terminate
对其进行了 - 以 root 身份重新启动会话
当所有这些都消失之后,系统将变得尽可能的简陋(没有网络命令,没有网络脚本等):
- 登录到
busybox
的ash
shell 仍然有效(也可以作为默认的非 root 用户) /etc/resolv.conf
、、/etc/hostname
和/etc/hosts
仍会在启动时自动再生。- 网络已启动 —— 通过 DNS 进行 Ping 操作成功,
cat /proc/net/fib_trie
返回了 IP 地址(当然,和 WSL2 一样,是 NAT 的)。 - Windows 驱动器仍自动安装
- Windows 互操作(运行 Windows 可执行文件,例如“powershell.exe”)仍然有效
- Windows 路径仍然附加到 Linux 路径。
我确实希望这个init
过程能有更好的文档记录,因为它是 WSL 中非常重要的一部分。话虽如此,至少“如何配置”文档是好的,即使它没有深入内部细节。