ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Docker Desktop 的 docker-desktop 虚拟机与 builder-jammy-base 镜像到底有何区别?

Docker Desktop 的 docker-desktop 虚拟机与 builder-jammy-base 镜像到底有何区别? 在 Windows 上折腾 Docker 的人基本都遇到过这么个困惑明明装的是 Docker Desktop for Windows为什么打开 PowerShell 执行docker images会看到一个叫builder-jammy-base:latest的镜像这个镜像和 Docker Desktop 自带的 Linux 环境有什么关系到底谁才是那个真正“跑 Linux”的东西这个问题我一开始也犯过迷糊。后来因为排查一次构建环境异常不得不把 Docker Desktop 的整套结构翻了个底朝天才算彻底搞明白docker-desktop 是一个常驻后台的轻量级 Linux 虚拟机而 builder-jammy-base:latest 是虚拟机里 BuildKit 构建流程使用的一个临时镜像。两者的角色、生命周期、资源占用完全不在同一个层面上。这篇文章我就把这两个东西的核心区别、工作原理、实操验证方法一次说清楚顺便把我在实际排障中踩过的坑一并写出来。1. 先搞清楚这两个东西分别是什么1.1 docker-desktop 的本质藏在 Windows 里的轻量 Linux 虚拟机Docker 在 Windows 上跑 Linux 容器靠的不是什么魔法而是虚拟机。Docker Desktop 默认使用 WSL2 作为后端它会在系统里注册两个 WSL 发行版其中一个就直接叫docker-desktop。这个发行版可不仅仅是给你“看一眼”用的它是整个 Docker 引擎的家。daemon也就是后台服务、容器运行时容器网络、Linux 内核模块全都跑在这个小小的发行版里。你执行docker run创建出来的每个 Linux 容器实际上都生存在这个虚拟机内部。它存在你的磁盘上占用的是 WSL 的虚拟磁盘文件一般存放在%LOCALAPPDATA%\Docker\wsl\disk\docker_data.vhdx这类位置。我可以用一个生活化的类比来理解它如果你的 Windows 是一套商品房那 Docker Desktop 就是在阳台上搭建的一个集装箱小屋这个集装箱就是docker-desktop虚拟机。你在小屋里怎么折腾都不影响外面商品房的结构但是商品房的供电、供水决定了小屋能不能住人。Windows 的 CPU、内存、虚拟化能力就是供给这个小屋的资源。1.2 builder-jammy-base 是什么构建阶段的“临时食堂”builder-jammy-base:latest这名字乍看很唬人拆开就清楚了builder说明它是构建用的jammy是 Ubuntu 22.04 LTS 的代号Ubuntu 22.04 的版本代号就是 Jammy Jellyfishbase表示它是最底层的基础镜像。也就是说它是一套基于 Ubuntu 22.04 的精简构建环境。它通常会在你使用 Docker Desktop 的 BuildKit 构建容器镜像时被自动拉取下来。尤其是当你使用docker buildx并且构建驱动选择了默认的 Docker Desktop 驱动时构建过程需要一个干净的、预置了工具链的运行环境builder-jammy-base就是干这个的。它跟我们平时自己拉取的ubuntu:22.04镜像不一样。我们自己拉取ubuntu是为了跑业务容器而builder-jammy-base更偏向“一次性的构建工具场”里面往往会预置编译所需的常见基础工具、系统库和网络配置让构建流程在干净且一致的环境里执行。你不用手动去docker pull它它通常会自动出现。这也是新手最迷惑的地方为什么我什么都没做docker images里就多了一个陌生的镜像。1.3 层级关系VM 是宿主镜像只是虚拟机里的产物理清关系的关键在于层级。我再换个角度解释docker-desktop虚拟机类似你电脑上的操作系统是承载所有容器的宿主层。builder-jammy-base:latest镜像是运行在这个宿主层上的 Docker 镜像属于“容器镜像”这个层面。打个比方docker-desktop虚拟机相当于一个工厂的厂房厂房提供电力、照明、安保builder-jammy-base则是一条具体的组装流水线流水线在厂房里工作但流水线不是厂房本身。日常使用中最常见的误区是有人试图用docker exec -it builder-jammy-base /bin/bash进去改东西以为这样就能修改 Docker Desktop 的 Linux 环境。这方向就完全整反了你想进虚拟机不应该通过docker exec而应该通过 WSL 的命令去访问那个docker-desktop发行版。2. 逐项拆解它们的关键区别2.1 运行层面内核态 vs 用户态最本质的区别在于运行层级。docker-desktop虚拟机拥有一个完整的 Linux 内核Docker 引擎的 daemon 进程直接跑在这个内核之上。而builder-jammy-base:latest只是一个镜像它本身没有内核当它作为容器或构建环境运行时使用的是宿主虚拟机也就是docker-desktop的内核。这里可以类比为一栋写字楼虚拟机是整栋楼水电主干管是内核而容器镜像只是其中一个办公室里的家具布局楼里供水供电靠的是整栋楼的基础设施。你在办公室容器里怎么摆放桌椅安装依赖改动不了主干管内核的任何配置。这也解释了为什么在容器里执行uname -r看到的内核版本和 Docker Desktop 虚拟机相同但与 Windows 完全不同。因为容器共享的是虚拟机的内核而不是 Windows 的内核。2.2 生命周期常驻后台 vs 按需拉取docker-desktop虚拟机的生命周期和 Docker Desktop 图形界面是绑定的。只要你启动了 Docker Desktop 或者设置了开机自启这个 WSL 发行版就会常驻后台。我平时留意过哪怕界面上没有打开任何容器后台的docker-desktop进程依然占用着几百 MB 到 1GB 不等的内存因为引擎、网络组件、DNS 服务这些都得持续运行。builder-jammy-base则完全是另一套节奏。它不常驻。你第一次使用构建功能时它会被拉取之后如果镜像没有变更就一直缓存着。如果长时间不用或者 Docker Desktop 执行了清理垃圾镜像的操作它可能会被删掉。下次需要时又重新拉取。它的存在仅仅是“以备不时之需”。2.3 资源占用内存大头 vs 磁盘缓存很多人都遇到过 Docker Desktop 内存占用高的烦恼这些资源绝大部分是docker-desktop虚拟机的不是某个容器镜像的。每启动一个容器本质上就是在这个虚拟机里新增了几个进程内存自然水涨船高。镜像本身是静态文件拉下来之后躺着不动不会吃内存。builder-jammy-base主要占用的是磁盘空间。它是一个基础镜像里面包含了一些工具链体积可能有一百多 MB 甚至更大。如果有强迫症想清理它直接docker rmi builder-jammy-base:latest就行。删掉之后不会影响 Docker Desktop 运行只是下次构建时重新拉取而已。2.4 文件系统层面VDHX 文件 vs OverlayFS 层由于docker-desktop是虚拟机它的整个根文件系统都包裹在一个 VHDX 虚拟磁盘文件里。这个文件可以非常大而且默认情况下不会自动缩小就算你删了里面很多内容磁盘文件依然占着空间。很多人遇到 C 盘空间莫名告急九成以上是 Docker Desktop 的 VHDX 文件在膨胀。builder-jammy-base这个镜像则存在另一个空间里。它是 Docker 引擎自己管理的镜像层以 OverlayFS 的方式存放一般也在同一个虚拟磁盘里但它是通过 Docker 的存储驱动通常是 overlay2来读写不直接暴露成一个独立的磁盘文件。2.5 交互方式WSL 命令 vs Docker 命令对普通用户来说最直观的区别是你能用什么命令进去看它。进docker-desktop虚拟机可以直接在 PowerShell 或 CMD 里执行wsl -d docker-desktop如果你看到wsl: 检测到 localhost 代理配置但未镜像到 WSL之类的提示忽略即可。进去之后你就身处一个精简的 Linux 环境可以执行top、df -h、ps aux等命令观察引擎状态。而想进builder-jammy-base你反而应该用 Docker 命令docker run -it --rm builder-jammy-base:latest /bin/bash但它作为一个基础镜像里面可能没有安装完整可交互的 shell更常见的做法是把它作为一个FROM基础镜像去构建自己的镜像而不是直接进去操作。2.6 一个容易混淆的小细节docker-desktop 里还能看到 builder-jammy-base 吗有意思的是你在 Windows 宿主机上执行docker images能看到builder-jammy-base觉得它好像和 Windows 很亲密。但当你wsl -d docker-desktop进去之后在虚拟机里执行docker images又会发现镜像列表惊人地相似。因为 Docker CLI 连的都是同一个 Docker 引擎你在 Windows 上执行docker命令其实是在向docker-desktop虚拟机里的 daemon 发请求。所以操作路径其实是Windows 上的 docker CLI → 通过网络通常是 npipe 或 TCP→docker-desktop虚拟机里的 docker daemon → daemon 管理虚拟机内的容器和镜像。3. 实操验证如何一步步观察这两者的真实面貌3.1 打开 WSL 查看发行版列表先打开 PowerShell输入wsl -l -v正常情况下会看到两个发行版一个是 Docker Desktop 自带的docker-desktop另一个可能是docker-desktop-data不同版本名称略有差异。状态都是Running。如果这个是Stopped说明 Docker Desktop 当前没有启动或者启动失败了。这两个发行版就是 Docker Desktop 在 WSL2 世界的全部家当。docker-desktop-data主要负责存放 Docker 的数据docker-desktop负责运行引擎。3.2 进入 docker-desktop 虚拟机内部看进程继续在 PowerShell 里执行wsl -d docker-desktop进入之后执行ps aux --sort-%mem | head -20你会发现 dockerd 进程赫然在列后面还挂了一堆 containerd、containerd-shim 之类的东西。这就是整个 Docker 引擎在虚拟机里的运行证据。顺手再执行free -h可以直观看到这个虚拟机吃掉了多少内存。这一步能让很多人瞬间明白Docker Desktop 占内存不是某个容器镜像在作怪而是虚拟机在运行整个引擎。3.3 查看 builder-jammy-base 的详细信息然后从其他终端切回来在 Windows 的 PowerShell 里执行docker images | findstr builder或者docker image inspect builder-jammy-base:latest在 inspect 输出里重点看Architecture和Os字段基本是amd64和linux。再看RepoDigests或者Labels能发现它和 Docker 的构建工具链存在关联。这时候你再对比docker version里显示的Operating System字段会看到引擎运行在Docker Desktop之上内核版本来自 Linux。这就直观地把两件事联系在了一起镜像本身是 Linux 镜像它运行在 Linux 虚拟机里而你在 Windows 上看到的只是它的一个管理入口。3.4 实测容器运行在哪里再做一个直观实验。执行docker run -it --rm alpine sh进去后执行cat /proc/version会看到 Linux 内核版本信息这个内核版本号和你在wsl -d docker-desktop里执行uname -r看到的一致。这能证明容器确实跑在docker-desktop虚拟机里也顺带证明了镜像和虚拟机的关系。如果这时候你好奇builder-jammy-base是否也能这样跑也可以用docker run -it --rm builder-jammy-base:latest /bin/sh试一下。通常它也能启动但它没有像 alpine 那样轻量的 shell 优化启动速度和交互体验都不如 alpine 顺手。3.5 查看 Docker Desktop 设置对两者的影响打开 Docker Desktop 的 Settings → Resources里面有 CPU、内存、Swap 限制选项。我建议你把内存设置到一个合理的值比如 4GB 或 6GB。这里的限制直接影响的是docker-desktop这个虚拟机能分配到的系统资源。你调高内存虚拟机的free -h显示的总内存会增加能容纳的容器数量也会增加。而builder-jammy-base镜像的大小和使用并不会因为在这里调高参数而变化它只受构建配置影响。还有一个隐藏很深的知识点Docker Desktop 的资源限制并不能无限调高。Windows 本身也要吃内存盲目调高会造成整个系统卡顿。我一般会看任务管理器里剩余内存留出至少 4GB 给 Windows 自己用。4. 这两个概念混淆后容易踩的坑4.1 报错 Virtualization support not detected很多人在启动 Docker Desktop 的时候遇到Virtualization support not detected这个报错和builder-jammy-base没有任何关系问题出在docker-desktop虚拟机的运行前提没有被满足。虚拟化支持需要 CPU 开启 VT-x/AMD-V 且 Windows 的 Hyper-V 相关功能可用。排查步骤分三步打开任务管理器 → 性能 → CPU确认“虚拟化”一栏显示“已启用”。如果显示禁用需要进 BIOS 开启 Intel VT-x 或 AMD-V 开关。确认 Windows 功能里的“适用于 Linux 的 Windows 子系统”和“虚拟机平台”已经勾选。我遇到过一个有意思的情况虚拟化明明已经开启但 Docker Desktop 依然报这个错。最后发现是电脑上还装着一款安卓模拟器它占用了虚拟化资源导致 WSL2 无法正常初始化。关掉模拟器再启动 Docker Desktop一切恢复正常。4.2 连接不上 npipe:////./pipe/dockerDesktopLinuxEngine这个经典报错文案是failed to connect to the docker api at npipe:////./pipe/dockerDesktopLinuxEngine凡是看到这句话基本可以断定docker-desktop虚拟机里的 daemon 没起来或者 WSL 发行版卡死了。此时哪怕builder-jammy-base镜像还在磁盘上也无法被任何构建过程使用。解决思路不是去删镜像而是要“重启引擎”右键点击任务栏的 Docker Desktop 图标选择 Quit Docker Desktop。打开 PowerShell执行wsl --shutdown强制回收所有 WSL 虚拟内存和发行版状态。重新启动 Docker Desktop等系统托盘图标不再转圈、变成稳定的状态后再执行docker version。这个操作能解决大部分“管道不通”的问题。我建议遇到类似问题先执行wsl --shutdown再启动 Docker Desktop比直接重启软件更彻底。4.3 构建时卡在拉取 builder-jammy-base 这一步有时候在公司网络环境或者代理环境下执行构建命令时会卡住日志显示一直在 pullbuilder-jammy-base。这通常是网络问题或者镜像源配置不当。我当时的处理方案是给 Docker Desktop 配置镜像加速器或者设置代理规则。不过这里要提醒一句对于开发机我个人不太建议在构建流程里依赖一个未知来源的代理配置更推荐检查 DNS 和基础网络连通性。builder-jammy-base本身是构建需要的环境拉取失败会直接导致构建中断。如果只是本地缓存被清理导致重新拉取可以执行docker pull builder-jammy-base:latest手动提前把基础镜像拉到本地这样后续构建过程会顺滑很多。4.4 清理磁盘后容器全部异常有一次我用 Docker Desktop 自带的 Debug → Clean / Purge data 清理数据结果磁盘确实腾出了空间但所有镜像和容器都被清空builder-jammy-base自然也没了。重新构建时它又开始重新拉取。这里要特别提醒Docker Desktop 里的 Clean / Purge data 不等于“只清临时文件”它是彻底删除虚拟磁盘里的 Docker 数据包括所有镜像、容器、卷。如果你拿这个功能当“清理垃圾”用后果会很酸爽。正确的清理操作是执行docker system prune -a这个命令会移除未使用的镜像、容器和构建缓存但保留运行中的容器和数据卷。5. 一张速查表帮你快速定位问题为了更直观我把两者的核心维度做成了对照表方便你以后遇到问题快速定位到底该看哪个层面对比维度docker-desktop 虚拟机builder-jammy-base 镜像本质WSL2 发行版轻量 Linux 虚拟机基础镜像基于 Ubuntu 22.04是否常驻是Docker Desktop 启动即运行否构建时按需拉取角色定位运行 Docker 引擎的宿主环境提供构建阶段的基础工具链资源占用内存为主CPU 不定磁盘空间为主能否直接进入可以wsl -d docker-desktop可以但需docker run创建容器删除会影响什么导致 Docker Desktop 整体失效只会影响构建流程可重新拉取启动失败表现Docker 命令全部连不上构建过程拉取失败典型排障方式检查 WSL、虚拟化、硬件资源检查网络、镜像源、缓存我个人的排查习惯是先看wsl -l -v确认虚拟机的状态再执行docker version确认引擎通不通最后才去看镜像列表和构建日志。这个顺序能帮你快速分清问题出在“宿主虚拟机”还是“镜像构建”层面。还有一个小技巧如果你不确定某个镜像能不能删可以先用docker image ls -a --format {{.ID}}\t{{.Repository}}:{{.Tag}}\t{{.Size}}看出镜像大小和标签再去docker history看它的构建来源。builder-jammy-base这种带builder前缀的镜像我建议留着毕竟删了下次构建还得重新拉纯属给自己找麻烦。我在实际使用中最大的感受是搞懂 docker-desktop 和 builder-jammy-base 的区别不只是为了满足好奇心更是为了排障时能找到正确的方向。很多时候你以为自己在“容器”层面排查实际上问题出在“虚拟机”层面你以为自己要在docker-desktop虚拟机里改配置实际上应该去改的是某个镜像的构建参数。把这两个概念在脑袋里分开Windows 上玩 Docker 的体验会顺畅一大截。
返回列表