WSL开发系列-基础篇

本人使用win11+idea+docker+wsl2作为日常开发测试环境,
随着版本的迭代完善,加上本人丰富的踩坑经验,wsl已基本能满足我对linux单机使用的需求。
故重新整理wsl开发环境相关配置、优化、使用集成,形成本系列文章。
本文为WSL开发系列的开篇,也是目录,建议阅读此篇,再根据需求跳转。

导航

一 问答

  • 问:为什么不买一台linux服务器?

    答:因为没钱,且交不起电费。事实上已经买了nas了,但性能孱弱,无法用于开发。

  • 问:为什么不买云主机?

    答:因为没钱,且交不起电费。事实上已经买了两台了,加起来不到8c16g(我笔记本的一半)。

  • 问:为什么不装双系统系统?

    答:体验割裂,垃圾。

  • 问:为什么不直接装linux系统/黑苹果?

    答:生态匮乏(要玩游戏)。

  • 问:和虚拟机相比除了性能有什么优势?

    答:虚拟机使用上相当于多了台服务器,开发上并不方便。
    而wsl可以实现一个工程,一套源码,在windows下开发,在linux下运行。
    idea自带支持wsl,虽然也支持ssh,但体验上差一些。

    二 安装和基础配置

    建议优先看官方文档,会不断更新,是最可靠的。
    https://learn.microsoft.com/zh-cn/windows/wsl/
    下面的一些操作也是,我会尽可能给出官方链接,对比着来看。
    我的是自己的实际操作或补充,但可能失效了。

1 安装WSL

见:https://learn.microsoft.com/zh-cn/windows/wsl/install
现在已经可以一行命令安装了:wsl --install
我用的是Ubuntu-20.04,对应的命令应该是 wsl --install Ubuntu-20.04
安装过程会提示输入一个默认用户和对应密码,注意不能用root(已存在)

2 安装windows terminal

在应用商店下载安装,自行美化即可,新版本已可直接通过选项配置,不需要直接操作配置文件

另外建议在terminal配置文件中,找到Ubuntu的配置项,修改其启动目录为 “//wsl$/Ubuntu-20.04/home”

3 修改默认用户为root

见:https://learn.microsoft.com/zh-cn/windows/wsl/basic-commands#change-the-default-user-for-a-distribution

  1. 查看当前wsl列表:
    之所以要这一步是因为如果装了多个版本的ubuntu,其标识可能不一样

    1
    wsl -l 
  2. 修改对应wsl默认用户

    注意,操作标识不含特殊符号,如Ubuntu-20.04,则以下命令为Ubuntu2004(或全小写 ubuntu2004)

    1
    Ubuntu-20.04 config --default-user root

    截图

    不过需要注意,很多linux的软件默认不支持root用户启动,如chrome,相关处理方法见下文

    4 将linux根目录映射到网络驱动器

    见:https://learn.microsoft.com/zh-cn/windows/wsl/filesystems#view-your-current-directory-in-windows-file-explorer
    在文件地址栏输入 \wsl$ ,可以看到已安装的wsl文件系统,如 Ubuntu
    右键-映射网络驱动器,选择要映射的盘符即可。
    另外注意,可以用explorer.exe . 命令使用windows文件资源管理器打开当前路径(这个功能用得比较少)

5 配置国内软件源

参考:https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/

1
2
3
4
5
6
7
# 备份
cp /etc/apt/sources.list /etc/apt/sources.list.backup
# 替换
sudo sed -i "s@http://.*archive.ubuntu.com@https://mirrors.tuna.tsinghua.edu.cn@g" /etc/apt/sources.list
sudo sed -i "s@http://.*security.ubuntu.com@https://mirrors.tuna.tsinghua.edu.cn@g" /etc/apt/sources.list
# 更新
apt-get update -y && apt-get upgrade -y

三 可选进阶配置

1 配置代理

如果代理软件是装在windows系统的,参考WSL开发系列-网络篇,使用my.win就行了

1
2
3
4
5
6
7
8
9
cat << 'EOF' >> /etc/profile
export http_proxy="http://my.win:7890"
export https_proxy="http://my.win:7890"
export ftp_proxy="http://my.win:7890"
export PROXY_HOST="my.win"
export PROXY_PORT=7890
export no_proxy="*.internal,localhost,172.*,127.*"
EOF

2 配置ssh

除非确实需要,不然不建议启用ssh
应用场景:idea支持ssh运行环境但不支持wsl的时候

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
## 更新软件
apt -y update && apt -y upgrade
## 安装ssh(一般已安装)
apt install -y openssh-server
## 配置允许密码登录
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
## 配置允许root登录
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
## 启动/重启
service ssh restart
## 修改root密码
passwd
## 链接root目录(一般不需要执行!)
ln -s /root /home/root

## 测试ssh(使用刚设置的root密码登录)
ssh root@localhost

3 在wsl中启用systemd支持

wsl.conf配置参考:https://learn.microsoft.com/zh-cn/windows/wsl/wsl-config

在/etc/wsl.conf(文件不存在则新建)中添加如下配置

1
2
[boot]
systemd=true

需要wsl --shutdown重启生效
然后验证:

1
2
systemctl list-unit-files --type=service

4 禁止添加Windows-PATH

windows和wsl同时安装java,但wsl的hadoop需要使用wsl的java而非windows的

为了避免开发环境冲突,建议关闭Windows-PATH。
需要在wsl中使用windows软件的时候用路径全称即可,一般用得少。

在/etc/wsl.conf(文件不存在则新建)中添加如下配置

1
2
3
# 不加载Windows中的PATH内容
[interop]
appendWindowsPath = false

5 wsl-docker(ext4.vhdx)磁盘空间回收

问题描述:
Docker Desktop for Windows v2 使用 WSL2,
将所有映像和容器文件存储在单独的虚拟卷 (vhdx) 中。
当需要更多空间(达到一定限度)时,这个虚拟硬盘文件会自动增长。
不幸的是,如果您回收一些空间,即通过删除未使用的图像,vhdx 不会自动缩小。

处理方法:
暂时没有好的处理方法,得手动执行命令,或者利用Docker Desktop的Troubleshoot完全清除。
参考: https://github.com/microsoft/WSL/issues/4699

ext4.vhdx的完整路径获取方法:
见:https://learn.microsoft.com/zh-cn/windows/wsl/disk-space?source=recommendations#how-to-locate-the-vhdx-file-and-disk-path-for-your-linux-distribution

1
(Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | Where-Object { $_.GetValue("DistributionName") -eq 'Ubuntu-20.04' }).GetValue("BasePath") + "\ext4.vhdx"

执行命令前注意先停止Docker Desktop和WSL2
windows专业版执行命令:

1
2
wsl --shutdown
optimize-vhd -Path C:\…\…\ext4.vhdx -Mode full

windows家庭版执行命令:

1
2
3
4
5
6
7
8
wsl --shutdown
diskpart
# open window Diskpart
select vdisk file="C:\…\…\ext4.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exit

6 在wsl中以管理员身份调用powershell

2023.4更新:在更新wsl之后,调用wudo失败(socket.timeout: timed out),
5个open的issues有3个是与此相关的,可见不是小概率事件。且无较好解决方法,故本步骤不推荐使用。

wsl本身就有对windows软件的交互能力,但默认情况下没有管理员权限

参考:https://github.com/Chronial/wsl-sudo
前提:已安装python3,且版本>= 3.5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 下载py脚本
wget https://raw.githubusercontent.com/Chronial/wsl-sudo/master/wsl-sudo.py
# 替换成完整路径(如果你的wsl没有关闭使用windows的环境变量,则可忽略这一步)
sed -i "s#\"powershell.exe\"#\"/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe\"#g" wsl-sudo.py
# 修改名称并授权
mv wsl-sudo.py wudo
chmod a+x wudo

# 测试:报错"拒绝访问"
/mnt/c/WINDOWS/system32/net.exe sessions
# 测试:无报错
./wudo /mnt/c/WINDOWS/system32/net.exe sessions

# 拷贝到系统路径下
mv wudo /usr/bin/

# 再次测试
wudo /mnt/c/WINDOWS/system32/net.exe sessions

以后在wsl里面需要以admin身份调用powershell指令只需要加上前缀 wudo 即可

7 wsl存储位置迁移

wsl镜像导出导入命令参考:https://learn.microsoft.com/zh-cn/windows/wsl/enterprise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 关闭wsl
wsl --shutdown
# 确保为stop状态
wsl -l -v
# 文件夹需提前创建
wsl --export Ubuntu-20.04 E:\UbuntuWSL\ubuntu.tar
# 注销
wsl --unregister Ubuntu-20.04
# 确定已注销
wsl -l -v
# 执行导入(如果失败可再次尝试执行)
# 执行完会在E:\UbuntuWSL\创建ext4.vhdx,然后ubuntu.tar就可以删掉了
wsl --import Ubuntu-20.04 E:\UbuntuWSL\ E:\UbuntuWSL\ubuntu.tar
wsl -l -v

7 windows-docker存储位置迁移

除了常规的用户linux系统(如ubuntu),新版的windows-docker也是基于wsl2的

参考:https://docs.docker.com/desktop/wsl/

Docker Desktop installs two special-purpose internal Linux distros docker-desktop and docker-desktop-data.
The first (docker-desktop) is used to run the Docker engine (dockerd) while the second (docker-desktop-data) stores containers and images.
Neither can be used for general development.

即docker使用的磁盘目录无法通过data-root来指定,而是在名为docker-desktop-data的wsl上。
其ext4.vhdx具体位置可通过以下命令获取:

1
(Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | Where-Object { $_.GetValue("DistributionName") -eq 'docker-desktop-data' }).GetValue("BasePath") + "\ext4.vhdx"

所以其目录迁移和普通的wsl迁移一致

执行下面命令之前,先关闭windows-docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 关闭wsl
wsl --shutdown
# 确保为stop状态
wsl -l -v
# 文件夹需提前创建
wsl --export docker-desktop-data E:\dockerData\docker-desktop-data.tar
# 注销
wsl --unregister docker-desktop-data
# 确定已注销
wsl -l -v
# 执行导入(如果失败可再次尝试执行)
wsl --import docker-desktop-data E:\dockerData\ E:\dockerData\docker-desktop-data.tar
wsl -l -v

# 再次查看位置,确认修改成功
(Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | Where-Object { $_.GetValue("DistributionName") -eq 'docker-desktop-data' }).GetValue("BasePath") + "\ext4.vhdx"

再次启动windows-docker

参考:https://stackoverflow.com/questions/62441307/how-can-i-change-the-location-of-docker-images-when-using-docker-desktop-on-wsl2


WSL开发系列-基础篇
https://linshenkx.github.io/wsl-dev-base/
作者
John Doe
发布于
2023年2月11日
许可协议