发布时间:2021年9月3日
电脑买回来后就安装了WSL2,来帮忙执行一些bash脚本,但是一直没怎么使用,这几天才开始正常使用。
本地使用的配置是 Windows Terminal + Debian 配置,按照 Windows Terminal 官方推荐的设置给 wsl 的终端设置了主题,修改了 apt 的源仓库地址,装了一些包。
该文章用于记录一些使用中遇到的配置方案及问题
修改 /etc/apt/sources.list 文件,添加以下内容
deb http://mirrors.aliyun.com/debian/ buster main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster main non-free contrib
deb http://mirrors.aliyun.com/debian-security buster/updates main
deb-src http://mirrors.aliyun.com/debian-security buster/updates main
deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib
然后执行
sudo apt-get update
今天在安装 nodejs 的时候遇到了问题,因为 wsl2 是一个运行在虚拟机中的系统,其 IP 地址是经过 NAT转换的,无法直接共享 Windows 自身的代理配置,因此需要单独设置 WSL2 的代理,使其能正常访问互联网。
接下来就按照步骤讲解 WSL2 的代理配置流程:
在上面说过了 WSL2 是运行在 HyperV 中的独立系统,其网络地址是经过 NAT 转换的,所以我们需要先拿到对于 WSL2 系统来说 Windows 自身的 IP地址,执行以下命令我们可以拿到我们想要的信息:
cat /etc/resolve.conf
执行该条命令后,会输出以下内容:
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 172.25.240.1
其中的 172.25.240.1
就是我们 Windows 主机的 IP 地址
还是一样的原因,WSL2 会被认为是在局域网中的另一台电脑,所以如果要访问 Windows 的代理,需要开启代理软件的 允许局域网访问 选项
拿到了 Windows 主机的地址后,我们就可以在 WSL2 系统中配置代理了,为了方便我们使用,可以把配置代理名称写在 ~/.bashrc
文件中,这样每次打开 WSL2 的终端,便会自动设置了,脚本如下:
# 获取 Windows 主机IP
export hostip=$(cat /etc/resolv.conf |grep -oP '(?<=nameserver\ ).*')
# 设置 http https 代理
export https_proxy="http://${hostip}:10809"
export http_proxy="http://${hostip}:10809"
# 设置全局代理
export all_proxy="socks5://${hostip}:10808"
这样我们就可以正常访问全球互联网了
正常来说,按照上述的配置后就可以完成系统代理的设置,但是部分电脑可能存在无法连接的问题,此时需要修改Windows 主机的防火墙配置
首先我们需要打开控制面板,并进入 Windows Defender防火墙,点击左侧的 允许应用或功能通过 Windows Defender防火墙 。
在弹窗中,找到所有的代理程序,并勾选 专用、公用 两个选项,如下图:
此时,再去 WSL2 机器中尝试是否可以正常访问互联网,如果可以不用继续下一步。
在第一种方法没奏效的情况下,我们需要给在防火墙中开启 Windows 主机对应网关的对应 IP 段的访问策略。
还是在防火墙设置页面,点击左侧 高级设置,选择弹出窗左侧的 入站规则,点击右键新增规则,按照下图依次设置:
这样依次设置后再次尝试,一般即可解决问题。
以管理员身份打开 PowerShell 并执行下面这句指令,关闭 WSL 网卡对应的防火墙
Set-NetFirewallProfile -DisabledInterfaceAliases "vEthernet (WSL)"
在使用 wsl2 中的系统时,我们平常安装过的nodejs、docker等命令需要重新安装,使用 apt get-install
安装时可能会遇到依赖版本不同导致的无法安装问题,此时可以使用 aptitude
来帮忙进行依赖梳理,并完成包的安装。
首先,我们需要在环境中安装 aptitude
包,使用以下命令
# 安装aptitude
sudo apt-get install aptitude
# 修复依赖版本
sudo aptitude -f install
此时,aptitude
会梳理系统中当前包存在的依赖关系,如果存在未解决的依赖关系会询问你如何处理,类似于如下内容
The following packages have unmet dependencies:
iptables : Depends: libxtables12 (= 1.8.2-4) but 1.8.7-1 is installed
The following actions will resolve these dependencies:
Keep the following packages at their current version:
1) docker-ce [Not Installed]
2) iptables [Not Installed]
Accept this solution? [Y/n/q/?] n
会询问你是否要保留当前版本的包,我们选择 n
,目的是让 aptitude
重新梳理包的依赖关系,计算可行方案,然后会自动完成安装操作
windows界面安装 docker desktop 程序后wsl2 系统可以共享 docker 环境。
在使用的时候遇到了一些问题:
设置我们安装的linux系统为wsl默认系统
# 获取目前所有的wsl版本
wsl -l -v
我们可以看到系统中所有的wsl版本,此时我们指定安装的debian为默认版本
# 默认使用wsl2
wsl --set-version 2
# 默认使用debian
wsl --set-default Debian
进入docker desktop界面开启共享docker
执行以下命令,以防止在wsl2中上传镜像时无法认证问题
sudo ln -s /mnt/c/Program\ Files/Docker/Docker/resources/bin/docker-credential-desktop.exe /usr/bin/docker-credential-desktop.exe
此时再去执行 docker build -t
命令应该就没有问题了
在 windows 系统下编写的脚本在 wsl2 可能会存在无法执行的问题,造成这个问题的原因是Windows格式文件的换行符为 \r\n
,而Unix&Linux文件的换行符为 \n
这时我们需要一个工具帮我们完成换行符的替换,这个工具就是 dos2unix
# 安装dos2unix
sudo aptitude install dos2unix
# 转换文件
sudo dos2unix xxx.sh
# 执行文件
sudo ./xxx.sh
创建 /etc/wsl.conf
文件
编辑 /etc/wsl.conf
并输入以下内容
[automount]
options = "metadata"
在 Powershell 中使用 wsl --shutdown
关闭 wsl2
重新启动 wsl2 即可解决问题
使用 metadata
配置后,windows 会放开 wsl2 访问自己文件的权限,不再需要单独 chown
应该是文件共享机制问题,wsl2 无法做到实时监听文件的变动,需要把代码移动到 wsl2 中,重新安装依赖启动就可以做到热更新。
由于 wsl 的 hyper-v 经常会导致 wsl2 经常性访问内网失败,所以我将 wsl2 降级为了 wsl1,wsl1 会与 Windows 使用同一套网络配置,并不会创建新的局域网,更利于我们本地开发时通过 localhost
访问我们的开发服务器。
降级的操作也很简单,现在 powershell
中运行以下命令,输出当前系统中的 wsl 系统版本
wsl -l -v
# output
NAME STATE VERSION
* Ubuntu Running 1
docker-desktop Stopped 2
docker-desktop-data Stopped 2
然后执行以下命令
# 默认使用wsl1
wsl --set-default-version 1
# 转换Ubuntu为wsl1版本
wsl --set-version Ubuntu 1
这样就完成了 wsl2 至 wsl1 的降级
桌面端的 docker desktop
提供了 wsl2
中注入 docker
的方法,但是并不支持 wsl1
,但是可以通过其他方式实现在 wsl1 中使用 docker
首先我们需要打开 docker desktop 设置中暴露进程选项,如下图
然后在 wsl1 系统中执行以下命令
# 进入用户目录
cd ~
# 下载docker
wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.8.tgz
# 解压至当前目录
tar zxvf docker-20.10.8.tgz
# 添加环境变量
export DOCKER_HOST=tcp://localhost:2375
# 编辑bashrc并添加docker所需的配置项
sudo vim ~/.bashrc
# 设置docker的host地址
export DOCKER_HOST="tcp://0.0.0.0:2375";
# 添加alias
alias docker="~/docker"
# 重新加载alias
source ~/.bashrc
此时在 wsl1 中直接使用 docker 命令就可以了
因为WSL2本质上是以虚拟机的形式运行的,会在C盘中创建其虚拟磁盘文件,随着 wsl2 越来越深入的使用,我们会下载很多的 docker 镜像、项目等,这些内容在使用时占据着我们磁盘的空间,但在 wsl2 中删除这些内容后仍然不会自动释放这部分空间,这就导致我们电脑 C 盘的空余空间越来越小。
为了解决这个问题,我们需要手动压缩 wsl2 系统使用的虚拟磁盘文件,好在 windows 自身携带了这样的工具。
首先,为了定位 wsl2 使用的磁盘空间位置,我们需要借助磁盘分析软件 wiztree
,该软件会分析在对应磁盘中不同文件的大小,并按从大到小排列,非常直观,软件界面如下图
在右侧找到对应的 .vhdx
格式的虚拟磁盘文件,并在左侧通过鼠标右键复制路径,我们就得到了虚拟磁盘文件的位置,就可以着手压缩了。压缩的命令很简单,在powershell中按顺序执行以下命令
wsl --shutdown // 关闭wsl
diskpart // 打开diskpart
此时电脑会自动弹出 diskpart 命令行界面,我们再依次输入以下命令:
select vdisk shell="路径" # 挂载对应虚拟磁盘
attach vdisk readonly # 将虚拟磁盘设置为只读
compact vdisk # 压缩虚拟磁盘
detach vdisk # 取消挂载虚拟磁盘
exit # 退出 diskpart
此时再查看 C 盘,会发现多余占用的空间都被释放了,此时再正常启动 wsl2 即可