buildx 是一个 Docker CLI 插件,用于使用 BuildKit扩展构建功能。

GitHub:https://github.com/docker/buildx

https://zhuanlan.zhihu.com/p/622399482

主要特征:

  • 熟悉的 UI 来自 docker build
  • 具有容器驱动程序的完整 BuildKit 功能
  • 多个构建器实例支持
  • 跨平台镜像的多节点构建
  • 撰写构建支持
  • 高级构建构造 ( bake)
  • 容器内驱动程序支持(Docker 和 Kubernetes)

安装

与 Docker 一起使用buildx需要 Docker 引擎 19.03 或更高版本

注意:使用不兼容版本的 Docker 可能会导致意外行为,并且可能会导致问题,尤其是在将 Buildx 构建器与更新版本的 BuildKit 一起使用时。

  • Windows 和 macOS
    Docker Buildx 包含在适用于 Windows 和 macOS 的 Docker Desktop 中 。

  • Linux 软件包
    根据 Docker Engine 安装文档安装时,Docker Engine 软件包存储库包含 Docker Buildx 软件包。安装 docker-buildx-plugin 包以安装 Buildx 插件。

您还可以从 GitHub 发布页面下载最新的二进制文件。

重命名相关的二进制文件并将其复制到与您的操作系统匹配的目标:

操作系统 二进制名称 目标文件夹
Linux docker-buildx $HOME/.docker/cli-plugins
macOS docker-buildx $HOME/.docker/cli-plugins
Windows docker-buildx.exe %USERPROFILE%.docker\cli-plugins

或者将其复制到这些文件夹之一以在系统范围内安装。

在 Unix 环境中:

/usr/local/lib/docker/cli-plugins或者/usr/local/libexec/docker/cli-plugins
/usr/lib/docker/cli-plugins或者/usr/libexec/docker/cli-plugins

在 Windows 上:

C:\ProgramData\Docker\cli-plugins
C:\Program Files\Docker\cli-plugins

在 Unix 环境中,可能还需要使用以下命令使其可执行 chmod +x:

$ chmod +x ~/.docker/cli-plugins/docker-buildx

Dockerfile

以下是 如何基于 docker/buildx-bin 镜像在 Dockerfile 中安装和使用 Buildx:

# syntax=docker/dockerfile:1
FROM docker
COPY --from=docker/buildx-bin /buildx /usr/libexec/docker/cli-plugins/docker-buildx
RUN docker buildx version

将 buildx 设置为默认构建器

运行该命令 docker buildx install 会将 docker builder 命令设置为 docker buildx build. 这导致能够 docker build 使用当前的 buildx 构建器。

要删除此别名,请运行docker buildx uninstall.

# Buildx 0.6+
$ docker buildx bake "https://github.com/docker/buildx.git"
$ mkdir -p ~/.docker/cli-plugins
$ mv ./bin/build/buildx ~/.docker/cli-plugins/docker-buildx

# Docker 19.03+
$ DOCKER_BUILDKIT=1 docker build --platform=local -o . "https://github.com/docker/buildx.git"
$ mkdir -p ~/.docker/cli-plugins
$ mv buildx ~/.docker/cli-plugins/docker-buildx

# Local
$ git clone https://github.com/docker/buildx.git && cd buildx
$ make install

快速入门

使用 buildx 进行构建

Buildx 是一个 Docker CLI 插件,它扩展了 docker build 命令,完全支持 Moby BuildKit 构建器工具包提供的功能。docker build它提供了与许多新功能相同的用户体验,例如创建范围构建器实例和同时针对多个节点进行构建。

安装后,使用 Docker 19.03 可以通过命令访问 buildx docker buildx。 docker buildx build 是启动新构建的命令。对于早于 19.03 的 Docker 版本,可以直接调用 buildx 二进制文件来访问 docker buildx 子命令。

$ docker buildx build .
[+] Building 8.4s (23/32)
 => ...

Buildx 将始终使用 BuildKit 引擎进行构建,并且不需要 DOCKER_BUILDKIT=1 环境变量来启动构建。

docker buildx build 命令支持 的可用功能 docker build,包括输出配置、内联构建缓存和指定目标平台等功能。此外,Buildx 还支持常规功能尚不可用的新功能,docker build例如构建清单列表、分布式缓存以及将构建结果导出到 OCI 映像 tarball。

Buildx 非常灵活,可以在通过各种 “驱动程序” 公开的不同配置中运行。每个驱动程序都定义了构建的运行方式和位置,并且具有不同的功能集。

我们目前支持以下驱动程序:

  • docker 驱动
  • docker-container 驱动
  • kubernetes 驱动
  • remote 驱动)

有关驱动程序的更多信息,请参阅驱动程序指南。

使用构建器实例

默认情况下,buildx 最初将使用 docker 支持的驱动程序,从而提供与本机 docker build. 请注意,您必须使用本地共享守护程序来构建应用程序。

Buildx 允许您创建独立构建器的新实例。这可用于为 CI 构建获取一个范围环境,该环境不会更改共享守护程序的状态,或者用于隔离不同项目的构建。您可以为一组远程节点创建一个新实例,形成构建场,并在它们之间快速切换。

您可以使用该命令创建新实例 docker buildx create 。这将根据您当前的配置创建一个具有单个节点的新构建器实例。

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

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

Docker 还具有一个docker context 可用于为远程 Docker API 端点命名的命令。Buildx 集成,docker context以便您的所有上下文自动获取默认构建器实例。在创建新的构建器实例或向其添加节点时,您还可以将上下文名称设置为目标。

构建多平台图像

BuildKit 旨在很好地构建多个平台,而不仅适用于调用构建的用户恰好运行的体系结构和操作系统。

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

docker-container 当当前构建器实例由或 驱动程序支持时kubernetes,您可以一起指定多个平台。在这种情况下,它构建一个清单列表,其中包含所有指定架构的图像。docker run 当您在或中使用此映像时docker service,Docker 会根据节点的平台选择正确的映像。

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

  1. 使用内核中的 QEMU 模拟支持
  2. 使用相同的构建器实例在多个本机节点上构建
  3. 使用 Dockerfile 中的阶段交叉编译到不同的架构

如果您的节点已经支持 QEMU(例如,如果您正在使用 Docker Desktop),QEMU 是最简单的入门方法。它不需要更改您的 Dockerfile,并且 BuildKit 会自动检测可用的辅助架构。当 BuildKit 需要运行不同架构的二进制文件时,它会通过binfmt_misc 处理程序中注册的二进制文件自动加载它。

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

# 安装 binfmt 支持
$ docker run --privileged --rm tonistiigi/binfmt --install all

使用多个本机节点可以为 QEMU 无法处理的更复杂的情况提供更好的支持,并且通常具有更好的性能。您可以使用该标志将其他节点添加到构建器实例 --append

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

$ 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 .

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

# syntax=docker/dockerfile:1
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 交叉编译助手来实现更高级的用例。

Pipeline 示例

pipeline {
  agent any
  stages {
    stage('检出') {
      steps {
        checkout([$class : 'GitSCM',
        branches         : [[name: GIT_BUILD_REF]],
        userRemoteConfigs: [[
          url          : GIT_REPO_URL,
          credentialsId: CREDENTIALS_ID
        ]]
      ])
    }
  }

  stage('编译') {
    steps {
      withCredentials([
        usernamePassword(
          // CODING 持续集成的环境变量中内置了一个用于上传到当前项目制品库的凭证
          credentialsId: "${CODING_ARTIFACTS_CREDENTIALS_ID}",
          usernameVariable: 'CODING_ARTIFACTS_USERNAME',
          passwordVariable: 'CODING_ARTIFACTS_PASSWORD'
        )]) {
          withEnv([
                "CODING_ARTIFACTS_USERNAME=${CODING_ARTIFACTS_USERNAME}",
                "CODING_ARTIFACTS_PASSWORD=${CODING_ARTIFACTS_PASSWORD}"
              ]) {
              sh 'mvn package -U -Dmaven.test.skip=true -s ./settings.xml'
            }
          }
        }
      }

      stage('构建镜像并推送到 CODING Docker 制品库') {
        steps {
          script {
            DOCKER_VERSION = BRANCH_NAME.replace('release/','')
            if(BRANCH_NAME == 'master'){
              DOCKER_VERSION = 'latest'
            }
          }

          // 不使用 buildx
          // sh "docker login -u ${PROJECT_TOKEN_GK} -p ${PROJECT_TOKEN} ${CODING_DOCKER_REG_HOST}"
          // sh "docker build -t ${CODING_DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION} -f ${DOCKERFILE_PATH} ${DOCKER_BUILD_CONTEXT}"
          // sh "docker tag  ${CODING_DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION} ${CODING_DOCKER_REG_HOST}/${CODING_DOCKER_IMAGE_NAME}:${DOCKER_VERSION}"
          // sh "docker push ${CODING_DOCKER_REG_HOST}/${CODING_DOCKER_IMAGE_NAME}:${DOCKER_VERSION}"
          // 使用 buildx
          sh "docker login -u ${PROJECT_TOKEN_GK} -p ${PROJECT_TOKEN} ${CODING_DOCKER_REG_HOST}"
          sh 'docker run --rm --privileged tonistiigi/binfmt --install all'
          sh 'docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master-tencent'
          sh 'docker buildx use mybuilder-cn '
          sh "docker buildx build --platform linux/arm64,linux/amd64  -t ${CODING_DOCKER_REG_HOST}/${CODING_DOCKER_IMAGE_NAME}:${DOCKER_VERSION} -f ${DOCKERFILE_PATH} ${DOCKER_BUILD_CONTEXT} --push"
          sh "docker buildx imagetools inspect ${CODING_DOCKER_REG_HOST}/${CODING_DOCKER_IMAGE_NAME}:${DOCKER_VERSION}"

        }
      }

    }
    environment {
      DOCKER_REPO_NAME = 'docker'
      DOCKERFILE_PATH = 'Dockerfile'
      DOCKER_BUILD_CONTEXT = '.'
      DOCKER_IMAGE_VERSION = '${GIT_COMMIT_SHORT}'
      CODING_DOCKER_REG_HOST = "${CCI_CURRENT_TEAM}-docker.pkg.${CCI_CURRENT_DOMAIN}"
      CODING_DOCKER_IMAGE_NAME = "${PROJECT_NAME.toLowerCase()}/${DOCKER_REPO_NAME}/${DEPOT_NAME}"
      CODING_MAVEN_REPO_ID = "${CCI_CURRENT_TEAM}-${PROJECT_NAME}-${MAVEN_REPO_NAME}"
      CODING_MAVEN_REPO_URL = "${CCI_CURRENT_WEB_PROTOCOL}://${CCI_CURRENT_TEAM}-maven.pkg.${CCI_CURRENT_DOMAIN}/repository/${PROJECT_NAME}/${MAVEN_REPO_NAME}/"
    }
  }
作者:Jeebiz  创建时间:2023-11-09 18:54
最后编辑:Jeebiz  更新时间:2024-08-02 14:21