构建多架构镜像的最佳实践

简介: 如今,Docker 容器镜像可以支持多种架构/平台,多架构镜像的构建已经成为了必备技能。

image.png

作者:xcbeyond

博客:https://xcbeyond.cn/ 公众号:程序猿技术大咖


在云时代,容器化已经成为一种事实,把软件产品打包、构建成 Docker 镜像是最基本、最关键的一步。在信创的大背景下,云环境中会存在 x86、arm 等不同的架构,所以在构建镜像时需要构建出多种架构的镜像,以适配不同架构的服务器。


在拉取 Docker 镜像时,会根据当前环境的架构自动拉取对应架构的镜像,如:在 x86 环境下拉取的镜像为 x86 架构的镜像,在 arm 环境下拉取的镜像为 arm 架构的镜像。(前提是,该镜像是多架构的镜像


本文将针对基于 Docker Buildx 来构建多架构的镜像展开说明(一次构建多架构的镜像)。

1、buildx 安装

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


  1. 下载 buildx 二进制文件。
    Github Release 页面下载最新的 buildx 二进制文件。
    根据您的操作系统选择对应的二进制文件。


  1. buildx 复制到 Docker 对应目录。
    重命名下载的 buildx 二进制文件,并将其复制到您操作系统对应的目录:
操作系统 二进制名称 目标文件夹
Linux docker-buildx $HOME/.docker/cli-plugins
MacOS docker-buildx $HOME/.docker/cli-plugins
Windows docker-buildx.exe %USERPROFILE%\.docker\cli-plugins


例如,我的 MacOS:

xcbeyond@xcbeyonddeMacBook-Pro ~ % mv ~/Downloads/buildx-v0.7.1.darwin-arm64 ~/.docker/cli-plugins/docker-buildx
xcbeyond@xcbeyonddeMacBook-Pro ~ % chmod +x ~/.docker/cli-plugins/docker-buildx

注意:需对 buildx 二进制文件赋予权限,执行 chmod +x


  1. 检查 buildx。
    执行 docker buildx version
xcbeyond@xcbeyonddeMacBook-Pro ~ % docker buildx version
github.com/docker/buildx v0.7.1 05846896d149da05f3d6fd1e7770da187b52a247


2、开启 binfmt_misc 来运行非本地架构的 Docker 镜像

如果您使用的是 Mac 或者 Windows 版本 Docker 桌面版,则可以跳过这个步骤,因为 binfmt_misc 默认开启。


如果使用的是其它平台,可使用 tonistiigi/binfmt 镜像进行安装:

docker run --privileged --rm tonistiigi/binfmt --install all


3、将默认 Docker 构建器切换为多架构构建器

默认情况下,Docker 会使用默认构建器,是不支持多架构构建。


为了构建多架构的镜像,需要创建新的支持多架构的构建器,需执行 docker buildx create --use

xcbeyond@xcbeyonddeMacBook-Pro % docker buildx create --use --name mybuilder
mybuilder


查看新的多架构构建器是否生效,需执行 docker buildx ls

xcbeyond@xcbeyonddeMacBook-Pro % docker buildx ls
NAME/NODE       DRIVER/ENDPOINT             STATUS   PLATFORMS
mybuilder *     docker-container                     
  mybuilder0    unix:///var/run/docker.sock inactive 
desktop-linux   docker                               
  desktop-linux desktop-linux               running  linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
default         docker                               
  default       default                     running  linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6


4、构建多架构镜像

  1. 编写测试程序。
    为方便测试,用 Golang 写了一个简单的程序,并输出当前程序运行环境的架构信息:
package main
import (
   "fmt"
   "runtime"
)
func main() {
   fmt.Printf("the current platform architecture is %s.\n", runtime.GOARCH)
}
  1. 编写 Dockerfile。

编写该程序的 Dockerfile

FROM xcbeyond/go-builder:1.16
LABEL maintainer xcbeyond
WORKDIR /app
COPY multi-arch-test.go /app
RUN go build -o multi-arch-test /app/multi-arch-test.go
CMD ["./multi-arch-test"]
  1. 构建多架构镜像。
    通过命令 docker buildx build -t  --platform=linux/arm64,linux/amd64 . --push,构建一个支持 arm64 和 amd64 架构的多架构镜像,并推送至 Docker Hub:
    (参数 --push 会自动将镜像推送到 Docker Hub,本地并不会保留该镜像。如果不想推送,则可去掉该参数。)
xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker buildx build -t xcbeyond/multi-arch-test --platform=linux/arm64,linux/amd64 . --push
[+] Building 3105.4s (19/19) FINISHED                                                                                                                                                                       
=> [internal] load build definition from Dockerfile                                                                                                                                                   0.0s
=> => transferring dockerfile: 222B                                                                                                                                                                   0.0s
=> [internal] load .dockerignore                                                                                                                                                                      0.0s
=> => transferring context: 2B                                                                                                                                                                        0.0s
=> [linux/amd64 internal] load metadata for docker.io/xcbeyond/go-builder:1.16                                                                                                                        5.2s
=> [linux/arm64 internal] load metadata for docker.io/xcbeyond/go-builder:1.16                                                                                                                        4.9s
=> [auth] xcbeyond/go-builder:pull token for registry-1.docker.io                                                                                                                                     0.0s
=> [internal] load build context                                                                                                                                                                      0.0s
=> => transferring context: 40B                                                                                                                                                                       0.0s
=> [linux/amd64 1/4] FROM docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc                                                               2323.9s
=> => resolve docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc                                                                              0.0s
=> => sha256:6e1d20a8313edd44a36cb9198f4d11ac5eedb41d1faf5e8a33c5a0a5a25d2b92 85.80MB / 85.80MB                                                                                                    2318.7s
=> => sha256:6494e4811622b31c027ccac322ca463937fd805f569a93e6f15c01aade718793 54.57MB / 54.57MB                                                                                                      27.3s
=> => sha256:5b59121a0c3517cfd68aba8a3955cbb40ca12dd56db3317e3a17cf56131ca915 129.08MB / 129.08MB                                                                                                    77.1s
=> => sha256:cb5b7ae361722f070eca53f35823ed21baa85d61d5d95cd5a95ab53d740cdd56 10.87MB / 10.87MB                                                                                                      96.5s
=> => sha256:9b829c73b52b92b97d5c07a54fb0f3e921995a296c714b53a32ae67d19231fcd 5.15MB / 5.15MB                                                                                                         5.2s
=> => sha256:0e29546d541cdbd309281d21a73a9d1db78665c1b95b74f32b009e0b77a6e1e3 54.92MB / 54.92MB                                                                                                      61.0s
=> => extracting sha256:0e29546d541cdbd309281d21a73a9d1db78665c1b95b74f32b009e0b77a6e1e3                                                                                                              1.5s
=> => extracting sha256:9b829c73b52b92b97d5c07a54fb0f3e921995a296c714b53a32ae67d19231fcd                                                                                                              0.1s
=> => extracting sha256:cb5b7ae361722f070eca53f35823ed21baa85d61d5d95cd5a95ab53d740cdd56                                                                                                              0.3s
=> => extracting sha256:6494e4811622b31c027ccac322ca463937fd805f569a93e6f15c01aade718793                                                                                                              1.6s
=> => extracting sha256:6e1d20a8313edd44a36cb9198f4d11ac5eedb41d1faf5e8a33c5a0a5a25d2b92                                                                                                              1.9s
=> => extracting sha256:5b59121a0c3517cfd68aba8a3955cbb40ca12dd56db3317e3a17cf56131ca915                                                                                                              3.3s
=> => extracting sha256:2db41f0db9d9d9a1f49978ec31e8d187f491767e9b377f5ee121827c407e015e                                                                                                              0.0s
=> [linux/arm64 1/4] FROM docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc                                                               2187.3s
=> => resolve docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc                                                                              0.0s
=> => sha256:221ff675cd357b3b345da24f781791fc9b91066d687f9e928993aab31618d13d 99.63MB / 99.63MB                                                                                                      54.3s
=> => sha256:627b3401fb617535edd16e96bd5941ecea7fe10ce6087bd47707602cfc396c2b 81.01MB / 81.01MB                                                                                                     472.1s
=> => sha256:841dd868500b6685b6cda93c97ea76e817b427d7a10bf73e9d03356fac199ffd 54.67MB / 54.67MB                                                                                                    2084.9s
=> => sha256:aa9c5b49b9db3dd2553e8ae6c2081b77274ec0a8b1f9903b0e5ac83900642098 10.66MB / 10.66MB                                                                                                       6.2s
=> => sha256:ac9d381bd1e98fa8759f80ff42db63c8fce4ac9407b2e7c8e0f031ed9f96432b 5.14MB / 5.14MB                                                                                                         6.8s
=> => sha256:94a23d3cb5be24659b25f17537307e7f568d665244f6a383c1c6e51e31080749 53.60MB / 53.60MB                                                                                                      22.7s
=> => extracting sha256:94a23d3cb5be24659b25f17537307e7f568d665244f6a383c1c6e51e31080749                                                                                                              1.5s
=> => extracting sha256:ac9d381bd1e98fa8759f80ff42db63c8fce4ac9407b2e7c8e0f031ed9f96432b                                                                                                              0.1s
=> => extracting sha256:aa9c5b49b9db3dd2553e8ae6c2081b77274ec0a8b1f9903b0e5ac83900642098                                                                                                              0.2s
=> => extracting sha256:841dd868500b6685b6cda93c97ea76e817b427d7a10bf73e9d03356fac199ffd                                                                                                              1.5s
=> => extracting sha256:627b3401fb617535edd16e96bd5941ecea7fe10ce6087bd47707602cfc396c2b                                                                                                              1.7s
=> => extracting sha256:221ff675cd357b3b345da24f781791fc9b91066d687f9e928993aab31618d13d                                                                                                              2.7s
=> => extracting sha256:10c716f05a00666c190fb40f99503dc83b2886de744ab9b3dc6c5d37d01f6e49                                                                                                              0.0s
=> [auth] xcbeyond/go-builder:pull token for registry-1.docker.io                                                                                                                                     0.0s
=> [linux/arm64 2/4] WORKDIR /app                                                                                                                                                                     0.1s
=> [linux/arm64 3/4] COPY multi-arch-test.go /app                                                                                                                                                     0.0s
=> [linux/arm64 4/4] RUN go build -o multi-arch-test /app/multi-arch-test.go                                                                                                                          0.3s
=> [linux/amd64 2/4] WORKDIR /app                                                                                                                                                                     0.2s
=> [linux/amd64 3/4] COPY multi-arch-test.go /app                                                                                                                                                     0.0s
=> [linux/amd64 4/4] RUN go build -o multi-arch-test /app/multi-arch-test.go                                                                                                                          1.5s
=> exporting to image                                                                                                                                                                               774.4s
=> => exporting layers                                                                                                                                                                               10.5s
=> => exporting manifest sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2                                                                                                      0.0s
=> => exporting config sha256:628f504898973d1d935ffd37993d1db5fdc4715c5d58467db2c6531d3d7d3181                                                                                                        0.0s
=> => exporting manifest sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd                                                                                                      0.0s
=> => exporting config sha256:47e7af533f821be5ba256919303e0de3b39990109a419a98dbfddc6c82086822                                                                                                        0.0s
=> => exporting manifest list sha256:8417543ebc47e6040a67a392d6ee9de05735ed464e48b22fcc3bdf66ce22224b                                                                                                 0.0s
=> => pushing layers                                                                                                                                                                                761.8s
=> => pushing manifest for docker.io/xcbeyond/multi-arch-test:latest@sha256:8417543ebc47e6040a67a392d6ee9de05735ed464e48b22fcc3bdf66ce22224b                                                          2.0s
=> [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io                                                                                                                           0.0s
=> [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io                                                                                                                           0.0s
=> [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io                                                                                                                           0.0s


5、测试多架构镜像

将构建的多架构镜像 xcbeyond/multi-arch-test:latest 进行测试,以确保能够正常运行,并使用对应架构镜像能够输出匹配的架构信息。


  1. 查看每个架构镜像的信息。
    执行命令 docker manifest inspect,可查看该镜像清单,并能得知该镜像对应架构的镜像 SHA 值:
xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker manifest inspect xcbeyond/multi-arch-test:latest
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 2419,
         "digest": "sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2",
         "platform": {
            "architecture": "arm64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 2420,
         "digest": "sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      }
   ]
}

也可以直接在 Docker Hub 上直接看到该镜像支持的多架构信息:

image.png

  1. 根据不同架构镜像的 SHA 值,来逐一运行该镜像,并查看其输出结果。
    分别执行 docker run --rm 命令:


arm 架构的镜像:

xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker run --rm xcbeyond/multi-arch-test:latest@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2
Unable to find image 'xcbeyond/multi-arch-test:latest@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2' locally
docker.io/xcbeyond/multi-arch-test@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2: Pulling from xcbeyond/multi-arch-test
94a23d3cb5be: Pull complete 
ac9d381bd1e9: Pull complete 
aa9c5b49b9db: Pull complete 
841dd868500b: Pull complete 
627b3401fb61: Pull complete 
221ff675cd35: Pull complete 
10c716f05a00: Pull complete 
15bae122089f: Pull complete 
d764b5be0a55: Pull complete 
34bfa57028a2: Pull complete 
Digest: sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2
Status: Downloaded newer image for xcbeyond/multi-arch-test@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2
the current platform architecture is arm64.


x86 架构的镜像:

xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker run --rm xcbeyond/multi-arch-test:latest@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd
Unable to find image 'xcbeyond/multi-arch-test:latest@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd' locally
docker.io/xcbeyond/multi-arch-test@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd: Pulling from xcbeyond/multi-arch-test
0e29546d541c: Pull complete 
9b829c73b52b: Pull complete 
cb5b7ae36172: Pull complete 
6494e4811622: Pull complete 
6e1d20a8313e: Pull complete 
5b59121a0c35: Pull complete 
2db41f0db9d9: Pull complete 
f708bf6a9dc8: Pull complete 
cb0d69b97354: Pull complete 
a8f5aa83ecfb: Pull complete 
Digest: sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd
Status: Downloaded newer image for xcbeyond/multi-arch-test@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd
the current platform architecture is amd64.


上面的输出结果,和我们的期望一致:多架构的镜像构建成功,并能在各自架构环境下运行。

6、总结

多架构镜像是基于 Docker Buildx 构建的,目前 buildx 还需额外安装,未来 buildx 很可能成为 docker build 命令的一部分,无需额外安装,毕竟多架构镜像已在各种场景中应用广泛起来了。


参考文章:

  1. Docker Buildx
  2. How to Build Multi-Architecture Docker Images with BuildX | Deploy containers to x86 and ARM!
目录
相关文章
|
6月前
|
数据采集 运维 监控
构建企业级Selenium爬虫:基于隧道代理的IP管理架构
构建企业级Selenium爬虫:基于隧道代理的IP管理架构
|
6月前
|
人工智能 监控 测试技术
告别只会写提示词:构建生产级LLM系统的完整架构图​
本文系统梳理了从提示词到生产级LLM产品的八大核心能力:提示词工程、上下文工程、微调、RAG、智能体开发、部署、优化与可观测性,助你构建可落地、可迭代的AI产品体系。
905 52
|
6月前
|
机器学习/深度学习 人工智能 搜索推荐
从零构建短视频推荐系统:双塔算法架构解析与代码实现
短视频推荐看似“读心”,实则依赖双塔推荐系统:用户塔与物品塔分别将行为与内容编码为向量,通过相似度匹配实现精准推送。本文解析其架构原理、技术实现与工程挑战,揭秘抖音等平台如何用AI抓住你的注意力。
1746 7
从零构建短视频推荐系统:双塔算法架构解析与代码实现
|
5月前
|
存储 监控 安全
132_API部署:FastAPI与现代安全架构深度解析与LLM服务化最佳实践
在大语言模型(LLM)部署的最后一公里,API接口的设计与安全性直接决定了模型服务的可用性、稳定性与用户信任度。随着2025年LLM应用的爆炸式增长,如何构建高性能、高安全性的REST API成为开发者面临的核心挑战。FastAPI作为Python生态中最受青睐的Web框架之一,凭借其卓越的性能、强大的类型安全支持和完善的文档生成能力,已成为LLM服务化部署的首选方案。
1061 3
|
6月前
|
消息中间件 缓存 监控
中间件架构设计与实践:构建高性能分布式系统的核心基石
摘要 本文系统探讨了中间件技术及其在分布式系统中的核心价值。作者首先定义了中间件作为连接系统组件的"神经网络",强调其在数据传输、系统稳定性和扩展性中的关键作用。随后详细分类了中间件体系,包括通信中间件(如RabbitMQ/Kafka)、数据中间件(如Redis/MyCAT)等类型。文章重点剖析了消息中间件的实现机制,通过Spring Boot代码示例展示了消息生产者的完整实现,涵盖消息ID生成、持久化、批量发送及重试机制等关键技术点。最后,作者指出中间件架构设计对系统性能的决定性影响,
|
6月前
|
SQL 弹性计算 关系型数据库
如何用读写分离构建高效稳定的数据库架构?
在少写多读业务场景中,主实例读请求压力大,影响性能。通过创建只读实例并使用数据库代理实现读写分离,可有效降低主实例负载,提升系统性能与可用性。本文详解配置步骤,助你构建高效稳定的数据库架构。
|
5月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
Cloud Native Devops 云计算
云计算的未来:云原生架构与微服务的革命####
【10月更文挑战第21天】 随着企业数字化转型的加速,云原生技术正迅速成为IT行业的新宠。本文深入探讨了云原生架构的核心理念、关键技术如容器化和微服务的优势,以及如何通过这些技术实现高效、灵活且可扩展的现代应用开发。我们将揭示云原生如何重塑软件开发流程,提升业务敏捷性,并探索其对企业IT架构的深远影响。 ####
438 3

热门文章

最新文章