ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Windows上用wslc跑Linux容器:安装、镜像构建与排障复盘

Windows上用wslc跑Linux容器:安装、镜像构建与排障复盘 在 Windows 上跑 Linux 容器这件事我前前后后换过四套方案。最早是装个完整虚拟机开机三分钟内存先吃掉一半后来用桌面版容器工具图形界面点着舒服但一旦要和命令行脚本、流水线对齐就总隔着一层说不清的封装再后来是在 WSL 里手动装容器引擎能跑但每次换机器都要重来一遍那套拳法。wslcWSL Containers出现之后这套流程被压缩成了一个命令的事——容器直接跑在 WSL 内核之上不需要额外开虚拟机也不需要一套独立的后台服务常驻。这篇是我把 wslc 从零装到日常使用、再踩了几个坑之后的完整复盘包含安装顺序、命令链路、镜像构建、路径映射陷阱和排障思路。适合两类人看一是在 Windows 上做 Linux 侧开发、被环境折腾过的二是已经装上了 wslc但卡在挂载、端口或者构建失败上出不来的。命令细节我会给出具体写法同时提醒哪些地方会随预览版本变化——这一点很重要别把某一版的命令当成永久契约。1. wslc 的定位它和虚拟机方案、桌面容器工具的分界线在哪1.1 三层隔离模型进程级、发行版级、容器级要理解 wslc 为什么轻得先把隔离这件事拆成三层看。最外面一层是虚拟机它模拟整套硬件有自己的内核隔离最彻底代价是启动慢、内存占用固定且偏高中间一层是 WSL 里的 Linux 发行版实例它共享宿主内核的部分能力但有自己的文件系统、用户体系和软件包管理本质是一个轻量虚拟机加系统调用翻译最里面一层就是容器它只做命名空间和资源限制进程直接跑在同一个内核上没有独立的引导过程。wslc 的位置很有意思它把容器这一层直接架在了 WSL 的发行版实例里面。也就是说你不需要先开一个虚拟机再在虚拟机里装容器引擎再在引擎里跑容器——这三层被压成了两层。实际感受是wslc run一个基础镜像从敲下回车到出现 shell 提示符通常在两秒以内而同样的事情在完整虚拟机方案里要二十秒起步。这个压缩带来的直接好处是资源账好算了。你不需要为虚拟机本身预留一份固定内存容器不用的时候它就是个静止的进程集合不占 CPU。但代价也要说清楚既然容器共享的是 WSL 实例的内核那么内核参数、内核模块、某些需要特权的操作就会受限于这个实例的配置而不是像独立虚拟机那样随便折腾。我在做网络抓包相关实验的时候就撞到过这个边界后来只能在实例层面调整容器内部改不动。理解这三层之后很多为什么这个功能在别处能用、在这里不行的疑问就有答案了不是工具坏了是它站在了不同的隔离层级上。1.2 与桌面版容器工具的实际差异对照很多人第一反应是我桌面上的容器工具不是挺好用吗为什么要换。这个问题问得对我一开始也这么想。差异不在功能多少而在链路上多了什么、少了什么。我把自己实际用下来的对比整理成了一张表都是日常会碰到的场景对比维度桌面版容器工具wslc后台常驻服务需要独立服务进程开机自启依附 WSL 实例无常驻守护进程首次启动耗时数十秒冷启动更久通常 1~3 秒与 Linux 侧文件系统交互跨文件系统边界大量小文件读写明显变慢容器与实例同一文件系统接近原生命令行一致性命令可用但部分行为经过封装转换命令语义贴近 Linux 原生图形化管理有完整界面以命令行和配置文件为主资源占用固定预留内存不易按需回收按需分配空闲时占用低与脚本、流水线对齐需要额外适配层脚本可直接复用这张表里最值得说的是第三行和第五行。跨文件系统这件事表面上看只是慢一点实际影响的是整个开发循环的体感。我曾经在一个包含几万个依赖文件的前端项目上做过对比同样的安装依赖步骤跨边界方案要六分多钟同文件系统内不到一分半。这种差距不是优化能补的是架构决定的。反过来说图形界面这一项确实是短板。如果你的工作流高度依赖点选、看面板、拖拽管理镜像那 wslc 会让你不适应。但对大多数把命令写进脚本、把步骤写进文档的人来说命令行反而是优势——可复制、可版本化、可审查。1.3 适合迁移与不适合迁移的项目类型不是所有项目都值得迁。我的判断标准很简单看这个项目里容器是主角还是配角。如果容器是主角——比如你在做微服务拆分、需要本地起三四个服务互相调用、需要精确控制运行时依赖版本——那 wslc 很合适。它启动快意味着你可以频繁销毁重建把环境不一致这个老问题从根上掐掉。我现在做联调习惯是每次拉最新代码后直接把旧容器删掉重起成本几乎为零这在小规模项目里是很奢侈的体验。如果容器是配角——比如你只是偶尔需要一个特定版本的解释器跑一下脚本——那我建议你直接用 WSL 发行版实例里装的解释器别上容器。多一层封装就多一层解释成本出了问题还要判断是容器的问题还是实例的问题。还有一类要格外谨慎需要内核级特性的场景比如自定义网络栈、需要加载特定内核模块、需要完整 systemd 行为的。这些在共享内核模型下都有边界不是不能做是要额外折腾投入产出比不划算。我一般遇到这类需求就直接退回虚拟机别硬扛。2. 装之前先把环境账算清楚功能启用顺序与版本核对2.1 硬件与系统版本的门槛确认安装失败最常见的原因不是命令敲错了是前置条件没满足。动手之前有两件事必须先确认。第一件是硬件虚拟化。这一项在任务管理器的性能页里能看到标着虚拟化已启用就对了。如果显示已禁用得进固件设置里打开。这一步我吃过亏——有台机器装完一切正常唯独容器启动后立刻退出日志还是空的排查了两个小时才发现是虚拟化没开。因为部分功能在虚拟化关闭时仍然能装、能跑命令只是容器一启动就死报错还特别隐晦。第二件是系统版本。WSL 的容器能力是跟着 WSL 版本走的不是跟着系统大版本走的。你得先确认当前的 WSL 版本足够新用这条命令看wsl --version输出里会列出 WSL 版本、内核版本、以及 WSLg 之类的组件版本。如果这条命令直接报无法识别说明你的环境还停留在靠系统组件提供 WSL 的旧形态需要先升级到基于应用包分发的新形态再谈容器能力。这个升级动作本身很轻通常一条命令加一次重启但顺序不能反——先升 WSL再装 wslc。我建议把版本号记下来写在项目文档的环境要求里。原因是 wslc 目前还在快速迭代不同版本之间命令名、参数名、默认行为都可能变。我在两个不同版本的机器上执行同一条命令输出格式就不一样。把版本钉住出问题时才有对照基准。2.2 可选功能启用的先后顺序与重启节奏Windows 的可选功能有依赖关系顺序错了会出现启用成功但实际不生效的假象。我总结的顺序是先启用虚拟机平台相关功能再启用子系统相关功能最后确认默认版本指向。具体操作用管理员权限打开终端# 第一步启用虚拟机平台能力这是容器运行的基础 dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart # 第二步启用 Linux 子系统能力 dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart # 第三步统一重启不要中途重启 shutdown /r /t 0我特意把两步写在一起、最后统一重启是因为分两次重启很浪费时间而且第二步在某些系统上会提示需要重启才能继续容易让人误以为第一步失败了。重启之后把默认版本设为 2wsl --set-default-version 2这一步的意义在于容器能力依赖的是 WSL 2 的轻量虚拟化架构版本 1 是不行的。如果你之前装过旧版发行版它们可能还停留在版本 1需要单独转换wsl --list --verbose wsl --set-version 发行版名称 2转换过程会重建文件系统耗时取决于里面有多少文件。我有次在一个塞了几十 G 依赖的实例上做转换等了将近十分钟中途一度以为卡死了。实际上它在正常干活别中断。2.3 安装本体与首次初始化前置条件齐了安装本体本身反而最简单。按应用包分发的形态可以直接用包管理工具装winget install --id Microsoft.WSL -e装完再用wsl --version确认一遍版本号应该比之前新。如果你所在的环境不方便联网也可以下载离线包手动安装思路一样注意包的架构要和系统匹配多数机器是 x64部分轻薄本可能是 ARM 架构装错了会提示不兼容。wslc 的命令行入口通常在 WSL 升级后一并提供可以在 WSL 实例里直接调用wslc --help如果这条命令提示找不到有两种可能一是 WSL 版本还不够新二是不在 WSL 实例里执行。注意wslc 的命令要在 WSL 实例内部执行而不是在 Windows 侧的 PowerShell 里执行。这一点和很多人习惯的在 PowerShell 里敲 wsl 加参数不同容易混淆。我自己的习惯是先wsl进实例再在实例里操作路径清晰。首次运行会做一次初始化检查运行环境、准备存储目录、注册默认网络配置。这个过程通常几秒钟屏幕上会打印一些检查项。我建议把这段输出完整看一遍它列出的每一项都是后面排障的线索。有一次我跳过没看后面遇到网络不通回头才发现初始化时就已经提示某组件未就绪。2.4 三步验证法判断装上了和能用了装完不等于能用。我用一套三步验证法逐层排除问题第一步验证命令行入口。执行wslc version或wslc --version能打印出版本信息说明二进制在、路径对。第二步验证运行能力。拉一个最小的基础镜像并跑一条命令wslc pull alpine:latest wslc run --rm alpine:latest echo container ok看到输出container ok就说明镜像拉取、容器创建、进程执行这条链路通了。这一步失败问题通常出在镜像拉取或者存储权限上。第三步验证网络与文件系统。跑一个带端口映射的服务同时挂一个目录进去wslc run --rm -d --name probe -p 8080:80 -v /tmp/probe:/usr/share/nginx/html nginx:alpine curl -s http://localhost:8080如果 curl 能拿到页面内容说明端口映射和挂载都正常。三步都过环境就算真正可用了。这套验证我建议存成一个脚本换机器、升级版本之后都跑一遍比凭感觉判断靠谱得多。3. 第一个容器跑通从拉镜像到端口映射的完整链路3.1 镜像从哪来、存在哪镜像的来源和存放位置这两件事看起来是细节实际决定了很多为什么磁盘好像不够用了的困惑。来源默认是公共镜像仓库。wslc pull会按名称去拉取格式是仓库地址/命名空间/镜像名:标签。标签不写默认取latest而latest这个东西在生产里是灾难——你今天拉的latest和上周拉的latest可能完全是两份不同的东西。我的做法是始终显式写版本标签哪怕写个alpine:3.20这种也比latest强。存放位置上镜像和解压后的层都落在 WSL 实例的虚拟磁盘文件里不是散落在 Windows 的某个目录。这个设计带来两个后果一是你在 Windows 资源管理器里看不到镜像文件别去那儿找二是磁盘占用会整体体现在那个虚拟磁盘文件的大小上而虚拟磁盘文件有个特点——只增不减。删掉镜像占用空间不一定立刻还给系统需要额外做一次压缩。查看当前有哪些镜像、占了多少wslc images wslc system dfimages列的是镜像清单system df给的是汇总账包括镜像、容器、构建缓存各占多少。我第一次跑df的时候被构建缓存那一栏惊到了——缓存比镜像本身还大。后面专门讲清理。3.2 运行、进入、退出的正确姿势跑容器有两种典型用法一种是执行一次性命令一种是进交互式 shell。前者用wslc run --rm alpine:latest ls /etc--rm的意思是容器退出后自动删除不留垃圾。这个参数在跑一次性命令时几乎必加否则你会发现wslc ps -a里堆了几十个已退出的容器。后者是进 shellwslc run --rm -it alpine:latest /bin/sh-i保持标准输入打开-t分配一个伪终端。这两个参数少一个都会出问题只加-i你在 shell 里看不到提示符输入也没回显只加-t某些交互程序会立刻退出。我一开始图省事只加了-it里的一个折腾半天以为是镜像坏了。进出容器还有一条更省事的路径就是对已经跑起来的容器执行命令不必新开wslc exec -it 容器名 /bin/sh退出交互式 shell 用exit或者 CtrlD。这里有个容易忽略的点如果你是用wslc run -it起的容器并且没加--rm退出后容器处于停止状态想再进去要wslc start再exec。而加了--rm的容器退出即消失数据也不留。取舍看你是在调试还是在跑服务。3.3 端口映射与宿主机访问路径端口映射的写法是-p 宿主端口:容器端口。这里有个认知需要纠正映射之后你在 Windows 侧的浏览器里访问localhost:宿主端口是能通的不需要知道 WSL 实例的 IP。这是 WSL 网络特性带来的便利很多人不知道还在费劲查实例 IP。但如果你的服务又需要被局域网里其他机器访问情况就复杂了。默认情况下映射出来的端口只在本机回环地址上监听局域网访问不到。这需要在实例层面调整网络模式属于进阶配置我一般不轻易动因为改了之后本机的访问路径也可能跟着变等于拆东墙补西墙。多端口映射就重复写-pwslc run --rm -d --name svc \ -p 8080:80 \ -p 8443:443 \ nginx:alpine容器端口那侧必须是容器内实际监听的端口写错了不会报错只会一直连不上。我遇到过一次服务配置里监听的是 8080我映射的是 80查了半小时网络配置最后发现是端口对不上。现在的习惯是起完容器先wslc logs看一眼启动日志确认服务真正监听在哪个端口再决定映射。3.4 挂载Windows 路径与 Linux 路径的映射陷阱挂载是最容易出问题的地方没有之一。核心矛盾在于容器的视角是 Linux 文件系统而你手上的代码在 Windows 盘上中间隔着一层路径翻译。先说路径写法。在 WSL 实例里Windows 的 C 盘被挂在/mnt/c所以你写挂载源要用这个形式wslc run --rm -it -v /mnt/c/Users/me/project:/work alpine:latest /bin/sh看起来简单但坑在权限上。通过/mnt/c挂进去的文件容器里看到的属主和权限是由挂载层决定的不是原文件的真实属性。结果就是容器里的非 root 用户读不了文件或者写出来的文件在 Windows 侧显示权限异常。我遇到过几次构建过程报权限被拒绝最后定位到都是这个原因。绕开的方法有两个。一是在容器里用 root 跑简单粗暴但会带来产物权限问题二是把项目代码放到 WSL 实例自己的文件系统里比如/home/用户名/project从这里挂载进去权限语义就正常了。我现在统一用第二种虽然要多一步复制但省下的排障时间远超那点复制成本。还有一个隐蔽的陷阱是路径大小写。Windows 文件系统不区分大小写Linux 区分。你的代码里写了import Config文件实际叫config.js在 Windows 上跑得好好的一进容器就报找不到模块。这类问题在挂载/mnt/c时尤其容易冒出来因为挂载层会尽量兼容但容器内的应用未必买账。构建上下文同理后面还会提到。4. 自建镜像构建上下文、缓存层与报错对照4.1 构建上下文与大小写敏感的坑构建镜像时wslc build会把指定的目录作为上下文打包送进构建过程。这里第一个决策点是上下文给多大。给整个项目根目录是最常见的做法但如果根目录下有node_modules、.git、构建产物这类巨型目录打包和传输会非常慢。解决办法是写一个忽略文件把不需要的路径排掉# .dockerignore node_modules .git dist *.log这份忽略文件带来的提速是数量级的。我在一个中等规模项目上做过对比加了忽略文件后构建启动时间从四十多秒降到三秒。原因很简单上下文打包是同步操作文件越多越慢而且这些文件根本不会在构建里用到。第二个决策点是路径大小写。构建过程中的路径解析遵循 Linux 规则严格区分大小写。如果你的COPY指令写的是COPY ./Src ./app而实际目录叫src构建会直接失败并报找不到文件。这在从 Windows 迁移过来的项目里极其常见因为本地开发根本感知不到这个问题。我的处理办法是在构建前跑一遍文件名清单和 Dockerfile 里的指令逐条比对。听起来笨但比反复构建试错快。4.2 多阶段构建与层缓存复用多阶段构建是控制镜像体积最有效的手段逻辑是把编译和运行拆成两个阶段只把编译产物带进最终镜像。# 阶段一构建 FROM node:20-alpine AS builder WORKDIR /src COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # 阶段二运行 FROM node:20-alpine WORKDIR /app COPY --frombuilder /src/dist ./dist COPY --frombuilder /src/node_modules ./node_modules EXPOSE 3000 CMD [node, dist/main.js]这样写的好处是最终镜像里不含源码、不含编译工具链体积能小一半以上。我做过一个对照单阶段镜像 1.1G多阶段降到 420M。层缓存的复用规则要理解清楚每条指令生成一层某层失效它之后的所有层都要重建。所以指令顺序很关键——变化频率低的东西放前面变化频率高的放后面。上面的例子里先COPY package*.json再npm ci最后才COPY . .就是为了让依赖安装这一层在源码变动时仍然命中缓存。如果顺序反过来每次改一行代码都要重装一遍依赖构建时间从十几秒变成几分钟。这里有个实操细节npm ci比npm install更适合构建场景因为它严格按锁文件安装结果可复现而且不会因为版本范围匹配到新版本。这一点在流水线上尤其重要我遇到过因为依赖小版本升级导致构建产物行为变化的事故换成ci之后这类问题基本消失。4.3 构建失败报错对照表构建报错的信息量往往不大得靠经验对照。我把常遇到的几类整理成表报错关键词大概率原因处理方向failed to compute cache key/not foundCOPY 源路径写错或大小写不匹配核对上下文内实际路径与大小写permission denied挂载目录权限语义异常或容器内用户无权限改用实例内路径作为上下文或调整运行用户no space left on device虚拟磁盘空间耗尽或构建缓存堆积清理缓存与悬空镜像必要时压缩磁盘exec format error镜像架构与当前平台不匹配确认拉取的镜像架构标签network timeout/connection reset拉取基础镜像或依赖时网络中断改用离线导入或重试并延长超时exit code: 137进程被强制终止通常是内存不足提高实例内存上限或优化构建内存占用表里最容易被误判的是exit code: 137。很多人第一反应是命令写错了实际上是内存超限被杀。构建大型前端项目时尤其常见因为打包过程会吃很多内存。我现在的做法是给实例分配足够内存同时在构建命令里限制并发用时间换空间。exec format error也值得单独说。如果你在 ARM 架构的机器上拉了一个只为 x86 构建的镜像就会撞到这个错。报错信息不会告诉你架构不匹配只会说格式错误很容易往别处想。确认方法是在拉取时显式指定架构标签或者查一下镜像支持的平台列表。5. 排障实录五个报错从现象追到根因5.1 容器启动即退出日志一片空白现象wslc run -d之后wslc ps里看不到容器wslc ps -a能看到状态是Exited (0)wslc logs什么都没输出。这条链路我是这么走的。第一步确认容器是不是真的执行了命令。用wslc inspect看容器的配置重点看Cmd和Entrypoint字段。有次发现镜像里定义的入口脚本路径不对容器启动后找不到命令直接以 0 退出日志自然是空的。第二步如果命令没问题就换成前台模式跑把输出直接打到终端wslc run --rm -it 镜像 /bin/sh能进 shell 说明镜像本身没坏问题在启动命令上。这时候手动执行一遍原来的入口命令报错就出来了。第三步如果连 shell 都进不去那就是镜像或者运行时的问题。检查wslc images里镜像大小是否异常偏小——偏小通常意味着拉取中断层不完整。删掉重新拉一次。我在这个问题上最深刻的一次教训是日志空白不等于没有错误很多时候是错误发生在日志系统就绪之前。这时候inspect和前台运行比logs有用得多。5.2 端口被占用却找不到进程现象启动容器报port is already allocated但用netstat查那个端口什么也没查到。根因通常有两层。第一层是停止状态的容器仍然占着端口记录。wslc ps -a会列出所有容器包括已经退出的那些如果某个已退出的容器曾经映射过这个端口记录可能还在。处理办法是把它彻底删掉wslc rm -f 容器名第二层是实例内的其他进程占了端口但你在 Windows 侧的 netstat 里看不到因为那是实例内部的网络命名空间。查这个要在实例里执行ss -lntp | grep 8080我有一次就是卡在第二层在 Windows 侧查了半天没结果进实例一查是个之前遗留的服务进程还挂着。杀掉之后立刻正常。顺着这个思路还能推出一条经验端口冲突类问题永远先在容器和实例这两个层面查别一上来就怀疑系统。跨层的进程视图不互通是这类问题的最大迷惑源。5.3 挂载后文件权限被改写现象容器内向挂载目录写文件写出来的文件在 Windows 侧打开提示权限异常或者容器内的服务进程报无权写入。前面提过根因在挂载层的权限映射。这里补充具体的定位方法。先在容器内看文件的实际属主ls -ln /work如果显示的数字 UID 和容器内运行用户的 UID 对不上就是这个原因。解决办法分两种场景一种是开发调试图省事直接在运行命令里指定用户wslc run --rm -it --user $(id -u):$(id -g) -v /home/me/project:/work alpine:latest /bin/sh这样容器内进程的 UID 和挂载源属主一致读写就不会冲突。另一种是构建产物场景需要产物在 Windows 侧能正常使用。这时候更稳的做法是把构建过程放在实例内的路径下完成最后再复制到 Windows 盘而不是直接往/mnt/c下写。多一步复制省掉一堆权限纠纷。5.4 磁盘占用暴涨现象用了一阵子虚拟磁盘文件涨到几十 G删了镜像也没见变小。这里要理解虚拟磁盘的分配机制它是按需增长的增长后不会自动收缩。删文件只是把块标记为空闲文件本身的大小不变。所以要分两步处理。第一步清掉容器侧的无用数据wslc system prune -a --volumes这条命令会删除所有停止的容器、未被引用的镜像、构建缓存和未使用的数据卷。执行前务必确认没有还需要的东西——它不给撤销机会。我第一次跑的时候手快把一个还在调试的容器删了只能重来。第二步如果文件仍然很大做一次磁盘压缩。先关闭所有实例再用系统工具压缩虚拟磁盘文件。这一步耗时较长取决于磁盘大小我一般放在下班前跑。日常预防更有效定期跑wslc system df看账构建缓存那一栏超过几 G 就清一次。养成这个习惯之后我的磁盘再没暴涨过。5.5 镜像拉取超时的离线解法现象wslc pull卡住或者超时重试几次都不行。网络链路的排查我这里不多展开重点说一条更可靠的替代路径离线导入。思路是在能正常访问的环境里把镜像导出成文件再拷到目标机器导入。# 在可用环境导出 wslc pull nginx:alpine wslc save -o nginx-alpine.tar nginx:alpine # 在目标环境导入 wslc load -i nginx-alpine.tar这条路径的好处是完全不依赖构建时的网络适合内网环境、演示现场这类网络不确定的场景。代价是文件体积大传输要花时间。我现在的习惯是给常用基础镜像准备一份离线包放在本地目录里新机器上手先导入再慢慢拉其他东西。导出的时候注意别把一堆无关镜像打进去save是按镜像逐个导的多写几个镜像名会打成一个包体积翻倍。6. 长期用下去资源边界、清理节奏与工作流融合6.1 内存和 CPU 的分配边界WSL 实例默认会按需吃内存理论上限可以到宿主内存的一多半。这在跑容器时会出问题构建一个大项目把内存吃满宿主开始卡顿甚至触发系统级别的内存回收构建进程被杀报一个毫无信息量的退出码。控制办法是写一个配置文件给实例设上限。配置文件放在用户目录下内容大致是[wsl2] memory8GB processors4 swap2GB数字按机器实际情况定。我的一般原则是给实例分配宿主内存的一半处理器核数不超过物理核数减二留出余量给宿主侧。这样既够容器跑又不至于把机器拖死。改完配置要重启实例才生效wsl --shutdown这条命令会关闭所有实例包括正在跑容器的那些执行前记得保存工作。另一个容易被忽略的点是交换空间。设了 swap 之后内存压力大时不会立刻杀进程而是换到磁盘。代价是变慢。我在构建场景下会关掉 swap让内存不足直接暴露出来比默默变慢好排查。6.2 清理节奏镜像、容器、构建缓存清理这件事与其等磁盘告警再动手不如定个节奏。我的做法是分三档日常档每次调试结束跑一次轻量清理删掉退出状态的容器wslc container prune -f周档清一次构建缓存和悬空镜像wslc image prune -f wslc builder prune -f月档做一次全面盘点和磁盘压缩。先看账wslc system df然后按需清理最后压缩虚拟磁盘文件。这里有个经验不要用删了再说的心态清理。每次清理前先wslc images看一眼清单确认没有正在依赖的镜像是悬空状态——有些镜像虽然当前没有容器引用但你可能下周还要用删了还得重新拉。我吃过一次亏清理完第二天要演示结果镜像没了现场等了两分钟拉取非常尴尬。现在我给常用镜像打上明确标签清理时按标签排除。6.3 与编辑器、脚本、流水线的衔接工具装好只是开始真正提升效率的是把它嵌进日常流程。编辑器侧主流编辑器都有连接 WSL 实例的能力连上之后终端、文件浏览、调试都在实例内进行容器操作可以直接在集成终端里敲。这样省掉了来回切窗口的动作也避免了路径写错。脚本侧我把高频命令收进一个入口脚本参数化处理。比如一个dev.sh接up、down、logs、rebuild四个子命令内部封装对应的wslc调用。好处是团队里每个人敲的命令一样不会出现你这台机器上是这么跑的这种分歧。#!/usr/bin/env bash set -euo pipefail case ${1:-} in up) wslc run -d --name app -p 3000:3000 -v $PWD:/app app:dev ;; down) wslc rm -f app ;; logs) wslc logs -f app ;; rebuild) wslc build -t app:dev . ;; *) echo usage: $0 {up|down|logs|rebuild} exit 1 ;; esacset -euo pipefail这行别省它能让脚本在任一步失败时立刻停下而不是带着错误状态继续往下跑。我早期写的脚本没加这行出现过构建失败但容器还是启动了旧镜像的假成功排查起来很费劲。流水线侧关键在于本地和远端的构建方式保持一致。既然本地用 wslc 构建那构建文件本身就得是标准格式不要掺入本地特有的路径或参数。这一点做到了本地能过的构建换到别的环境大概率也能过。6.4 升级与回滚的注意点wslc 还在演进升级是常态。升级前有两件事要做一是记下当前版本号二是确认关键镜像和数据卷有备份或者能重建。版本号记录很简单wslc version把它写进项目文档的环境说明里。出问题时这个数字是你判断是不是版本变化导致的的第一依据。数据方面容器本身是无状态的删了能重建真正要保的是数据卷和自定义镜像。数据卷可以导出成归档文件自定义镜像可以用save导成 tar 包。我一般在下一次大版本升级前做一次这两个动作成本几分钟换来的是可以随时回退。升级之后别急着干活先跑一遍第 2.4 节那套三步验证。我遇到过一次升级后端口映射行为变化验证时发现了没影响到正式使用。如果不验证直接上很可能在关键时刻才发现问题。回滚的路径要提前想好。如果升级后出现无法绕过的问题卸载新版、装回旧版、重新导入镜像和数据这条链路能不能走通最好在不出问题的时候演练一次。听起来麻烦但真出事的时候手上有演练过的步骤和现场现编步骤是完全两种体验。最后分享一个我自己养成的小习惯每次环境有较大变动升级、改配置、换机器就在项目文档里加一行变更记录写上日期、做了什么、验证结果。几个月后回头看这些记录能帮你快速定位这个环境是从什么时候开始不一样的。这个东西不花时间但价值很高。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表