前言
自从 Win 10 推出 WSL2 之后,Docker Desktop 就默认使用 WSL2 运行了,此时通过 Hyper-V 无法再设置 Docker 镜像的存储位置,而且 Docker Desktop 的镜像位置设置项也不见了。
这就带来一个问题,由于 Docker 镜像默认是存储在 C 盘的 %LOCALAPPDATA%/Docker/wsl
目录,C 盘空间会越来越小,这对于 C 盘只作为系统盘的同学而言就十分不友好了,尤其是现在不少同学的 C 盘都是固态盘。
WSL 是适用于 Linux 的 Windows 子系统可让开发人员按原样运行 GNU/Linux 环境,包括大多数命令行工具、实用工具和应用程序,且不会产生虚拟机开销。WSL2 作为新版本,它支持适用于 Linux 的 Windows 子系统在 Windows 上运行 ELF64 Linux 二进制文件,它的主要目标是提高文件系统性能,以及添加完全的系统调用兼容性。
为了解决此问题,就需要想办法把 Docker 镜像迁移到其他盘符。
查看 Docker 官网说明,发现原来启用 WSL 后,Docker 运行数据都在 WSL 发行版中,因此镜像存储位置只能由 WSL 管理。
安装 Docker 后,Docker 会自动创建 2 个发行版:
- docker-desktop: 存储在
%LOCALAPPDATA%\Docker\wsl\distro
- docker-desktop-data: 存储在
%LOCALAPPDATA%\Docker\wsl\data
(占用空间的元凶)
在 WSL1 时代,几乎都是使用第三方工具 LxRunOffline 进行迁移,但是这个工具到了 WSL2 时代就不能用了:实践证明,LxRunOffline 确实可以迁移自己安装的发行版,却迁移不了 Docker 自动创建的 2 个发行版。
解决方法
其实用 WSL 命令就可以简单实现迁移,操作步骤如下:
- 停止 Docker 进程
- 关闭所有发行版:
wsl --shutdown
- 导出 docker-desktop-data 发行版:
wsl --export docker-desktop-data D:\wsl\docker\tmp\docker-desktop-data.tar
- 注销 docker-desktop-data 发行版:
wsl --unregister docker-desktop-data
- 导入 docker-desktop-data 到期望迁移的目录:
wsl --import docker-desktop-data D:\wsl\docker\data\ D:\wsl\docker\tmp\docker-desktop-data.tar --version 2
(迁移目录D:\wsl\docker\data\
可根据个人需求修改) - (可选)删除第 3 步导出的临时文件:
D:\wsl\docker\tmp\docker-desktop-data.tar
- (可选)另一个 Docker 发行版 docker-desktop 可使用同样方式迁移,但是其占用空间很小,不迁移亦可
迁移完成后可发现
%LOCALAPPDATA%/Docker/wsl
目录下的发行版文件已被删除, C 盘空间已释放
PowerShell 一键迁移脚本
# wsl2_move_docker_image.ps1
# Docker 镜像存储位置一键迁移脚本(适用于 WSL2 版本)
#
# Powershell Script 3.0+
# ---------------------------------------------------------------------------------------
# 脚本使用方式(需使用管理员权限执行):
# .\wsl2_move_docker_image.ps1 -target "D:\wsl\docker"
# ---------------------------------------------------------------------------------------
#
# target: 期望迁移的目录
param([string]$target="D:\wsl\docker")
Write-Host "Stop docker ..."
net stop "com.docker.service"
Write-Host "Stop wsl ..."
wsl --shutdown
Write-Host "Move docker-desktop-data image ..."
wsl --export docker-desktop-data $target\tmp\docker-desktop-data.tar
wsl --unregister docker-desktop-data
wsl --import docker-desktop-data $target\data\ $target\tmp\docker-desktop-data.tar --version 2
Remove-Item $target\tmp\docker-desktop-data.tar -recurse
Write-Host "Move docker-desktop image ..."
wsl --export docker-desktop $target\tmp\docker-desktop.tar
wsl --unregister docker-desktop
wsl --import docker-desktop $target\distro\ $target\tmp\docker-desktop.tar --version 2
Remove-Item $target\tmp\docker-desktop.tar -recurse
Write-Host "Finish."
小知识:WSL 如何访问宿主机服务?
- WSL1 与宿主机在同一网络下,直接访问
127.0.0.1
即可 - WSL2 因虚拟技术的差异,与宿主机不在同一网络下,且每次重启时宿主机 IP 均会变化,故只能通过
cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }'
命令获取宿主机 IP