[转帖]buildkit: 用法介绍

buildkit,用法,介绍 · 浏览次数 : 0

小编点评

**构建多平台镜像** * 使用 LLB 打包文件。 * 使用前端构建描述文件。 * 实现自定义构建描述。 **实现自定义构建描述** * An Alternative to the Dockerfile * r2d4/mockerfile **前端构建描述** * linkapiVersion: v1alpha1images:- name: demo * from: ubuntu:22.04 * package: install: - ca-certificates * src: https://storage.googleapis.com/kubernetes-release/release/v1.10.0/bin/linux/amd64/kubectl * dst: /usr/local/bin/kubectl **LLB 构建描述** * gateway.v0 (对接自定义 frontends 的内置服务) **总结** * buildkit 灵活的输入和输出能力。 * 在应用管理中的使用模式。 * 实现代码+配置+XXX -> 交付物。

正文

https://flyer103.com/2022/08/20220806-buildkitd-usage/

 

buildkit 是一个将 source code 转换为 build artifacts 的开源工具,它于 2017 年由 docker 的创始人 tonistiigi 提议,将 docker build 的能力独立成一个项目,针对 构建 的底层技术进行协作,更好复用和定制构建技术,该将项目即为 buildkit

简介

tonistiigi 的 proposal 针对 buildkit 提出了这样的架构设想,力图成为高效、描述构建意图强、扩展性强的基础构建工具:

  • 构建过程分为 frontend 和 backend 两个环节
    • frontend 描述用户的构建定义,如 Dockerfile 等
    • backend 致力于找到最有效的方法解决通用的构建操作描述
  • 作为 long-running 型服务使用

从 GitHub 上的描述可知,buildkit 具有如下特性:

  • Automatic garbage collection
  • Concurrent dependency resolution
  • Efficient instruction caching
  • Build cache import/export
  • Extendable frontend formats
  • Multiple output formats
  • Nested build job invocations
  • Distributable workers
  • Pluggable architecture
  • Execution without root privileges

总结起来,特性如下:

  • 灵活的 input / output
  • 灵活的 cache (local / remote)
  • 并行执行
  • 扩展性强
  • 安全

通过图示可以直观了解 buildkit 的架构和特性:

buildkit overview

常规用法

接下来将会介绍 buildkit 的常规用法,在进行操作前,需要提前准备好如下工具:

本地运行 buildkitd,并配置 buildctl 运行所需的环境变量 (下述以 v0.10.3 版本为例):

$ docker run -d --name buildkitd --privileged moby/buildkit:v0.10.3
$ export BUILDKIT_HOST=docker-container://buildkitd
$ buildctl build --help

构建镜像

基于 Dockerfile 构建镜像,但不导出

buildkit 默认不导出产物,下述操作仅起到构建效果:

$ cat > Dockerfile <<EOF
FROM nginx:1.21.0

RUN sed -i 's#http://deb.debian.org#https://mirrors.cloud.tencent.com#g' /etc/apt/sources.list

RUN apt-get update
RUN apt-get install -y curl

RUN mkdir -p /app/bin/
RUN cd /app/bin && curl -LO https://github.com/fullstorydev/grpcurl/releases/download/v1.8.6/grpcurl_1.8.6_linux_x86_64.tar.gz \
    && tar xvf grpcurl_1.8.6_linux_x86_64.tar.gz

WORKDIR /app/bin/

CMD ["nginx", "-g", "daemon off;"]
EOF
$ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=.

产出不同的 output

下述操作将基于上述 Dockerfile 进行。

将输出导入到本地目录 ./tmp

$ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --output type=local,dest=./tmp

将输出导入到本地 tar 包

$ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --output type=tar,dest=out.tar

将输出导出为 docker image

$ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --output type=docker,name=myimage | docker load

将输出导出为 oci tar 包

$ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --output type=oci,dest=output.tar

cache

buildkit 将构建过程中产生的 layer 作为 cache,使用层面包含 export-cache 和 import-cache 两种操作,即导出 cache 和使用 cache。

对于 export-cache,buildkit 支持如下几种类型:

  • inline:将 cache 嵌入到镜像中,并推送镜像到镜像仓库
  • registry:将 cache 和镜像分别推送到镜像仓库
  • local:将 cache 导出到本地目录
  • gha:将 cache 导出到 GitHub Actions 的 cache 服务中
  • s3:将 cache 导出到 S3 对象存储中

对于 import-cache,buildkit 支持如下几种类型:

  • registry:使用镜像仓库中的 cache,对应上述使用 inline / registry 类型导出的 cache
  • local:使用本地的 cache,对应上述使用 local 类型导出的 cache
  • gha:使用 GitHub Actions 中的 cache,对应上述使用 gha 类型导出的 cache
  • s3:使用 S3 中的 cache,对应上述 s3 类型导出的 cache

与此同时,buildkit 支持将不同阶段的 layer 作为 cache:

  • 只导出最终镜像的 layers:对应 min 模式
  • 导出所有步骤的 layers:对应 max 模式

下述给出常见的几种使用 cache 的操作。

使用 inline 类型导出缓存,使用 registry 类型使用缓存

# 首次执行时仅有 `导出缓存` 的操作,重复执行将会既有 `使用缓存` 又有 `导出缓存` 的操作
$ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --output type=image,name=ccr.ccs.tencentyun.com/flyer103/demo-grpcurl:0.1,push=true --export-cache type=inline --import-cache type=registry,ref=ccr.ccs.tencentyun.com/flyer103/demo-grpcurl:0.1

使用 registry 类型导出和使用缓存

# 首次执行时仅有 `导出缓存` 的操作,重复执行将会既有 `使用缓存` 又有 `导出缓存` 的操作
$ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --output type=image,name=ccr.ccs.tencentyun.com/flyer103/demo-grpcurl:0.1,push=true --export-cache type=registry,ref=ccr.ccs.tencentyun.com/flyer103/demo-grpcurl:buildcache --import-cache type=registry,ref=ccr.ccs.tencentyun.com/flyer103/demo-grpcurl:buildcache

使用 local 模式导出和使用缓存

# 导出缓存
$ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --output type=image,name=ccr.ccs.tencentyun.com/flyer103/demo-grpcurl:0.1,push=true --export-cache type=local,dest=./tmp

# 再次构建使用缓存
$ buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --output type=image,name=ccr.ccs.tencentyun.com/flyer103/demo-grpcurl:0.1,push=true --import-cache type=local,src=./tmp

查看 buildkitd 中的缓存

$ buildctl du -v

清理 buildkitd 中的缓存

$ buildctl prune

buildkitd 中 cache 管理的策略

可参见 buildkitd.toml 配置中的描述,不赘述。

构建多平台镜像

$ buildctl build --frontend=dockerfile.v0 --opt platform=linux/amd64,linux/arm64 --local context=. --local dockerfile=. --output type=image,name=ccr.ccs.tencentyun.com/flyer103/demo-grpcurl:0.1,push=true

对 Dockerfile 语法增强

Docker 从 18.09 版本开始,新增内置 buildkitd 作为 backend 执行构建,同时基于 Dockerfile 提供的 Parser directives 特性,可以使用不同版本的 Dockerfile 语法。

如下为不同版本的 Dockerfile 增强的语法:

实现简单的 frontend

buildkit 的强大不仅体现在灵活的 output 和 cache、并发执行等特性,还体现在灵活的 input,即可类似 Dockerfile,自定义不同的构建描述文件,使用自定义的 frontend 来解析描述文件,由 buildkitd 的 backend 执行构建意图。

在 buidlkitd 的实现中,衔接 frontend 和 backend 的核心是名为 LLB (Low-Level Builder),它是一种二进制格式,用来描述构建操作的依赖关系图,定义可参见 buildkit/solver/pb/ops.proto

实现 frontend 的整体思路如下:

buildkitd frontend

下述将给出几个示例,由浅入深理解如何实现自定义的构建描述和 frontends。前 2 个示例关注点在步骤 2) 上,感受如何裸写 LLB,第 3 个示例关注整个链路,走通全部环节。

所有示例源码均在该仓库中:https://github.com/flyer103/buildkit-demo

使用 LLB 硬编码镜像

代码逻辑比较简单,基于 LLB 生成构建的执行动作,包括诸如:

  • 设定执行环境
  • 拷贝文件
  • 执行 shell 命令
  • etc.

源码:link

执行如下命令可查看 json 格式的 LLB 描述:

$ go run cmd/hardcode-image/main.go | buildctl debug dump-llb | jq .

执行构建并导出:

$ go run cmd/hardcode-image/main.go | buildctl build --local context=. --output type=tar,dest=out.tar

可以解开上述 tar 包查看构建的产物。

使用 LLB 打包文件

该示例逻辑和上述实例类似,区别在于使用不同的执行环境,由于执行环境的限制带来了可进行的构建操作的限制。

源码:link

可通过上述相同的操作分析 LLB 和执行构建。

实现自定义构建描述

该示例重点参考 An Alternative to the Dockerfile 和 r2d4/mockerfile,针对 buildkit 当前的版本 (v0.10.3) 做了适配和部分操作的简化。

构建描述文件:link

apiVersion: v1alpha1
images:
- name: demo
  from: ubuntu:22.04
  package:
    install:
    - ca-certificates
    - curl
    - build-essential
    - git
    - gcc
    - lsb-release
  external:
  - src: https://storage.googleapis.com/kubernetes-release/release/v1.10.0/bin/linux/amd64/kubectl
    dst: /usr/local/bin/kubectl
  - src: https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v4.5.5/kustomize_v4.5.5_linux_amd64.tar.gz
    dst: /usr/local/bin/kustomize
  - src: https://get.helm.sh/helm-v3.9.1-linux-amd64.tar.gz
    dst: /tmp/helm
    install:
    - install /tmp/helm/linux-amd64/helm /usr/local/bin/helm
  - src: https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-217.0.0-linux-x86_64.tar.gz
    dst: /tmp

可以简单把构建描述文件类比为 配置文件,其中的关键字定义了支持的构建操作,可修改的值表征了意图操作的数据。 完整的实现源码参见:link

使用前需要将该 frontend 构建为镜像,作为 buildkitd 内置的 gateway.v0 (对接自定义 frontends 的内置服务) 的 source,用法如下:

$ buildctl build --frontend=gateway.v0 --opt source=<FRONTEND IMAGE> --local context=. --local dockerfile=./yaml/frontend-mockerfile/ --output type=oci,dest=output.tar

完整的操作过程参见 frontend-mockerfile

小结

本篇文章主要从宏观视角理解 buildkit 的架构和特性,通过实践 buildkit 常见操作,直观感受 buildkit 的作用和可能性。

buildkit 灵活的输入和输出能力,在 应用管理领域 带来了令人兴奋的想象力,实现 代码+配置+XXX -> 交付物 的最短路径,站在 应用 的维度进行构建和交付。

接下来几篇文章将会研究 buildkit 的核心实现,探索在应用管理中的使用模式。

参考

与[转帖]buildkit: 用法介绍相似的内容:

[转帖]buildkit: 用法介绍

https://flyer103.com/2022/08/20220806-buildkitd-usage/ 2022-08-06 buildkit cloud-native app-delivery buildkit cloud-native app-delivery Word Count: 23

[转帖]用buildkit和containerd构建镜像

https://zhuanlan.zhihu.com/p/366671300 最近因为K8s抛弃Docker了,所以就只装了个containerd,这样就需要一个单独的镜像构建工具了,就用了buildkit,这也是Docker公司扶持的,他们公司的人出来搞的开源工具,官网在 https://gith

[转帖]用buildkit和containerd构建镜像

https://zhuanlan.zhihu.com/p/366671300 最近因为K8s抛弃Docker了,所以就只装了个containerd,这样就需要一个单独的镜像构建工具了,就用了buildkit,这也是Docker公司扶持的,他们公司的人出来搞的开源工具,官网在 https://gith

[转帖]BuildKit

https://github.com/moby/buildkit BuildKit is a toolkit for converting source code to build artifacts in an efficient, expressive and repeatable manner

[转帖]497.【kubernetes】使用 buildkit 构建镜像

https://www.jianshu.com/p/835179171609 一、安装 buildkit 客户端 buildkit 可执行文件: 下载地址解压:tar -zxvf buildkit-v0.10.6.linux-amd64.tar.gz复制到 /usr/bin cp build/bui

[转帖]containerd_v1.6.0+nerdctl+buildkit 二进制安装,支持多CPU并发构建

一、安装containerd # yum install libseccomp -y #下载containerd curl -L https://github.com/containerd/containerd/releases/download/v1.6.0/cri-containerd-cni-

[转帖]containerd_v1.6.0+nerdctl+buildkit 二进制安装,支持多CPU并发构建

一、安装containerd # yum install libseccomp -y #下载containerd curl -L https://github.com/containerd/containerd/releases/download/v1.6.0/cri-containerd-cni-

[转帖]下一代镜像构建工具 Buildkit 简介

https://www.freeaihub.com/post/78098.html Buildkit 是 Docker 公司出品的一款更高效、docekrfile 无关、更契合 [云原生应用] 的新一代 Docker 构建工具。 开源工具已经不能满足 DID 的需求 云原生的一个特点是一切基础设施都

[转帖]巧用 Docker Buildx 构建多种系统架构镜像

http://www.taodudu.cc/news/show-4511396.html?action=onClick Docker Buildx 是一个 Docker CLI 插件,其扩展了 Docker 命令,支持 Moby BuildKit 提供的功能。提供了与 Docker Build 相同

[转帖]nerdctl+buildkitd构建容器镜像

https://www.cnblogs.com/wyh-l6/p/16590586.html 搭建nerdctl+buildkitd环境: 安装nerdctl: wget https://github.com/containerd/nerdctl/releases/download/v0.22.0/