不要用WSL,否则会变得不幸
本文最后更新于 2026年3月20日 晚上
有位前辈用一句话形容 Linux:“Linux 本身不要钱,但你(折腾)的时间更费钱。”
而寄宿在 Windows 上的 WSL,更是把这句话发挥到极致。
当时我从头搭建 Kubernetes 工具链。由于家境贫寒,本想用手头 4 台老旧 PC 搭个能用就行的集群;结果在 Windows 里装 WSL、再在 WSL 里折腾 Kubernetes 的过程中,遇到太多看不到尽头的问题,最后只好放弃。
目前我的方案是:把其中 2 台 PC 直接装 Ubuntu,至少先把一个最小可用的主从集群跑起来。
这篇文章就当作一次“失败复盘”:记录我在 WSL 上踩过的坑,等以后学有余力了再回头补课。
没想到吧,3年后是 AI (GPT-5.3-Codex) 来帮忙补课!
既然都 update 了那就多写两句,那个时候刚刚从云原生的 start-up 被开,怀着现在已经想不起的心情,想着要潜心打好云原生相关的基础,大展拳脚,所以想从头夯实基础,且那个时候手头拮据,不像现在家里好几台电脑,又加戏想通过不用虚拟机来体现逼格顺便学更多东西,真的是学习的门都没有摸到。
后来进了声网又做和富途一样的客户端相关的事情了,完全和云原生没关系。
再后来去了百度云,也不需要自己装了,光速跑路之后终于到了 NXP 而且巧合的也是客户端,这下是彻底告别云原生了,不过总结来看,其实我也就只有这一段经历而已,其他基本上都是客户端。
现在又是 AI 时代,除非我有缘做到 AI Infra,否则再也不会和云原生有关了。
文字的神奇之处就在于可以穿越时空对话,不知道我下次 update 的时候又是什么境地。
1. WSL 的适用范围(我的结论)
写写 Python、跑跑普通的前后端应用,WSL 非常合适,甚至能省掉在 Windows 上装一堆软件的麻烦。
但一旦涉及更底层的东西,比如虚拟化、容器化、集群化,尤其是会碰到“网卡/路由/桥接/iptables”这类东西时,WSL 这种基于 Hyper-V 的“精简版虚拟机”就容易变得缺胳膊少腿。
那种感觉很像早年用“番茄花园”精简版 Windows 打游戏:能用,但关键组件缺一块,问题还特别难查。
AI 辅助解法(2026 视角补充)
- 如果你的目标是 Kubernetes/容器/网络实验:优先顺序基本是
- 物理机 Linux
- 正经虚拟机(VMware/VirtualBox/Hyper-V VM)
- WSL(适合开发,不适合当“底层实验场”)
- 如果你只是想在 Windows 上跑容器:可以直接用 Docker Desktop(WSL2 后端),不要手搓一堆 systemd/iptables/网络。
2. 最好的方案是物理机,其次是真正的虚拟机
那几天我一直在坑里匍匐:很多问题要么没有通用解法,要么网上的“解法”试下来根本不管用。
最后我的学习阶段建议很朴素:真要折腾底层,就用物理机;退而求其次,用 VMware / VirtualBox 这种成熟到不能再成熟的虚拟机。
AI 辅助解法(2026 视角补充)
- 如果你坚持 Windows 作为主力:可以把“底层实验环境”彻底隔离成一台 VM,省心很多。
- 如果你要做局域网里多节点互联:VM 的桥接、Host-only、NAT 这些网络模式更可控,也更符合大多数教程的默认前提。
AI 没活硬整, prompt 里说了补充下就真没什么说的废话也要补充一下,像极了我写周报的样子。
3. 时用 WSL 上遇到的问题
3.1 systemd 与 systemctl:很多服务根本起不来
systemd 是 Linux 常见的初始化系统和服务管理器;
systemctl 是 systemd 的命令行工具,用来启动、停止、重启、查看服务状态、设置开机自启等。
WSL2 本身是由 Windows 负责运行的,因此你用 tree 或 ps 去看进程时,会发现根进程(PID 1)不是 systemd。这会导致很多依赖 systemd 的服务守护进程(daemon)无法按预期启动。
当我执行 systemctl 时,会提示 init system (PID 1) 并非 systemd,而是微软提供的 init。
即使在 /etc/wsl.conf 里加 systemd=true 之类的配置,当时也还是会遇到各种问题。
3.1.1 用 service 代替 systemctl 也不稳
有些时候能用 service 顶一下 systemctl,但也经常出现:
Failed to connect to bus: No such file or directory
比如我跑一个“自动安装 Docker / 自动开启 SSH”的脚本,脚本默认用 systemctl,还是绕不开这个问题。
而我如果去批量替换别人的脚本,又会引入新的问题。
AI 辅助解法(2026 视角补充)
- 先确认 WSL 版本是否足够新:
wsl --version- 旧版 WSL 对 systemd 支持不完整,很多“教程能跑”的前提是 新 WSL + 新发行版。
- 如果要启用 systemd(适用于支持 systemd 的新版 WSL):
- 编辑
/etc/wsl.conf:1
2[boot]
systemd=true - 在 Windows 侧执行:
1
wsl --shutdown - 重新进入 WSL 验证:
ps -p 1 -o comm=应该看到systemd
- 编辑
- 如果你只是“为了跑 Docker”:
- 直接用 Docker Desktop,或者在 VM/物理机里装 Docker,会省掉 80% 的时间。
真不愧是 AI ,我当时肯定是试过的,这个 systemd 在装当时的 k8s 某些组件的时候会疯狂报错,只能说让 AI 处理互相矛盾的资料还是太难为它了。
3.2 WSL2 无法联网:DNS / 网络栈异常
3.2.1 resolv.conf 被自动生成,而且 nameserver 不对
参考:
打开:
sudo vim /etc/resolv.conf
你会看到类似:
1 | |
把 nameserver 改成 8.8.8.8 保存后,就可能恢复网络。
3.2.2 winsock 相关的重置
参考:
管理员模式打开 CMD,执行:
1 | |
完成之后一定要重启 WSL,否则修改不生效。
AI 辅助解法(2026 视角补充)
- 修改 DNS 时,建议“从根上禁止自动覆盖”,否则你下次重启又变回去:
- 编辑
/etc/wsl.conf:1
2[network]
generateResolvConf=false - 删除并重建 resolv.conf:
1
2sudo rm -f /etc/resolv.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf - Windows 侧执行
wsl --shutdown再重进。
- 编辑
3.3 SSH / 局域网访问:连得上 localhost,连不上局域网
WSL2 可以直接用 Windows 命令行进入,也可以通过 VSCode 的 WSL 插件直接连。
但我想要的其实是:从局域网另一台机器 ssh 进来(因为我要做集群)。
3.3.1 无法设置 Bridge Network(桥接)
在正经虚拟机里,设置桥接网络通常就是点两下。
但在 WSL 上我没搞定。各种教程都说去 Windows 的 Hyper-V 管理器里设置一下就行,可如果真这么简单,也不会有这篇文章了。
3.3.2 kex_exchange_identification: Connection closed by remote host
在 WSL2 里开启 sshd 之后,连本机 WSL2 用 ssh localhost 通常没问题。
但当我从局域网另一台 PC 去连 WSL2 时,就会出现标题这个报错,甚至更离谱的 timeout。我尝试了很多次都没成功(多半还是因为上面的桥接没搞定)。
AI 辅助解法(2026 视角补充)
- 先认清一个现实:WSL2 的网络更像“在 NAT 后面的一台虚拟机”,它并不是设计来当“局域网可直连服务器”的。
- 如果你只是需要“从 Windows 以外访问 WSL 的 ssh”:
- 一个常见思路是 Windows 做端口转发(portproxy)把 Windows 的 22 转到 WSL 的 22(或别的端口)。
- 但这条路会牵扯到防火墙、WSL IP 变化、重启失效等一堆维护成本。
- 如果你的目标是“局域网多节点互联 + 固定 IP + 跑集群”:
- 直接用 VM(桥接)或物理机 Linux,会更接近真实环境,也更省时间。
AI 还是太怕得罪人了,是我我就直说建议放弃。
3.4 Transport endpoint is not connected:建议放弃
这个问题的原因太多了。
我当时的临时做法是不断重启 LxssManager 服务,有时能暂时恢复一下。但最后我就是被这个问题搞到彻底放弃。
LxssManager 是 Windows 10 中的一个服务,它支持运行本机 ELF 二进制文件。该服务提供在 Windows 上运行 ELF 二进制文件所需的基础结构。WSL 是 Windows Subsystem for Linux 的缩写,它是一个允许在 Windows 10 上运行 Linux 二进制文件的兼容层。LxssManager 是 WSL 的一部分,它负责管理 WSL 的 Linux 发行版。
AI 辅助解法(2026 视角补充)
- 先做“最小破坏”的恢复动作(比重启机器轻):
- Windows 侧:
wsl --shutdown(这一步很关键) - 或者:
wsl --terminate <发行版名>
- Windows 侧:
- 如果你频繁遇到这个错误,通常要从“文件系统挂载/虚拟化通道/磁盘状态”去排:
- 尽量把重 IO 的东西放在 WSL 自己的 Linux 文件系统里(而不是
/mnt/c/...) - 检查 Windows 磁盘、杀毒软件、同步软件是否在干扰
- 尽量把重 IO 的东西放在 WSL 自己的 Linux 文件系统里(而不是
- 但说实话:如果你的主要目标是 Kubernetes 集群,这个坑不值得长时间死磕。
嘿,这里学会说放弃了。
3.5 swap:在 WSL 上关不掉(当时)
部署 Kubernetes 的机器通常要求关闭 swap,因为写入虚拟内存会影响性能,也可能造成系统卡顿。
在实体机上只要 sudo swapoff -a 就能搞定;
但我当时在 WSL 上死活不起作用。推测 WSL 的 swap 是由 Windows 上某个专门负责虚拟化的东西统一配置的,所以这个问题既偏门又难查。
AI 辅助解法(2026 视角补充)
- WSL 的 swap/内存上限通常由 Windows 侧配置控制:
- 检查用户目录下的
~/.wslconfig(Windows 路径:C:\Users\<你>\.wslconfig) - 常见写法类似:
1
2[wsl2]
swap=0 - 改完后执行:
wsl --shutdown
- 检查用户目录下的
- Kubernetes 角度还有一个“绕开法”(不推荐长期用):让 kubelet 不因为 swap 直接 fail(具体参数随版本变化)。
- 但这会掩盖真实环境问题,不适合作为学习路线的默认方案。
4. 后来我怎么做的:Ubuntu 物理机/虚拟机桥接 + 固定 IP
最后我还是回到了“正统解法”:用 Ubuntu 直接桥接进局域网,给节点固定 IP。
4.1 入网方式(虚拟机常见三种)
一般虚拟机软件都提供多种网络模式,主要有:
- NAT 模式:虚拟机不直接接入局域网,和集群里的 Node 宿主机互相 ping 不通,不选
- Bridged Adapter 模式:即桥接模式,为虚拟机模拟出一个独立网卡,用独立 IP 接入局域网,选
4.2 固定 IP(netplan)
当虚拟机使用桥接模式接入局域网之后,就和物理机 Ubuntu 的设置一样了。
Ubuntu 18.04 LTS 之后的版本使用 /etc/netplan/ 下的文件来配置网络。我当时用的文件名是 01-network-manager-all.yaml。
先用 ifconfig 查看网络情况,找到桥接网卡名称(我这里是 enp0s3);
然后:sudo vim /etc/netplan/01-network-manager-all.yaml,添加类似内容:
1 | |
networkd 和 NetworkManager 都是用于管理网络接口的后端。networkd 是 systemd 的一部分,是一个轻量级网络管理器;NetworkManager 更“高级”,一般桌面版用得多。
AI 辅助解法(2026 视角补充)
- netplan 改完别忘了:
1
sudo netplan apply - 如果你在服务器上只想要稳定:
- renderer 选
networkd往往更省心;桌面环境/需要 GUI 再考虑 NetworkManager。
- renderer 选
- 集群环境下,固定 IP 只是第一步:
- 还要同步考虑网关、DNS、节点名解析(hosts / 内网 DNS)、以及后续的 CNI 网络规划。
按行数算钱是吧,这都不是 WSL 遇到的问题了,而且写的也是废话,料想我领导看我写的估计也是这个感觉。