pkkvC6S.png

起因

很多同学拉取镜像使用一段时间后发现 C 盘快满了,把之前用过的镜像和容器删除,发现 WSL 挂载目录的虚拟磁盘大小没有变化,非常的奇怪
其实,不同于 WSL1
WSL2 本质上是虚拟机,所以 Windows 会自动创建 vhdx 后缀的虚拟磁盘文件作为存储.这个 vhdx 后缀的虚拟磁盘文件特点是可以自动扩容,但是一般不会自动缩容.一旦有很多文件把它"撑大"即使把这些文件删除它也不会自动"缩小"
所以删除文件后还需要我们手动进行压缩才能释放磁盘空间.

解决

找到要压缩的虚拟磁盘文件

如果你不是个大聪明如果你没更改挂载磁盘的位置,那他位置在 %userprofile%\AppData\Local\Docker\wsl\data\ext4.vhdx

关闭 Docker Desktop

在任务栏右下角右键单击 Docker Desktop 图标关闭 Docker 桌面,选择退出 Docker 桌面,等一会 Docker 图标没了之后,就证明 Docker 完全关闭了,然后,打开命令提示符:

wsl --list -v
pkkvMXF.png

压缩虚拟磁盘文件

在 PowerShell 中执行:

# 关闭 WSL2 中的 linux distributions
wsl --shutdown
# 运行管理计算机的驱动器的 DiskPart 命令
diskpart
在新打开的 DiskPart 命令窗口中执行:
# 选择虚拟磁盘文件
select vdisk file="就是步骤2.1虚拟磁盘文件的路径"
# 压缩文件
compact vdisk
# 压缩完毕后卸载磁盘
detach vdisk

上述操作执行完毕,WSL2 删除文件后空出来的磁盘空间就被释放了,可以去虚拟磁盘文件的路径看到 ext4.vhdx 文件大小已经减小.最后打开 Docker Desktop 可以看到原来镜像还在,成功解决问题。

捷径

powershell

生成 .ps1 文件 (PowerShell 脚本)
Write-Host "正在关闭 WSL2..."
wsl --shutdown
Write-Host "WSL2 已关闭."

Write-Host "正在启动 DiskPart..."
# 创建一个临时文件来存储 DiskPart 命令
$diskpartScript = Join-Path $PSScriptRoot "compress_disk.txt"
@"
select vdisk file="%userprofile%\AppData\Local\Docker\wsl\data\ext4.vhdx"
compact vdisk
detach vdisk
exit
"@ | Out-File -FilePath $diskpartScript -Encoding utf8

# 运行 DiskPart
diskpart /s $diskpartScript

# 删除临时文件
Remove-Item $diskpartScript

Write-Host "DiskPart 已完成."

Write-Host "完成!"
Read-Host -Prompt "按 Enter 键继续..."

然后在同目录下创建一个名为 compress_disk.txt 的文件
select vdisk file="%userprofile%\AppData\Local\Docker\wsl\data\ext4.vhdx"
compact vdisk
detach vdisk
exit
解释

Write-Host: 用于在 PowerShell 控制台中输出信息。
wsl --shutdown: 关闭 WSL2。
$PSScriptRoot: 表示当前 PowerShell 脚本所在的目录。
Join-Path: 将路径组合在一起,确保 DiskPart 能找到 compress_disk.txt。
Out-File: 将字符串输出到文件,-Encoding utf8 指定使用 UTF-8 编码,以防止中文乱码。
diskpart /s $diskpartScript: 使用 DiskPart 工具,/s 参数指定使用脚本文件。
Remove-Item: 删除临时文件。
Read-Host: 暂停脚本执行,等待用户按下 Enter 键。
compress_disk.txt: 包含 DiskPart 命令的文本文件。select vdisk 选择虚拟磁盘文件,compact vdisk 压缩虚拟磁盘,detach vdisk 卸载虚拟磁盘,exit 退出 DiskPart。

cmd

创建一个名为 compress_wsl2.bat 的文件
@echo off
echo 正在关闭 WSL2...
wsl --shutdown
echo WSL2 已关闭.

echo 正在启动 DiskPart...
diskpart /s "%~dp0compress_disk.txt"
echo DiskPart 已完成.

echo 完成!
pause
然后在同目录下创建一个名为 compress_disk.txt 的文件
select vdisk file="%userprofile%\AppData\Local\Docker\wsl\data\ext4.vhdx"
compact vdisk
detach vdisk
exit
解释

@echo off: 关闭命令回显,使脚本更简洁。
wsl --shutdown: 关闭 WSL2。
diskpart /s "%~dp0compress_disk.txt": 使用 DiskPart 工具,/s 参数指定使用脚本文件。%~dp0 表示当前批处理脚本所在的目录,确保 DiskPart 能找到 compress_disk.txt。
pause: 暂停脚本执行,以便您查看结果。
compress_disk.txt: 包含 DiskPart 命令的文本文件。select vdisk 选择虚拟磁盘文件,compact vdisk 压缩虚拟磁盘,detach vdisk 卸载虚拟磁盘,exit 退出 DiskPart。