Skip to content

BuildKit 详解

BuildKit 是 Docker 的下一代构建工具,提供了更快速、更高效、更灵活的镜像构建能力。本文将深入介绍 BuildKit 的架构、特性和使用方法。

目录

  1. BuildKit 架构
  2. 核心特性
  3. LLB(Low Level Builder)
  4. Solver(求解器)
  5. 前端扩展
  6. 高级功能

BuildKit 架构

1.1 整体架构

┌─────────────────────────────────────────────────────────────────────┐
│                         BuildKit 架构                               │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                      Client Layer                            │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │   │
│  │  │   Docker    │  │   buildctl  │  │   Language SDKs     │  │   │
│  │  │    CLI      │  │  (CLI tool) │  │  (Go/Python/Node)   │  │   │
│  │  └──────┬──────┘  └──────┬──────┘  └──────────┬──────────┘  │   │
│  └─────────┼────────────────┼────────────────────┼─────────────┘   │
│            │                │                    │                  │
│            └────────────────┴────────────────────┘                  │
│                         │ gRPC / LLB                                │
│                         ▼                                           │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                     BuildKit Daemon                          │   │
│  │                                                              │   │
│  │  ┌─────────────────────────────────────────────────────┐   │   │
│  │  │                    Frontend Layer                    │   │   │
│  │  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  │   │   │
│  │  │  │  Dockerfile │  │    MLC      │  │   Custom    │  │   │   │
│  │  │  │   Gateway   │  │  Frontend   │  │  Frontends  │  │   │   │
│  │  │  └─────────────┘  └─────────────┘  └─────────────┘  │   │   │
│  │  └─────────────────────────────────────────────────────┘   │   │
│  │                           │ LLB                              │   │
│  │                           ▼                                  │   │
│  │  ┌─────────────────────────────────────────────────────┐   │   │
│  │  │                    Solver Layer                      │   │   │
│  │  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  │   │   │
│  │  │  │    DAG      │  │   Cache     │  │  Parallel   │  │   │   │
│  │  │  │  Builder    │  │   Manager   │  │  Executor   │  │   │   │
│  │  │  └─────────────┘  └─────────────┘  └─────────────┘  │   │   │
│  │  └─────────────────────────────────────────────────────┘   │   │
│  │                           │                                  │   │
│  │                           ▼                                  │   │
│  │  ┌─────────────────────────────────────────────────────┐   │   │
│  │  │                    Worker Layer                      │   │   │
│  │  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  │   │   │
│  │  │  │   OCI       │  │   Snapshot  │  │  Content    │  │   │   │
│  │  │  │  Worker     │  │   Manager   │  │   Store     │  │   │   │
│  │  │  └─────────────┘  └─────────────┘  └─────────────┘  │   │   │
│  │  └─────────────────────────────────────────────────────┘   │   │
│  │                                                              │   │
│  └─────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────┘

1.2 组件说明

组件职责说明
Frontend解析构建定义Dockerfile、Buildpacks 等
Solver执行构建DAG 调度、缓存管理
Worker底层执行快照管理、内容存储
Cache缓存管理本地/远程缓存
Exporter结果导出镜像、目录、OCI 等

核心特性

2.1 并发构建

BuildKit 使用 DAG(有向无环图)分析依赖关系,并行执行独立步骤:

dockerfile
# syntax=docker/dockerfile:1

# 这些步骤可以并行执行
FROM alpine AS stage1
RUN sleep 5 && echo "Stage 1" > /tmp/stage1

FROM alpine AS stage2
RUN sleep 5 && echo "Stage 2" > /tmp/stage2

FROM alpine AS stage3
RUN sleep 5 && echo "Stage 3" > /tmp/stage3

# 最终阶段等待所有并行步骤
FROM alpine AS final
COPY --from=stage1 /tmp/stage1 /tmp/
COPY --from=stage2 /tmp/stage2 /tmp/
COPY --from=stage3 /tmp/stage3 /tmp/

构建时间对比:

构建器执行方式总时间
传统顺序15 秒
BuildKit并行5 秒

2.2 高效缓存

BuildKit 提供多种缓存机制:

dockerfile
# syntax=docker/dockerfile:1

# 1. 内联缓存(存储在镜像中)
FROM node:18-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm \
    npm ci

# 2. 外部缓存挂载
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN --mount=type=cache,target=/root/.cache/pip \
    pip install -r requirements.txt

# 3. 持久缓存
FROM golang:1.21-alpine AS builder
WORKDIR /app
RUN --mount=type=cache,target=/go/pkg/mod \
    go mod download

2.3 安全构建

dockerfile
# syntax=docker/dockerfile:1

# 1. 秘密挂载(不缓存敏感数据)
RUN --mount=type=secret,id=api_key \
    API_KEY=$(cat /run/secrets/api_key) make build

# 2. SSH 代理转发
RUN --mount=type=ssh,id=github \
    go mod download

# 3. 绑定挂载(只读)
RUN --mount=type=bind,source=package.json,target=package.json,readonly \
    npm install

LLB(Low Level Builder)

3.1 LLB 概述

LLB 是 BuildKit 的中间表示格式,定义构建操作的图结构:

protobuf
// LLB 定义示例(protobuf 格式)
message Definition {
  repeated Op def = 1;
  SourceLocation source = 2;
}

message Op {
  oneof op {
    ExecOp exec = 1;
    SourceOp source = 2;
    BuildOp build = 3;
    ...
  }
}

3.2 LLB 图结构

LLB DAG 示例:

        ┌─────────────┐
        │   Source    │
        │ (alpine:latest)
        └──────┬──────┘

       ┌───────┴───────┐
       │               │
       ▼               ▼
┌─────────────┐  ┌─────────────┐
│    Copy     │  │    Copy     │
│ (package.json)│  │   (src/)    │
└──────┬──────┘  └──────┬──────┘
       │               │
       ▼               ▼
┌─────────────┐  ┌─────────────┐
│    Exec     │  │    Exec     │
│ (npm ci)    │  │ (npm build) │
└──────┬──────┘  └──────┬──────┘
       │               │
       └───────┬───────┘


        ┌─────────────┐
        │    Merge    │
        │  (Final Image)
        └─────────────┘

3.3 使用 LLB Go SDK

go
package main

import (
    "context"
    "github.com/moby/buildkit/client/llb"
)

func main() {
    // 定义基础镜像
    base := llb.Image("alpine:latest")
    
    // 添加运行命令
    run := base.Run(llb.Shlex("apk add --no-cache curl"))
    
    // 定义状态
    state := run.Root()
    
    // 导出定义
    def, err := state.Marshal(context.TODO())
    if err != nil {
        panic(err)
    }
    
    // 使用定义进行构建
    // ...
}

Solver(求解器)

4.1 Solver 工作原理

Solver 执行流程:

1. 接收 LLB 定义


2. 构建 DAG
   ├─ 解析操作依赖
   ├─ 识别可并行节点
   └─ 创建执行计划


3. 缓存查询
   ├─ 计算操作缓存键
   ├─ 查询缓存存储
   └─ 标记缓存命中/未命中


4. 执行计划
   ├─ 并行执行独立操作
   ├─ 等待依赖完成
   └─ 存储结果到缓存


5. 导出结果

4.2 缓存键计算

go
// 缓存键计算示例
type CacheKey struct {
    // 操作类型和配置
    Op Op
    
    // 输入摘要
    Inputs []digest.Digest
    
    // 内容摘要(文件内容等)
    Content digest.Digest
}

// 缓存键 = Hash(Op + Inputs + Content)

4.3 进度监控

bash
# 查看详细构建进度
docker buildx build --progress=plain .

# 查看自动进度
docker buildx build --progress=auto .

# 静默模式
docker buildx build --progress=quiet .

# 输出为 JSON
docker buildx build --progress=rawjson . 2>&1

前端扩展

5.1 Dockerfile 前端

Dockerfile 是最常用的 BuildKit 前端:

dockerfile
# syntax=docker/dockerfile:1
# ^ 指定前端版本

FROM alpine
RUN echo "Hello BuildKit"

5.2 自定义前端

dockerfile
# 使用 Buildpacks 前端
# syntax=heroku/buildpacks:18

# 使用 MLC(机器学习容器)前端
# syntax=mlc/mlc:latest

5.3 创建自定义前端

go
// 自定义前端实现
package main

import (
    "context"
    "github.com/moby/buildkit/frontend/gateway/client"
)

func main() {
    // 读取构建配置
    // 生成 LLB 定义
    // 返回结果
}

高级功能

6.1 分布式构建

bash
# 创建远程构建器
docker buildx create \
  --name remote-builder \
  --driver remote \
  tcp://build-server:1234

# 使用远程构建器
docker buildx use remote-builder
docker buildx build -t myapp:latest .

6.2 多阶段优化

dockerfile
# syntax=docker/dockerfile:1

# 使用缓存挂载优化多阶段
FROM node:18-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm,id=npm \
    npm ci

FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN --mount=type=cache,target=/app/.next/cache,id=next \
    npm run build

FROM node:18-alpine AS production
WORKDIR /app
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
CMD ["node", "server.js"]

6.3 条件构建

dockerfile
# syntax=docker/dockerfile:1

ARG TARGETOS
ARG TARGETARCH

FROM --platform=$BUILDPLATFORM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o app

FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/app .
CMD ["./app"]

6.4 构建证明和 SBOM

bash
# 生成 Provenance 证明
docker buildx build \
  --provenance=true \
  -t myapp:latest \
  --push .

# 生成 SBOM
docker buildx build \
  --sbom=true \
  -t myapp:latest \
  --push .

# 查看证明
docker buildx imagetools inspect myapp:latest --format '{{ json .Provenance }}'

# 查看 SBOM
docker buildx imagetools inspect myapp:latest --format '{{ json .SBOM }}'

6.5 构建诊断

bash
# 启用调试模式
docker buildx build --debug .

# 导出构建详情
docker buildx build \
  --metadata-file build-metadata.json \
  -t myapp:latest .

# 查看构建历史
docker buildx du

# 清理构建缓存
docker buildx prune

BuildKit 配置

7.1 守护进程配置

json
{
  "builder": {
    "gc": {
      "enabled": true,
      "defaultKeepStorage": "20GB",
      "policy": [
        {
          "all": false,
          "keepDuration": "168h",
          "keepStorage": "10GB"
        },
        {
          "all": true,
          "keepStorage": "50GB"
        }
      ]
    }
  }
}

7.2 构建器配置

bash
# 创建带配置的构建器
docker buildx create \
  --name mybuilder \
  --driver docker-container \
  --driver-opt image=moby/buildkit:master \
  --driver-opt network=host \
  --buildkitd-flags '--debug' \
  --use

# 配置构建器
docker buildx inspect --bootstrap

下一步

基于 MIT 许可发布