1. docker buildx

Buildx 是基于 BuildKit 的 Docker 扩展插件项目。Buildx 默认使用 BuildKit 引擎进行构建,本质上调用了 Buildkit 的 API,构建是在 Buildkit 的环境中进行的。

Buildx 是一个 Docker CLI 插件,它扩展了 docker build 命令的镜像构建功能,完整的支持 Moby BuildKit builder 工具包提供的特性。也提供了与 docker build 相似的操作体验,并提供了许多新构建特性,比如多架构镜像构建,以及并发构建。

相关的两个项目:

docker buildx 主要特点:

  • docker build 相似的操作体验
  • 使用 docker-container 驱动可以支持完整的 BuildKit 功能
  • 支持多构建器 builder 实例
  • 支持多节构建跨平台的镜像
  • 支持 Compose
  • 支持高级构建特性 (bake)
  • 支持容器内驱动,可以同时支持 Docker 和 Kubernetes

此外,Buildx 还支持常规 Docker 构建所没有的新特性,如构建清单列表 (manifest lists)、分布式缓存构建和将构建结果导出到OCI 镜像 tarball。

1.1. 使用限制

  • Docker 版本限制。使用 buildx 作为 docker CLI 插件需要使用 Docker 19.03 或更新版本。旧版本的 Docker 可以单独安装调用二进制文件作为插件,可以支持部分功能。对于 Docker 版本大于 19.03 的版本,可以直接调用 buildx 二进制来访问 Docker buildx 子命令。
  • Linux 内核版本限制。要求 Linux kernel >= 4.8,因为自该 Linux 内核版本 binfmt_misc 才支持 fix-binary (F) flag。fix_binary 标志允许内核在容器或 chroot 内使用 binfmt_misc 注册的二进制格式处理程序,即使该处理程序二进制文件不是该容器或 chroot 内可见的文件系统的一部分。即可以支持编译打包不同架构平台的镜像。

[!TIP|style:flat] 是否支持多架构,取决于 Buildkit 的环境。 如果内核支持,Buildkit 可以直接支持多架构构建。 如果内核不支持,也可以通过 builder 关联不同架构的机器来进行构建。 如果上面两种方式都无法提供,可以在 Dockerfile 中使用交叉编译构建不同的二进制并打包镜像。

1.2. 驱动

Buildx 具有灵活的特性,支持配置驱动的方式来运行在不同的场景,目前支持三种驱动方式,以后会计划支持更多的驱动。

  • 其一,支持 docker 驱动,将 BuildKit 库绑定到 Docker Daemon 守护进程中。直接使用 dockerd 服务的构建能力。
  • 其二,支持 docker-container 驱动,会自动在 Docker 容器中启动 BuildKit。
  • 其三,支持 kubernetes 驱动,它会自动启动带有定义的 BuildKit 容器镜像的 pod,以构建镜像。

用户即使选择的驱动不同,在使用 buildx 时的方式也基本一样。但有些特性目前 docker 驱动还不支持,因为绑定到 docker daemon 守护进程方式与 BuildKit 库目前使用了不同的存储组件。同时,所有使用 docker 驱动构建的镜像默认会自动添加到 docker images 视图中;而使用其他驱动时,需要使用 --output 选择输出镜像的方法。

1.3. builder 构建器实例

builder 构建器是一个或一组后端提供镜像构建的服务器实例(docker host)。默认情况下 buildx 最初会使用 docker 驱动,提供一个非常类似于原生 docker 构建的用户体验。注意,必须使用本地共享守护进程来构建应用程序。

Buildx 可以创建独立的 builder 实例。这可以用于给 CI 构建提供一个不影响系统共享 docker daemon 守护进程状态的环境,或者用于隔离不同项目的构建。您可以使用一组远程节点来创建新实例,形成构建集群,并在多个 builder 之间快速切换。

你可以使用 docker buildx create 命令创建新的 builder 实例。这将基于当前配置创建一个具有单个节点的 builder 构建器实例。

要使用远程节点,您可以在创建新的构建器时指定 DOCKER_HOST 或远程上下文名称。创建一个新实例后,你可以使用 docker buildx inspectdocker buildx stopdocker buildx rm 命令来管理它的生命周期。要列出所有可用的构建器,请使用 docker buildx ls。创建新构建器后,还可以向其添加新节点。

要在不同的构建器之间切换,使用 docker buildx use <name>。运行此命令后,构建命令将自动使用此构建器。

Docker 还有一个 docker context 命令,可以通过名称来访问远程 Docker API 的 endpoits 实例列表。Buildx 集成了 docker 上下文,这样所有的上下文都会自动获得一个默认的构建器实例。在创建新的构建器实例或向其添加节点时,还可以将上下文名称作为设置目标。

1.4. 构建多架构镜像

[!TIP|style:flat] 多架构镜像(multiple platform image)是指一个镜像 TAG 可以同时提供运行在不同 CPU、操作系统上的镜像清单列表(manifest list)。

BuildKit 被设计成可以很好地支持多个平台进行镜像构建,而不仅仅是针对调用构建的用户当前运行的体系结构和操作系统。

当您调用构建时,可以设置 --platform 标志来指定构建输出的目标平台(例如,linux/amd64、linux/arm64 或 darwin/amd64)。

如果当前构建器实例由 docker-container 驱动 或 kubernetes 驱动程序支持时,您可以同时指定多个平台。在本例中,它构建一个清单列表(manifest list),其中包含所有指定体系结构的镜像。当你在 docker rundocker service 中使用这个镜像时,docker 会根据节点的平台选择正确的镜像。

你可以使用 Buildx 和 Dockerfiles 支持的三种不同策略来构建多平台映像:

  • 在内核中使用 QEMU 模拟支持
  • 使用相同的构建器实例在多个原生节点上构建
  • 使用 Dockerfile 中的一个阶段交叉编译到不同的架构

如果您的节点已经支持 QEMU,那么 QEMU 是最简单的启动方法(例如。如果你正在使用 Docker 桌面)。它不需要修改 Dockerfile,而且 BuildKit 会自动检测可用的二级架构。当 BuildKit 需要为不同的体系构建运行二进制文件时,它会通过在 binfmt_misc 处理程序中注册的二进制文件自动加载它。

为了在主机操作系统上注册到 binfmt_misc 的 QEMU 二进制文件透明地在容器中工作,它们必须使用fix_binary标志进行注册。这需要一个内核 kernel >= 4.8binfmt-support >= 2.1.7。您可以通过检查 F 是否在 /proc/sys/fs/binfmt_misc/qemu-* 中的标志中来检查是否正确注册。虽然 Docker Desktop 为其他平台预先配置了 binfmt_misc 支持,但可能依旧需要使用 tonistiigi/binfmt 镜像来安装。

$ docker run --privileged --rm tonistiigi/binfmt --install all
Unable to find image 'tonistiigi/binfmt:latest' locally
latest: Pulling from tonistiigi/binfmt
2b4d0e08bd75: Pull complete 
c331be51c382: Pull complete 
Digest: sha256:5bf63a53ad6222538112b5ced0f1afb8509132773ea6dd3991a197464962854e
Status: Downloaded newer image for tonistiigi/binfmt:latest
installing: arm64 OK
installing: s390x OK
installing: riscv64 OK
installing: arm OK
installing: ppc64le OK
installing: mips64le OK
installing: mips64 OK
{
  "supported": [
    "linux/amd64",
    "linux/ppc64le",
    "linux/s390x",
    "linux/386",
    "linux/arm/v7",
    "linux/arm/v6"
  ],
  "emulators": [
    "qemu-aarch64",
    "qemu-arm",
    "qemu-mips64",
    "qemu-mips64el",
    "qemu-ppc64le",
    "qemu-riscv64",
    "qemu-s390x"
  ]
}

查看构建器信息

# docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS  PLATFORMS
default * docker                  
  default default         running linux/amd64, linux/386, linux/riscv64, linux/arm/v7, linux/arm/v6, linux/s390x, linux/ppc64le, linux/arm64

使用多个原生节点可以支持 QEMU 无法处理的复杂情况,并且通常具有更好的性能。您可以使用 --append 标志向构建器实例添加额外的节点。

假设在 docker context ls 中存在 node-amd64node-arm64 上下文;

$ docker buildx create --use --name mybuild node-amd64
mybuild
$ docker buildx create --append --name mybuild node-arm64
$ docker buildx build --platform linux/amd64,linux/arm64 .

最后,根据您的项目,您使用的语言可能对交叉编译有很好的支持。在这种情况下,Dockerfiles 中的多阶段构建可以有效地用于为使用 --platform 指定的平台构建二进制文件,使用构建节点的本地架构。像 BUILDPLATFORM 和 TARGETPLATFORM 这样的构建参数列表在你的 Dockerfile 中自动可用,并且可以被作为构建的一部分运行的进程所利用。

FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log
FROM alpine
COPY --from=build /log /log

对于更高级的用例,您也可以使用 tonistiigi/xx Dockerfile 交叉编译助手。

Dockerfile 支持如下架构相关的变量

  • TARGETPLATFORM 构建镜像的目标平台,例如 linux/amd64, linux/arm/v7, windows/amd64。
  • TARGETOS TARGETPLATFORM 的 OS 类型,例如 linux, windows
  • TARGETARCH TARGETPLATFORM 的架构类型,例如 amd64, arm
  • TARGETVARIANT TARGETPLATFORM 的变种,该变量可能为空,例如 v7
  • BUILDPLATFORM 构建镜像主机平台,例如 linux/amd64
  • BUILDOS BUILDPLATFORM 的 OS 类型,例如 linux
  • BUILDARCH BUILDPLATFORM 的架构类型,例如 amd64
  • BUILDVARIANT BUILDPLATFORM 的变种,该变量可能为空,例如 v7

1.5. 高级构建选项(bake)

Buildx 还旨在提供对高级构建概念的支持,而不仅仅是调用单个构建命令。我们希望支持同时构建应用程序中的所有映像,并让用户定义项目特定的可重用构建流,然后任何人都可以轻松调用这些构建流。

BuildKit 可以有效地处理多个并发构建请求和重复数据删除工作。构建命令可以与通用的命令运行程序(例如 make )结合使用。然而,这些工具通常是按顺序调用构建的,因此不能充分利用 BuildKit 并行化的潜力,也不能为用户组合 BuildKit 的输出。对于这个用例,我们添加了一个叫docker buildx bake 的命令。

bake 命令支持从 compose 文件构建映像,类似于 docker-compose 构建,但允许将所有服务作为单个请求的一部分并发构建。

它还支持从 HCL/JSON 文件中定制构建规则,从而实现更好的代码重用和不同的目标组。bake 的设计处于非常早期的阶段,我们正在寻找来自用户的反馈。

1.6. 命令

2. 参考

Copyright © 温玉 2021 | 浙ICP备2020032454号 all right reserved,powered by Gitbook该文件修订时间: 2023-05-22 14:19:45

results matching ""

    No results matching ""