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

简介: 如今,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!
目录
相关文章
|
2月前
|
消息中间件 负载均衡 中间件
⚡ 构建真正的高性能即时通讯服务:基于 Netty 集群的架构设计与实现
本文介绍了如何基于 Netty 构建分布式即时通讯集群。随着用户量增长,单体架构面临性能瓶颈,文章对比了三种集群方案:Nginx 负载均衡、注册中心服务发现与基于 ZooKeeper 的消息路由架构。最终选择第三种方案,通过 ZooKeeper 实现服务注册发现与消息路由,并结合 RabbitMQ 支持跨服务器消息广播。文中还详细讲解了 ZooKeeper 搭建、Netty 集群改造、动态端口分配、服务注册、负载均衡及消息广播的实现,构建了一个高可用、可水平扩展的即时通讯系统。
213 0
|
3月前
|
存储 SQL 分布式计算
19章构建企业级大数据平台:从架构设计到数据治理的完整链路
开源社区: 贡献者路径:从提交Issue到成为Committer 会议演讲:通过DataWorks Summit提升影响力 标准制定: 白皮书撰写:通过DAMA数据治理框架认证 专利布局:通过架构设计专利构建技术壁垒
|
2月前
|
小程序 安全 JavaScript
构建即时通讯APP内的小程序生态体系:从架构设计到技术实现-优雅草卓伊凡
构建即时通讯APP内的小程序生态体系:从架构设计到技术实现-优雅草卓伊凡
122 1
构建即时通讯APP内的小程序生态体系:从架构设计到技术实现-优雅草卓伊凡
|
2月前
|
数据采集 存储 分布式计算
一文读懂数据中台架构,高效构建企业数据价值
在数字化时代,企业面临数据分散、难以统一管理的问题。数据中台架构通过整合、清洗和管理数据,打破信息孤岛,提升决策效率。本文详解其核心组成、搭建步骤及常见挑战,助力企业高效用数。
|
2月前
|
消息中间件 缓存 负载均衡
构建高效可扩展的后端架构:从设计到实现
本文探讨了如何构建高效、可扩展的后端架构,涵盖需求分析、系统设计、实现与优化全过程。内容包括微服务、数据库设计、缓存与消息队列等关键技术,并涉及API设计、自动化测试、CI/CD及性能优化策略,助力打造高性能、易维护的后端系统。
|
9月前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
10月前
|
Cloud Native Devops 云计算
云计算的未来:云原生架构与微服务的革命####
【10月更文挑战第21天】 随着企业数字化转型的加速,云原生技术正迅速成为IT行业的新宠。本文深入探讨了云原生架构的核心理念、关键技术如容器化和微服务的优势,以及如何通过这些技术实现高效、灵活且可扩展的现代应用开发。我们将揭示云原生如何重塑软件开发流程,提升业务敏捷性,并探索其对企业IT架构的深远影响。 ####
233 3
|
10月前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
5月前
|
Cloud Native Serverless 流计算
云原生时代的应用架构演进:从微服务到 Serverless 的阿里云实践
云原生技术正重塑企业数字化转型路径。阿里云作为亚太领先云服务商,提供完整云原生产品矩阵:容器服务ACK优化启动速度与镜像分发效率;MSE微服务引擎保障高可用性;ASM服务网格降低资源消耗;函数计算FC突破冷启动瓶颈;SAE重新定义PaaS边界;PolarDB数据库实现存储计算分离;DataWorks简化数据湖构建;Flink实时计算助力风控系统。这些技术已在多行业落地,推动效率提升与商业模式创新,助力企业在数字化浪潮中占据先机。
325 12
|
9月前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
642 70
从单体到微服务:如何借助 Spring Cloud 实现架构转型

热门文章

最新文章