不要用WSL,否则会变得不幸

有位前辈用“Linux本身不要钱,但是你(折腾)的时间更费钱”来形容Linux上可能遇到的适配问题,从而表达自己对该系统又爱又恨的感情。

而寄宿在Windows上的WSL,更是将这个说法发挥到极致。

在我自己从头搭建Kubernetes工具链的时候,由于家境贫寒,本想就着手上4台老旧PC搭建个基本能用的集群就行,结果在Windows里面装WSL,以及WSL里面装Kubernetes的时候,遇到太多看不到尽头的问题,遂放弃。

目前我的解决方案是安装Ubuntu系统到其中2台PC,至少先跑起来一个最小的主从集群。

而本次我本身就是为了学习才搭建环境,因此记录下遇到的WSL相关的问题,以便学有余力的时候更加透彻的掌握操作系统相关的知识。

``

WSL的适用范围

写写Python代码,搭建普通的前后端应用,WSL是非常合适的,甚至避免了在Windows上安装软件的麻烦事。

但是在涉及到底层的东西,比如说虚拟化、容器化、集群化等这种需要用到“网卡”之类硬件的配置的时候,WSL这类基于Hyper-v的“精简版”虚拟机就会变得缺胳膊少腿,有早年用过“番茄花园”这种精简版Windows打游戏然后缺少组件经历的朋友就能体会到我的感受。

最好的是物理机,其次是真正的虚拟机

这几天我一直在满是坑的泥泞中匍匐,很多问题要么是没有通用解法,要么是试下来根本不管用。

最后学习阶段只推荐VMware、VirtualBox这种成熟得不能再成熟的真正的虚拟机,如果不信欢迎自行尝试。

systemd与systemctl

systemd是一个Linux系统的初始化系统和服务管理器;

而systemctl是systemd的一个命令行工具,用于控制systemd系统和服务管理器。

systemctl可以启动、停止、重启、重载、状态检查、启用或禁用系统服务。

WSL2本身是由Windows负责运行的,因此使用tree或ps命令时会看到根进程不是systemd,这将导致无法启动Linux系统服务的守护进程(deamon)。当我们执行systemctl命令的时候,会显示出我们的init system (PID 1)并非systemd,而是微软提供的init system。

即使在/etc/wsl.conf添加systemd=true配置等操作也会有各种问题。

service代替systemctl

虽然有些时候能够通过service代替systemctl,但是有些时候会出现Failed to connect to bus: No such file or directory的错误。

比如我跑一个自动安装docker / 自动开启ssh的脚本的时候,由于源头默认提供的脚本是使用systemctl的,还是绕不开这个问题。

如果我去批量替换别人的脚本,又会带来新的问题。

WSL2无法连接网络

Windows automatically generates resolv.conf file with wrong nameserver

https://stackoverflow.com/questions/62314789/no-internet-connection-on-wsl-ubuntu-windows-subsystem-for-linux
Locate the file by running the following command:

sudo vim /etc/resolv.conf

You will see the following in the file:

This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/resolv.conf

1
2
3
# [network]
# generateResolvConf = false
nameserver xxx.xx.xx

Change the nameserver value to 8.8.8.8 and save the file. You should now be able to connect to the internet.

winsock

https://github.com/microsoft/WSL/issues/3438#issuecomment-41051857
Open Command Prompt as an Administrator and type these commands:

1
2
3
4
5
netsh winsock reset 
netsh int ip reset all
netsh winhttp reset proxy
ipconfig /flushdns
Reboot your machine.

完成之后一定重启WSL,否则修改不生效。

SSH

WSL2可以直接用Windows的命令行直接进入,也可以通过VSCode的WSL插件直接本地连接WSL;

无法Set Bridge Network

在正统的虚拟机配置设置Bridge Network都是点一键就能拿完成的工作,我无法在WSL上完成,虽然各种教程都说在Windows上的Hyper-v管理器上设置一下就好了,但是如果真的是这样的话,就不会有这篇文章了。

kex_exchange_identification: Connection closed by remote host

在WSL2中开启sshd服务之后,连接自己机器上的WSL2只需要通过ssh localhost就可以;

连接局域网中另一个PC物理机上的WSL2就会出现标题标错,还有更离谱的timeout,我尝试过很多,就没成功过(多半是因为上面Set Bridge Network没成功导致的)。

Transport endpoint is not connected

导致这个问题的原因太多了,不断重启LxssManager服务可能会暂时可用一下,我就是被这个问题搞得彻底放弃的。

LxssManager是Windows 10中的一个服务,它支持运行本机ELF二进制文件。该服务提供在Windows上运行ELF二进制文件所需的基础结构。WSL是Windows Subsystem for Linux的缩写,它是一个允许在Windows 10上运行Linux二进制文件的兼容层。LxssManager是WSL的一部分,它负责管理WSL的Linux发行版。

swap

首先部署Kubernetes的机器不能开启swap,因为在写入虚拟内存的时候会影响性能和造成系统卡顿;

于是在实体机上只需要sudo swapoff -a简单一步的操作,在WSL上死活不起作用,推测是WSL的swap是由Windows上的某个专门负责虚拟化的服务进行配置的,然后由于问题太过偏门,尝试了之后没有找到轻松有效的方法。

Ubuntu 桥接接入局域网固定IP

入网方式

一般虚拟机软件都提供多种网络模式,主要有:

NAT模式: 虚拟机没有直接接入局域网,和集群里面的Node宿主机互相ping不通,不选

Bridged Adapter模式:即桥接模式,为虚拟机模拟出一个独立的网卡,有独立的IP地址接入局域网,

固定IP

当虚拟机使用桥接模式接入局域网之后,就和物理机Ubuntu的设置一样了。

Ubuntu 18.04 LTS之后的版本使用/etc/netplan/下得文件来配置网络,我这里叫01-network-manager-all.yaml。

首先使用ifconfig查看当前机器的网络情况,找到桥接的网卡名称,我这里是enp0s3

然后使用sudo vim /etc/netplan/01-network-manager-all.yaml打开配置文件,添加如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Let NetworkManager manage all devices on this system
network:
ethernets:
enp0s3: #配置的网卡的名称
addresses: [192.168.31.50/24] #配置的静态ip地址和掩码
dhcp4: no #关闭DHCP,如果需要打开DHCP则写yes
optional: true
routes:
- to: 0.0.0.0/0
via: 192.168.31.1 #网关地址
nameservers:
addresses: [192.168.31.1] #DNS服务器地址,多个DNS服务器地址需要用英文逗号分隔开
version: 2
# renderer: NetworkManager
renderer: networkd #指定后端采用systemd-networkd或者Network Manager

networkd和NetworkManager都是用于管理网络接口的后端。networkd是systemd的一部分,它是一个轻量级的网络管理器,可以在Ubuntu 18.04及更高版本中使用。它使用Netplan配置文件来配置网络接口。NetworkManager是一个更高级的网络管理器,可以在Ubuntu 16.04及更高版本中使用。它提供了一个GUI界面,可以方便地配置网络接口。


不要用WSL,否则会变得不幸
https://gou7ma7.github.io/2023/04/30/devops/no_wsl/
作者
Roy Lee
发布于
2023年4月30日
许可协议