Docker for windows的容器类型和文件系统

Docker for windows的工作目录修改

Posted by 夏启钊 on Tuesday, August 8, 2023

“Docker for windows的工作目录修改”

Docker for windows的容器类型和文件系统

在windows 10系统中,docker的工作目录默认是C盘(C:\Users\Username\AppData\Local\Docker\wsl),这经常会导致一个问题就是容器和镜像多了之后这里的ext4.vhdx文件就会变得几十个G大,占用很多C盘空间,带来很多不便(比如docker用着用着就开始报错磁盘空间不够了,或者docker pull命令的时候报错read-only)。希望找到一个比较方便的方法来修改,捣鼓一通之后发现这个不只是工作目录的问题,还涉及到了一些文件系统和操作系统虚拟化方面的内容,写个短文介绍一下。

1. 工作目录切换

为了节约时间,先把切换目录的方法写在最前面:查了一些修改docker工作目录到其他盘符下的方法,发现大部分都需要重装docker,有点不太方便。最终找到了一个很好的不需要重装docker就直接能切换目录的方法。直接上shell:

# 直接管理员打开powershell
C:\WINDOWS\system32> wsl --list --verbose
  NAME                   STATE           VERSION
* docker-desktop-data    Running         2
  docker-desktop         Running         2

C:\WINDOWS\system32> wsl --export docker-desktop D:\Docker\workspace4DockerEXT\data\docker-desktop.tar
正在导出,这可能需要几分钟时间。
操作成功完成。

C:\WINDOWS\system32> wsl --export docker-desktop-data D:\Docker\workspace4DockerEXT\data\docker-desktop-data.tar
正在导出,这可能需要几分钟时间。
操作成功完成。

C:\WINDOWS\system32> wsl --shutdown
C:\WINDOWS\system32> wsl --unregister docker-desktop
正在注销。
操作成功完成。
C:\WINDOWS\system32> wsl --unregister docker-desktop-data
正在注销。
操作成功完成。

C:\WINDOWS\system32> wsl --import docker-desktop D:\Docker\workspace4DockerEXT\docker-desktop D:\Docker\workspace4DockerEXT\data\docker-desktop.tar --version 2
正在导入,这可能需要几分钟时间。
操作成功完成。
C:\WINDOWS\system32> wsl --import docker-desktop-data D:\Docker\workspace4DockerEXT\docker-desktop-data\ D:\Docker\workspace4DockerEXT\data\docker-desktop-data.tar --version 2
正在导入,这可能需要几分钟时间。
操作成功完成。

# 这里的路径都需要提前创建,如果没有创建会报错:
系统找不到指定的路径。
Error code: Wsl/ERROR_PATH_NOT_FOUND

# 参考:https://blog.51cto.com/u_15242378/5325380(但是原文的路径有一点小错误,可以直接参考本文的)

如果赶时间其实上面就是本文的全部内容了,下面是寻找上面的攻略的时候发现的一些有趣的东西。

2. 容器类型和对应的文件系统

虽然很难被意识到,但是实际上docker for windows针对linux容器和windows容器提供了两种了不同的容器类型:windows container和linux container,切换方法是在任务栏右侧托盘中右键docker图标,会显示switch to windows containers...(默认安装的时候是linux container)

这里的两种container,最主要的区别就是windows container只能运行windows的image,而linux container 只能运行linux的container。

2.1 虚拟化技术

具体来说,他们使用的虚拟化技术和对应的文件系统也是不同的——

linux主要使用了WSL2技术(实际上这也是一种基于Hyper-V的虚拟化技术,如果你对Linux内核有了解,就可以发现当我们在windows中的docker中使用linux 容器时,输入uname -r命令输出的内核版本就是WSL,这是一种很轻量化的虚拟化技术,可以使得container中运行的系统共享主机的操作系统内核,BTW这也是虚拟机和docker的区别,虚拟机拥有自己的内核)。

而Windows container使用了Windows内核的容器化虚拟技术,主要是基于Hyper-V技术,也是允许容器和主机共享windows内核,但是他们的文件系统、注册表和进程空间都是不共用的。

2.2 文件系统

而文件系统也有差别,当我们使用docker info命令查看docker运行环境的时候:

如果你使用的是Linux container,就会看到Docker Root Dir: /var/lib/docker这一行,而这就意味着,实际上Docker Desktop for Windows在内部运行了一个轻量级的Linux发行版(通常是LinuxKit),用于托管和运行Linux容器。而Docker将整个Linuxkit的文件系统存储在一个虚拟硬盘文件下,即ext4.vhdx,所以ext4.vhdx并不是某个具体linux容器的文件系统。而ext4正是很常见的一种linux文件系统(windows通常是NTFS)。

ext4.vhdx这个虚拟磁盘文件允许 Docker 在 Windows 上以更加原生的方式运行 Linux 容器,提供了类似 Linux 环境的文件系统功能和命令支持,使得 Docker 容器在 Windows 上拥有更好的兼容性和性能。用户无需直接操作这个虚拟磁盘文件,Docker 会在后台进行管理。

实际上看到stackoverflow论坛上有人说可以使用一些工具比如7zip打开这个文件(终止docker进程之后),之后可以看到version-pack-data\community\docker,这表示了存储了哪些image(但是我没有试过)

参考:https://stackoverflow.com/questions/42250222/where-is-docker-image-location-in-windows-10

而如果你使用的是windows container(这可能需要主机上的windows支持Hyper-V,简而言之就是企业版、教育版、专业版的windows10,家庭版不支持Hyper-V,附上微软的Hyper-V文档),docker info命令就会看到C:\ProgramData\Docker\,这意味着所有的image都存储在这个路径下

stackoverflow论坛上也有人提供了修改工作目录的方法(但是我也没有试过):

配置文件在C:\ProgramData\Docker\config\daemon.json,在这个json中添加一个"graph"如下:

{
"registry-mirrors": [],
"insecure-registries": [],
"debug": true,
"experimental": false,
"graph": "D:\\ProgramData\\Docker"
}

参考:https://stackoverflow.com/questions/42250222/where-is-docker-image-location-in-windows-10

3. Misc(杂项)

3.1 如果Hyper-V安装有问题

如果想尝试windows container,安装了Hyper-V,但是发现一直报错"containers feature is disabled. enable it using the powershell script (in an administrative powershell) and restart your computer before using docker desktop: enable-windowsoptionalfeature -online -featurename $(“microsoft-hyper-v”, “containers”) -all",附上一个尝试过的重新安装Hyper-V的教程:

Disable-WindowsOptionalFeature -FeatureName microsoft-hyper-v -online
restart-computer

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
restart-computer

Enable-WindowsOptionalFeature -Online -FeatureName Containers -All

Enable-WindowsOptionalFeature -Online -FeatureName $("VirtualMachinePlatform","Microsoft-Windows-Subsystem-Linux") 
restart-computer

# 参考:https://stackoverflow.com/questions/36590514/how-to-enable-the-windows-10-containers-feature(但是原文的字符串内容有一点小错误,可以直接参考本文的)

3.2 删除全部镜像清理C盘

直接GUI指导,简单粗暴有效,参考:https://stackoverflow.com/questions/70946140/docker-desktop-wsl-ext4-vhdx-too-large

3.3 WSL VDHX相关

怎样管理VHDX(微软文档):https://learn.microsoft.com/zh-cn/windows/wsl/disk-space