使用 docker buildx 构建多架构镜像

使用 docker buildx 构建多架构镜像

docker 多架构镜像介绍

在 docker 中,同一个 docker 镜像可以在不同的平台上运行,例如在 x86、ARM 等不同的 CPU 架构上。

为了支持这种多平台的镜像构建和管理,docker 在 17.06 版本时引入了 manifest 的概念,在此之前,docker 并没有原生支持多平台镜像的构建和管理,因此开发者需要手动构建和管理不同平台的镜像。需要注意的是,在 docker 19.03 版本中,docker 官方已经推出了 buildx 工具,它可以进一步简化多平台镜像的构建和管理。

接下来我们来看看如何使用 docker manifest 和 docker buildx 来构建和使用多架构镜像。

使用 docker manifest 构建多架构镜像

docker manifest 是一个 docker 镜像的描述文件,它可以用来实现多平台镜像的构建和管理。

在 docker manifest 会包含一个或多个镜像的元数据信息,例如镜像的操作系统、CPU 架构、大小等信息,同时还包含了这些镜像的关系和优先级信息,它可以用来指定多个镜像的组合,或者为单个镜像定义多个平台的支持。

通过使用 docker manifest,可以方便地管理多平台 docker 镜像,同时也可以避免重复构建和维护多个不同平台的镜像,从而降低了开发和维护的成本。

  1. 创建多平台的 docker 镜像
    首先,我们需要为每个平台构建一个 docker 镜像,并将其打上相应的标签。 例如,为 x86 架构构建一个镜像:

    1
    2
    docker build -t monifest:x86 -f dockerfile.x86 .
    docker push monifest:x86

    然后,为 ARM 架构构建一个镜像:

    1
    2
    docker build -t monifest:arm -f dockerfile.arm .
    docker push monifest:arm
  2. 创建 Manifest 文件
    使用 docker CLI 命令创建 Manifest 文件,并将所有平台的镜像关联在一起:

docker manifest create monifest:v1 monifest:x86 monifest:arm

  1. 给 manifest 打注解

    1
    2
    docker manifest annotate monifest:v1 monifest:x86 --os linux --arch amd64
    docker manifest annotate monifest:v1 monifest:arm --os linux --arch arm64
  2. 推送多平台镜像 使用 docker CLI 命令将多平台镜像推送到 docker Hub 或其他 docker Registry 中:
    docker manifest push monifest:v1

  3. 查看 Manifest 文件
    使用 docker CLI 命令查看 Manifest 文件的详细信息:
    docker manifest inspect monifest:v1

  4. 使用多架构镜像
    使用 docker CLI 命令从 docker Registry 拉取多平台镜像:

    1
    2
    # 使用多架构镜像,会自动识别当前环境架构
    docker run monifest:v1

使用 buildx 自动构建多架构镜像

  1. 首先创建一个 buildx 构建环境
    docker buildx create --use --name mutli-build

  2. 查看当前构建环境信息,以及支持的架构
    docker buildx inspect mutli-build

  3. dockerfile及源码
    cat main.go

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package main

    import (
    "io"
    "net/http"
    )

    func hello(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "[v1] Hello, Kubernetes!")
    }

    func main() {
    http.HandleFunc("/", hello)
    http.ListenAndServe(":3000", nil)
    }

    cat dockerfile

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    FROM golang AS builder
    RUN mkdir /src
    WORKDIR /src
    COPY . /src
    RUN go env -w GO111MODULE=auto
    RUN CGO_ENABLED=0 go build -o main .

    FROM gcr.io/distroless/base-debian11
    COPY --from=builder /src/main /main
    ENTRYPOINT ["/main"]
    EXPOSE 3000
  4. 构建多架构镜像
    docker buildx build --platform linux/amd64,linux/arm64 -t buildx:v1 . --push

查看多架构镜像manifest

docker buildx imagetools inspect buildx:v1

使用

由于没有arm架构机器,在腾讯云开了一台,云服务器 CVM 产品下中国-广州地区有标准型SR1 属于arm架构产品,可供测试
docker run buildx:v1

注意,本文构建的镜像使用了monifest、buildx等镜像名,无法顺利push到镜像仓库,需根据你的镜像仓库按需配置

参考链接

作者

孤独小狼

发布于

2023-08-06

更新于

2023-08-06

许可协议

评论