本人所使用的系统是 win11 22H2 家庭版,如果你不是非CentOS不可,强烈建议直接去微软应用商店里面下载Ubuntu,全自动安装到WSL,啥都不用管。(就是好像没办法选择安装路径)

1.启用WSL

刚开始安装WSL的时候,参考的是基于Windwos11的WSL安装CentOS。说实话,我个人并不喜欢这篇博客。因为里面遗漏了很多东西,并且在不恰当的位置贴出了命令,导致读者会误以为是需要执行这些命令。

比如我就理解错误,先执行了设置wsl默认版本为2的命令,这个命令先不要执行!后文会告诉你为什么。

这篇博客中对开启wsl的设置的位置描述也不完全,看上去像从网上哪里抄过来的win10的设置逻辑(win11的位置完全不一样)

1
该博客原文:在windows设置中打开【启用或关闭Windwos功能】,勾选【适用于Linux的Windwos子系统】,点击确定后会系统会提示重启,选择确认即可

实际上在win11中,需要多点好几个地方才能找到这个设置的位置

1
右键桌面 - 个性化 - 进入win11设置界面 - 应用 - 可选功能 - (往下滑)更多windows功能

image-20231015104701566

这都是我对一个不完善博客的吐槽,但并没有贬低这个教程的意思啊!至少他告诉我基本步骤应该做哪些。

为什么我要吐槽呢?因为这种写的不全的博客经常会让读者得去重新搜索某些设置的位置,而作者明明是已经走过这个流程的。博客里面作者的截图明显是windows11,但他提供的设置却是win10中的旧位置。多花30秒写清楚位置并带上截图,不知道能节省读者多少时间……如果你体会过查资料的时候阅读这些「断头短尾」的博客,应该也能体会到我的心情。

回到正题。在更多 windows 功能选项框中(win10/11的这个选项框基本相同),勾选上下面的几个选项,三个都要勾选上!

  • 适用于 Linux 的 Windows 子系统
  • 虚拟机平台
  • windows 虚拟机监控程序平台

点击确定,就成功启用了 WSL。系统会弹出一个进度条,下载一些东西。

image-20231015104951463

处理完毕后,WIN+R输入cmd,打开命令行工具,在命令行工具中输入wsl -l -v命令,有相关输出就是启用成功了!

初始化情况下,执行这个命令,应该会提示你当前什么虚拟机都没有安装。

2.安装Centos8

2.1 下载系统zip

github/wsldl-pg/CentWSL 上下载适用于wsl的CentOS8系统的zip

这个也可以:https://github.com/mishamosher/CentOS-WSL

image-20231015104110576

把zip解压到你想安装虚拟机的位置(一定要是一个空文件夹),然后右键CentOS8.exe,以管理员身份运行。

image-20231015104455537

2.2 报错HRESULT:0x80370102解决

安装CentOS8的时候,就遇到了这个issue中的问题👇

github.com/wsldl-pg/CentWSL/issues/36

用管理员身份运行CentOS8.exe之后,弹出的终端会输出如下内容

1
2
ERROR:Installation Failed!
HRESULT:0x80370102

根据该issue 中最后一个回复的解决办法,我先将wsl版本设置回了1(这就是为什么前文说不要先设置为默认wsl2)

image-20231015112649042

1
wsl --set-default-version 1

修改版本为1后,重复如上安装步骤(以管理员身份运行CentOS8.exe),就成功安装了CentOS的虚拟机。此时在win11的文件管理器左侧会多出来一个Linux图标,里面有CentOS8的系统里面的文件。

image-20231015105247440

在windows的powershell或者cmd中,输入wsl,就可以进入CentOS8的bash;见下图,我们已经成功安装好了一个CentOS8的虚拟机。内部的文件就是CentOS8系统的默认文件。

在内部执行exit命令,就可以退出wsl虚拟机,回到windows的终端下。

image-20231015105338512

而且WSL有个最大的好处,就是它能自动挂载windows下的文件到/mnt目录下,这个目录里面可以看到我的win11宿主机的3个硬盘分区;windows的文件资源管理器里面也可以看到Linux中的文件,方便我们在windows和linux下互传文件(就不需要用sftp工具了)

特别是如果你需要写带Doxygen文档的项目,在生成Doxygen的html后,就能直接从这里在windows的浏览器中打开网页,而不需要用sftp或者其他工具传到windows下再打开了!

当然,你也可以用带GUI的Linux系统来解决这个问题。

2.3 更新为WSL2

使用wsl -l -v命令,可以看到当前运行的wsl虚拟机,版本是1

1
2
3
PS C:\Users\S2522\Desktop> wsl -l -v
NAME STATE VERSION
* CentOS8 Running 1

我们可以将其升级为WSL2版本,但是这里会告诉你需要更新内核组件

1
2
3
4
PS C:\Users\S2522\Desktop> wsl --set-version CentOS8 2
正在进行转换,这可能需要几分钟时间...
有关与 WSL 2 的主要区别的信息,请访问 https://aka.ms/wsl2
WSL 2 需要更新其内核组件。有关信息,请访问 https://aka.ms/wsl2kernel

那就更新呗!微软官方文档 中会告诉你需要 wsl.exe --installwsl.exe --update命令。

这里我执行了wsl --update命令,执行后会弹窗要你提供管理权限,并出现一个进度条,等他跑完就行。

1
2
3
PS C:\Users\S2522\Desktop> wsl --update
正在安装: 适用于 Linux 的 Windows 子系统
已安装 适用于 Linux 的 Windows 子系统。

更新好了,再重新执行wsl --set-version CentOS8 2升级命令,会提示你正在执行转换,需要等待一会。

image-20231015105730332

最终成功转换了,使用命令wsl -l -v里面显示的版本也是2了。

1
2
3
4
5
6
7
8
PS C:\Users\S2522\Desktop> wsl --set-version CentOS8 2
有关与 WSL 2 关键区别的信息,请访问 https://aka.ms/wsl2

正在进行转换,这可能需要几分钟时间。
操作成功完成。
PS C:\Users\S2522\Desktop> wsl -l -v
NAME STATE VERSION
* CentOS8 Stopped 2

搞定!现在我们就有一个方便的CentOS8的WSL环境啦!

可以用如下命令,将当前的CentOS8设置为默认的wsl虚拟机。这样在windows命令行中执行wsl或者bash命令,就能直接进入CentOS8中。

1
wslconfig /setdefault CentOS8

重启电脑后,在powershell的下拉栏中会自动出现CentOS8的选项,点击它也能进入wsl虚拟机环境中。

image-20231015134927313

3.解决yum报错问题

因为这个CentOS的镜像是最小安装版本(类似于Docker安装的CentOS),所以内部的yum源都是坏掉的。执行yum update会出现如下报错。

1
2
3
4
5
[root@7945R9P ~]# yum -y update
Failed to set locale, defaulting to C.UTF-8
CentOS-8 - AppStream 68 B/s | 38 B 00:00
Failed to download metadata for repo 'AppStream'
Error: Failed to download metadata for repo 'AppStream'

这时候需要进行yum源的重新设置,参考本站博客解决这个问题就行

【Docker】配置CentOS容器时出现 Error Failed to download metadata for repo ‘appstream’ Cannot prepare internal mirrorlist | 转载

搞定yum之后,就可以正常安装你想要的开发软件了。这个系统很轻量,sudo和passwd等很多完整系统会自带的命令都没有,需要自行安装一些。

另外,我写过一个CentOS8的初始化脚本,可以自动化安装一些软件,这里安装的软件并不一定是你想要的,请酌情参考:https://gitee.com/musnows/centos8-init

rpm 30969错误

但我在重试的时候,yum安装软件还遇到了这个问题

1
2
3
4
5
6
RPM: error: db5 error(-30969) from dbenv->open: BDB0091 DB_VERSION_MISMATCH: Database environment version mismatch
RPM: error: cannot open Packages index using db5 - (-30969)
RPM: error: cannot open Packages database in /var/lib/rpm
The downloaded packages were saved in cache until the next successful transaction.
You can remove cached packages by executing 'yum clean packages'.
Error: Could not run transaction.

找到了GitHub的issue:Cannot install software with dnf after dnf update · Issue #46 · WhitewaterFoundry/Fedora-Remix-for-WSL · GitHub

该issue中的这个解决方案有效,注意,wsl纯净安装的centos是没有sudo命令的,把命令里面的sudo去掉就行了。(默认情况下进入的是root用户,也不需要sudo)

1
2
3
sudo dnf upgrade --refresh rpm glibc
sudo rm /var/lib/rpm/.rpm.lock
sudo dnf upgrade dnf

执行后,再重新执行yum install vim,不再出现报错。

1
yum install -y sudo

你可以执行上述命令安装一下sudo;

设置ls和ll命令别名

而且,默认情况下的ls命令也没有颜色输出,需要修改bash配置来设置命令别名;修改~/.bashrc文件即可。

1
2
alias ls='ls --color=auto'
alias ll='ls -l'

你也可以根据自己的喜好,改成zsh或者其他终端。

4.vscode连接

普通的虚拟机我们需要用vscode的remote ssh插件来连接,但是WSL主机我们直接用vsc的WSL插件来连接就行了,使用的效果和remote ssh插件是相同的

image-20231015111412100

在左侧这个远程连接控制器中(和Remote ssh是同一个位置),找到上方的下拉条,改成WSL目标,就能看到我们的CentOS8虚拟机。点击连接它就可以了。

image-20231015111429863

但是vscode默认链接的是root用户,一般情况下肯定不会在root下写代码的。所以需要配置一下子用户

修改虚拟机中的/etc/wsl.conf文件,添加下面两行

1
2
[user]
default=用户名

然后回到windows的命令行,重启wsl

1
wsl --shutdown CentOS8

再次启动wsl,这样vsc就能默认链接你的子用户了。

5.修改wsl资源限制

默认情况下,wsl2的虚拟机能访问到完整的系统资源,包括所有CPU核心和内存。

这就会导致如果Linux下对一些东西进行了缓存而没有及时清理,Windows是没办法回收这部分内存的。最终就导致我们Windows宿主机没有足够的内存可用了,这怎么行?

这种情况下,一般windows系统会把wsl直接给干掉,那我们虚拟机里面跑的活也没办法完成了。要知道,Linux可是很喜欢cache内存的,很容易会把宿主机的内存给干没。

为了解决这个问题,我们需要设置wsl的虚拟机内存/CPU限制。

Linux下可以用这两个命令来查看cpu和内存的配置信息,刚开始的时候应该是和你的宿主机的CPU和内存一样。

1
2
cat /proc/cpuinfo | grep processor # 查看cpu核心数量
cat /proc/meminfo | grep Total # 查看内存信息

在windows的C盘用户文件夹下,创建一个.wslconfig文件,并在内部写入限制

  • processors是cpu核数限制
  • memory和swap都是内存限制

顶多设置为宿主机内存的一半,避免宿主机卡顿。

1
2
3
4
[wsl2]
processors=8
memory=8GB
swap=8GB

这个配置文件的路径是(windows下)

1
C:\Users\你的用户名\.wslconfig

随后在windows的终端中使用如下命令,终止这个wsl虚拟机

1
2
3
4
PS C:\Users\S2522\Desktop> wsl --shutdown CentOS8
PS C:\Users\S2522\Desktop> wsl -l -v
NAME STATE VERSION
* CentOS8 Stopped 2

wsl命令中并没有--start选项,我们直接用wsl命令,就会自动重启并进入这个虚拟机。

这时候再在虚拟机内部看看CPU和内存信息,就可以看到你刚刚配置的性能限制结果了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@7945R9P ~]# cat /proc/cpuinfo | grep processor
processor : 0
processor : 1
processor : 2
processor : 3
processor : 4
processor : 5
processor : 6
processor : 7
[root@7945R9P ~]# cat /proc/meminfo | grep Total
MemTotal: 8136640 kB
SwapTotal: 8388608 kB
VmallocTotal: 34359738367 kB
HugePages_Total: 0

删除wsl主机

删除虚拟机的命令如下

1
wsl --unregister <DistributionName>

操作后,本地centos安装目录的ext4.vhdx虚拟磁盘文件会被删除。

1
2
3
PS C:\> wsl --unregister CentOS8
正在注销。
操作成功完成。

更多wsl命令参考微软官网 https://learn.microsoft.com/zh-cn/windows/wsl/basic-commands

6.启用systemctl

我们的系统里面有systemctl命令,但是没有办法使用。网上有些教程说用service命令来替代,但CentOS中是没有service命令的。

1
2
3
[root@7945R9P bison-3.8]# systemctl
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

6.1 distrod 第三方工具

我们需要用distrod来安装systemctl的组件,才能成功启用它。具体教程参考github仓库的README中的介绍。不是很难

https://github.com/nullpo-head/wsl-distrod

先下载一个自动安装的脚本(连不上github会报ssl或者timeout错误,请使用其他办法下载这个脚本再丢到虚拟机里面去就行)

1
2
3
curl -L -O "https://raw.githubusercontent.com/nullpo-head/wsl-distrod/main/install.sh"
chmod +x install.sh
sudo ./install.sh install

然后用下面两个命令之一来启动(第一个命令是会在windows开机自动启动的)

1
2
/opt/distrod/bin/distrod enable --start-on-windows-boot
/opt/distrod/bin/distrod enable

更多内容相见该仓库README

请注意,执行第一个自启动命令的时候需要windows的管理员权限,此时需要输入的是系统登录的微软账户的密码(不是你的PIN),看下面,我第一次输入密码输入的就是PIN,显示错误,第二次输入了微软账户的密码才成功。

1
2
3
4
5
6
7
8
9
10
11
12
[root@7945R9P pkg]# /opt/distrod/bin/distrod enable --start-on-windows-boot
[Distrod] Distrod has been enabled. Now your shell will start under systemd.
[Distrod] Enabling atuomatic startup of Distrod. UAC dialog will appear because scheduling
a task requires the admin privilege. Please hit enter to proceed.


Error
It seems the task has not been scheduled successfully. You may have typed a wrong password, or you may not have the
necessary administrative privileges. Do you want to retry?
[Y] Yes [N] No [?] 帮助 (默认值为“Y”): y
Enabling autostart has succeeded.
[Distrod] Distrod will now start automatically on Windows startup.

操作完成后,需要重启虚拟机。用如下命令将对应的wsl虚拟机关闭就行了,再次执行wsl就会重启这个虚拟机。

1
wsl --terminate CentOS8

如图,我的systemctl命令已经生效。

image-20231015150251531

也能正常通过systemctl命令启动mariadb数据库

image-20231015150404823

6.2 微软官方(推荐)

参考 https://zhuanlan.zhihu.com/p/569883693

查看wsl版本号命令为: wsl --version,如果此命令未正常回显版本号,或版本号低于0.67.6,那么你安装的wsl还不支持systemd。如下,我的wsl版本已经是支持的了。

1
2
3
4
5
6
7
8
PS C:\Users\S2522\Desktop> wsl --version
WSL 版本: 1.2.5.0
内核版本: 5.15.90.1
WSLg 版本: 1.0.51
MSRDC 版本: 1.2.3770
Direct3D 版本: 1.608.2-61064218
DXCore 版本: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows 版本: 10.0.22621.2134

进入wsl的CentOS虚拟机,执行如下命令

1
echo -e "[boot]\nsystemd=true" | sudo tee -a /etc/wsl.conf

随后exit退出虚拟机,回到windows终端命令行,重启wsl

1
wsl --shutdown

随后再次在windows命令行下执行wsl命令,重启这个虚拟机;

重启wsl虚拟机后,在虚拟机内部执行如下命令

1
ps --no-headers -o comm 1
  • 如果这个命令返回结果是systemd,则代表我们的systemctl命令已经可以使用。
  • 如果返回的是init(CentOS8),则设置失败(检查一下centos的wsl版本是否为2)
1
2
# ps --no-headers -o comm 1
systemd

如下图,我已经设置成功了!

image-20231015204810685

微软官方支持的systemd还是有一点是优于distrod的,那就是启用了官方 systemd 的 wsl2 实例,在用户停止操作后,会自动关闭,和未启用 systemd 时的特性一样,这有利于节约电脑的计算资源。