Loading... # BuildKit:Docker 的隐藏宝石,可用于构建几乎所有东西 # 一、新闻概述 ## 1. 标题 BuildKit:Docker 的隐藏宝石,可用于构建几乎所有东西 ## 2. 发布时间 2026 年 2 月 25 日 ## 3. 来源 Tuan-Anh Tran 的博客 # 二、核心内容 ## 1. 事件摘要 ### A. 主要内容 这篇文章揭示了 BuildKit 的真实面目——它不仅仅是 Docker 构建的引擎,而是一个通用、可插拔的构建框架。通过使用自定义前端,BuildKit 可以构建 OCI 镜像、tarball、本地目录、APK 包、RPM 包等任何可以用文件系统操作有向无环图描述的产物。 ### B. 核心亮点 - BuildKit 是通用构建框架,不仅限于构建容器镜像 - 采用可编程架构,支持自定义前端 - 支持多种输出类型,包括本地目录和 tarball - 提供内容寻址缓存和并行执行能力 ## 2. 关键信息 ### A. 涉及产品 - BuildKit:Docker 的底层构建引擎 - Dockerfile:BuildKit 的默认前端之一 ### B. 核心概念 - LLB(Low-Level Build definition):BuildKit 的中间表示 - Frontend:将构建定义转换为 LLB 的容器镜像 - Solver:执行 LLB 图并处理缓存的组件 ### C. 相关项目 - Earthly、Dagger、Depot 等项目都基于 BuildKit 的 LLB 构建 ## 3. 背景介绍 ### A. 前置知识 大多数人每天使用 BuildKit 而不自知。当运行 docker build 命令时,BuildKit 就是其背后的引擎。但将 BuildKit 简单地称为"构建 Dockerfile 的工具",就像把 LLVM 称为"编译 C 语言的工具"一样,严重低估了其架构价值。 ### B. 相关上下文 BuildKit 的设计清晰且易于理解,其核心思想是将构建过程抽象为内容寻址的文件系统操作图。这种设计使得任何能够产生有效 LLB 的程序都可以驱动 BuildKit。 # 三、详细报道 ## 1. 主要内容 ### A. 架构设计 BuildKit 的架构分为三个核心概念:LLB、Frontend 和 Solver。 **LLB:中间表示** LLB 是 BuildKit 的核心,类似于 LLVM 的中间表示(IR)。它是一种基于 protobuf 的二进制协议,描述了一个由文件系统操作组成的有向无环图(DAG)。这些操作包括运行命令、复制文件、挂载文件系统等。LLB 是内容寻址的,这意味着相同的操作会产生相同的哈希值,从而实现激进的缓存策略。 当编写 Dockerfile 时,Dockerfile 前端会解析它并生成 LLB。但 BuildKit 并不要求输入必须是 Dockerfile,任何能够生成有效 LLB 的程序都可以驱动 BuildKit。 **Frontend:自定义语法** Frontend 是一个容器镜像,BuildKit 运行它来将构建定义(Dockerfile、YAML、JSON、HCL 等)转换为 LLB。Frontend 通过 BuildKit Gateway API 接收构建上下文和构建文件,然后返回序列化的 LLB 图。 这是关键洞察:构建语言并没有硬编码在 BuildKit 中,它是一个可插拔的层。可以编写一个读取 YAML 规范、TOML 配置或自定义 DSL 的前端,BuildKit 会像执行 Dockerfile 一样执行它。 实际上,这种机制已经广泛应用。Dockerfile 顶部的 # syntax= 指令告诉 BuildKit 使用哪个前端镜像。# syntax=docker/dockerfile:1 只是默认值,可以指向任何镜像。 **Solver 和缓存:内容寻址执行** Solver 接收 LLB 图并执行它。DAG 中的每个顶点都是内容寻址的,如果之前已经用相同的输入构建过特定步骤,BuildKit 会完全跳过它。这就是 BuildKit 快速的原因:它不像旧的 Docker 构建器那样线性地缓存层,而是在整个图的操作级别进行缓存,并且可以并行执行独立的分支。 缓存可以是本地的、内联的(嵌入在镜像中)或远程的(存储在注册表中)。这使得 BuildKit 构建可重现且可在 CI 运行器之间共享。 ```mermaid graph TB subgraph Input[输入层] A[构建定义<br/>Dockerfile/YAML/JSON] end subgraph Frontend[前端层] B[Frontend 容器] A -->|解析| B end subgraph Core[核心层] C[LLB<br/>中间表示] B -->|生成| C D[Solver<br/>执行引擎] C -->|执行| D E[Cache<br/>缓存层] D <-->|读写| E end subgraph Output[输出层] F[type=image<br/>镜像] G[type=local<br/>本地目录] H[type=tar<br/>压缩包] I[type=oci<br/>OCI 镜像] D --> F D --> G D --> H D --> I end ```  ### B. 多样化输出 BuildKit 的 --output 标志使其在非镜像场景下变得实用。可以告诉 BuildKit 将结果导出为: - type=image —— 推送到注册表(docker build 的默认行为) - type=local,dest=./out —— 将最终文件系统转储到本地目录 - type=tar,dest=./out.tar —— 导出为 tarball - type=oci —— 导出为 OCI 镜像 tarball 其中 type=local 输出对于非镜像用例最有价值。构建可以生成编译后的二进制文件、软件包、文档或其他任何内容,BuildKit 会将结果转储到磁盘。不需要容器镜像。 像 Earthly、Dagger 和 Depot 这样的项目都建立在 BuildKit 的 LLB 之上,这是一个经过验证的模式。 ### C. 实战案例:构建 APK 包 为了具体演示这一点,作者构建了 apkbuild:一个自定义的 BuildKit 前端,它读取 YAML 规范并生成 Alpine APK 包。不涉及 Dockerfile。整个构建管道——从源码编译到 APK 打包——都在 BuildKit 内部使用 LLB 操作运行。 作者选择 YAML 是为了熟悉度,但规范可以是任何想要的格式(JSON、TOML、自定义 DSL),只要前端能够解析它。 包 YAML 规范示例如下: ```yaml name: hello version: "1.0.0" epoch: "0" url: https://example.com/hello license: MIT description: Minimal CMake APK demo sources: app: context: {} build: source_dir: hello ``` 就是这样。没有 Dockerfile。BuildKit 通过自定义前端读取这个规范并生成一个 .apk 文件。 **运行方法** 首先构建前端镜像: ```bash docker build -t tuananh/apkbuild -f Dockerfile . ``` 然后使用它来构建 APK 包: ```bash cd example docker buildx build \ -f spec.yml \ --build-arg BUILDKIT_SYNTAX=tuananh/apkbuild \ --output type=local,dest=./out \ . ``` 应该能够在 out 文件夹中看到 APK 包。 BUILDKIT_SYNTAX 告诉 BuildKit 使用自定义前端而不是默认的 Dockerfile 解析器。--output type=local 将生成的 .apk 文件转储到 ./out。不创建镜像,不涉及注册表。 ## 2. 技术细节 ### A. 内容寻址原理 BuildKit 的内容寻址机制是其高性能的核心。每个构建步骤的输入和输出都通过哈希值来标识,而不是通过时间戳或顺序。 ```mermaid graph LR A[输入文件] -->|计算哈希| B[哈希值] B -->|查找缓存| C{缓存命中?} C -->|是| D[使用缓存结果] C -->|否| E[执行构建步骤] E -->|输出结果| F[新缓存条目] F -->|哈希值| G[存储到缓存] ```  ### B. 并行执行能力 由于 LLB 是一个 DAG,BuildKit 可以识别独立的构建分支并并行执行它们。这比传统的线性构建方式显著提升了构建速度。 ## 3. 数据与事实 ### A. 性能优势 - 操作级别的缓存,而非仅仅层级别 - 支持并行执行独立分支 - 跨 CI 运行器的缓存共享 ### B. 可扩展性 - 支持任意输出类型 - 可插拔的前端架构 - 已被多个大型项目采用 # 四、影响分析 ## 1. 行业影响 ### A. 技术趋势 BuildKit 揭示了构建工具的新范式:将执行引擎与构建语言解耦。这种模式使得开发者可以根据自己的需求定义构建语法,同时复用 BuildKit 的成熟执行和缓存机制。 ### B. 生态影响 - Earthly:使用 LLB 作为执行引擎,提供类 Dockerfile 的构建语法 - Dagger:使用 LLB 运行 CI/CD 管道 - Depot:基于 BuildKit 构建的分布式构建服务 ## 2. 用户影响 ### A. 现有用户 Docker 用户已经受益于 BuildKit 的性能改进,但大多数人只使用了默认的 Dockerfile 前端。 ### B. 潜在用户 需要构建非容器产物的开发者可以使用 BuildKit 的自定义前端功能,构建 APK 包、RPM 包或其他任意文件系统产物。 ### C. 工具开发者 构建新工具的开发者可以考虑将 BuildKit 作为执行后端,而无需重新实现缓存、并行执行和可重现性等功能。 ## 3. 技术趋势 ### A. 架构解耦 构建工具的架构正在向"执行引擎 + 前端语言"的模式演进,类似于编译器领域的"后端 + 前端语言"分离。 ### B. 内容寻址 内容寻址作为一种高效缓存和去重机制,正在越来越多的构建系统中被采用。 # 五、各方反应 ## 1. 业内评价 该文章在 Hacker News 上引发了讨论,网友认为 BuildKit 的设计思想很有价值,但文档和示例仍然有限。 ## 2. 社区反馈 - 正面:认可 BuildKit 的架构设计,认为这种可插拔模式值得推广 - 关注点:自定义前端的开发门槛较高,需要更多示例和工具支持 # 六、相关链接 ## 1. 官方资源 - BuildKit GitHub 仓库 - BuildKit 文档 ## 2. 相关项目 - apkbuild:自定义 BuildKit 前端示例 - Earthly:基于 BuildKit 的构建工具 - Dagger:基于 BuildKit 的 CI/CD 平台 - Chainguard melange:Alpine 包构建工具 - Hacker News 讨论 *** ## 参考资料 1. [BuildKit: Docker's Hidden Gem That Can Build Almost Anything - Tuan-Anh Tran](https://tuananh.net/2026/02/25/buildkit-docker-hidden-gem/) 最后修改:2026 年 02 月 27 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏