缓存导出导入是什么
BuildKit 的构建缓存默认只保存在本机构建器里,换一台机器就全部作废。缓存导出导入把缓存写成外部形式(最常用的是推送到镜像仓库的一个专用标签),下次构建先拉回来再增量构建,让 CI 流水线的首次构建也能命中历史缓存。它解决的是跨机器、跨流水线的缓存复用问题,配合 buildx 与容器驱动构建器使用。
基本信息
| 导出语法 | --cache-to type=registry,ref=仓库/缓存标签,mode=max |
|---|---|
| 导入语法 | --cache-from type=registry,ref=仓库/缓存标签 |
| mode 取值 | min 只导出最终层相关、max 导出全部中间层 |
| 本地形式 | type=local,dest=目录 与 type=local,src=目录,适合单机接力 |
| 前置条件 | docker-container 驱动构建器;导入方需对缓存标签有拉取权限 |
| 作用范围 | 缓存内容寻址,命中的是内容相同的步骤 |
典型使用场景
- CI 每次用干净的构建节点:靠远端缓存避免全量重装依赖
- 多台构建机共享一份缓存,缩短整体流水线时间
- 排查缓存失效原因:对比导入前后的 CACHED 行数量
- 发布镜像与缓存标签分开命名,避免缓存层被当作正式产物拉取
- 单机接力:本地开发与集成环境之间用目录形式传递缓存
远端缓存示例
远端缓存示例
# 先建容器驱动构建器(缓存导出导入依赖它)
docker buildx create --name multiarch --driver docker-container --use
# 一次构建:先拉缓存,产出后再把缓存推回仓库
docker buildx build \
--cache-from type=registry,ref=registry.example.com/app/web:buildcache \
--cache-to type=registry,ref=registry.example.com/app/web:buildcache,mode=max \
--push -t registry.example.com/app/web:1.0 .
# 核对缓存是否命中:plain 日志里的 CACHED 行数量
docker buildx build --progress=plain \
--cache-from type=registry,ref=registry.example.com/app/web:buildcache \
-t app/web:1.0 . 2>&1 | grep -c CACHED本地目录形式
本地目录形式
# 导出到本地目录(单机或挂载共享盘时更省流量)
docker buildx build --cache-to type=local,dest=/var/cache/buildkit/app-web -t app/web:1.0 .
# 下次从该目录导入
docker buildx build --cache-from type=local,src=/var/cache/buildkit/app-web -t app/web:1.0 .
# 缓存目录会持续增长,需要纳入清理计划
du -sh /var/cache/buildkit/app-web参数选择
| 参数 | 含义 | 取舍 |
|---|---|---|
| mode=min | 只导出与最终镜像相关的层 | 流量小,中间阶段缓存缺失 |
| mode=max | 导出全部中间层 | 命中率高,仓库流量与存储上升 |
| registry 缓存 | 缓存存进仓库标签 | 跨机器复用方便,需权限 |
| local 缓存 | 缓存存本地目录 | 省流量,但换机器即失效 |
| 不写 cache-to | 不导出缓存 | 只适合单机构建 |
缓存标签与发布标签建议分开命名(如仓库名加 buildcache 后缀),避免有人误把缓存层当作可运行镜像拉取;缓存标签也需要定期清理策略。
缓存按内容寻址:Dockerfile 步骤与输入相同才命中。基础镜像更新、依赖清单变化都会让后续步骤全部失效,这是设计行为而不是配置错误。