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

简介: 如今,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!
目录
相关文章
|
24天前
|
监控 安全 API
使用PaliGemma2构建多模态目标检测系统:从架构设计到性能优化的技术实践指南
本文详细介绍了PaliGemma2模型的微调流程及其在目标检测任务中的应用。PaliGemma2通过整合SigLIP-So400m视觉编码器与Gemma 2系列语言模型,实现了多模态数据的高效处理。文章涵盖了开发环境构建、数据集预处理、模型初始化与配置、数据加载系统实现、模型微调、推理与评估系统以及性能分析与优化策略等内容。特别强调了计算资源优化、训练过程监控和自动化优化流程的重要性,为机器学习工程师和研究人员提供了系统化的技术方案。
146 77
使用PaliGemma2构建多模态目标检测系统:从架构设计到性能优化的技术实践指南
|
2天前
|
容灾 网络协议 数据库
云卓越架构:云上网络稳定性建设和应用稳定性治理最佳实践
本文介绍了云上网络稳定性体系建设的关键内容,包括面向失败的架构设计、可观测性与应急恢复、客户案例及阿里巴巴的核心电商架构演进。首先强调了网络稳定性的挑战及其应对策略,如责任共担模型和冗余设计。接着详细探讨了多可用区部署、弹性架构规划及跨地域容灾设计的最佳实践,特别是阿里云的产品和技术如何助力实现高可用性和快速故障恢复。最后通过具体案例展示了秒级故障转移的效果,以及同城多活架构下的实际应用。这些措施共同确保了业务在面对网络故障时的持续稳定运行。
|
5天前
|
运维 监控 BI
卓越架构之FinOps最佳实践
本文探讨了云成本管理的趋势和FinOps的最佳实践。随着云计算的普及,传统的IT管理模式已无法适应按需使用和按量付费的新模式,导致企业面临资源浪费和成本失控的风险。FinOps作为一种管理理念,强调运维、财务和技术团队的合作,通过数据驱动和业务价值驱动的方式优化云成本。文章介绍了FinOps的核心挑战、最佳实践及技术工具的应用,帮助企业有效管理和优化云成本,实现降本增效。
|
9天前
|
Kubernetes 安全 数据安全/隐私保护
云卓越架构:容器安全最佳实践
本次分享由阿里云智能集团解决方案架构师张玉峰主讲,主题为“云卓越架构:容器安全最佳实践”。内容涵盖容器安全的挑战、云原生容器安全架构及典型场景。首先分析了容器安全面临的问题,如镜像漏洞和权限管理。接着介绍了容器安全架构的五个维度:身份权限管理、配置安全检查、运行时防护、镜像安全检测及发布的安全管控。最后通过具体场景展示了容器身份与权限管理、密钥管理、运行时防入侵等最佳实践,强调了安全左移的重要性,确保从开发到运行的全生命周期安全覆盖。
|
19天前
|
Serverless 决策智能 UED
构建全天候自动化智能导购助手:从部署者的视角审视Multi-Agent架构解决方案
在构建基于多代理系统(Multi-Agent System, MAS)的智能导购助手过程中,作为部署者,我体验到了从初步接触到深入理解再到实际应用的一系列步骤。整个部署过程得到了充分的引导和支持,文档详尽全面,使得部署顺利完成,未遇到明显的报错或异常情况。尽管初次尝试时对某些复杂配置环节需反复确认,但整体流程顺畅。
|
27天前
|
缓存 Kubernetes 容灾
如何基于服务网格构建高可用架构
分享如何利用服务网格构建更强更全面的高可用架构
|
1月前
|
监控 安全 持续交付
构建高效微服务架构:策略与实践####
在数字化转型的浪潮中,微服务架构凭借其高度解耦、灵活扩展和易于维护的特点,成为现代企业应用开发的首选。本文深入探讨了构建高效微服务架构的关键策略与实战经验,从服务拆分的艺术到通信机制的选择,再到容器化部署与持续集成/持续部署(CI/CD)的实践,旨在为开发者提供一套全面的微服务设计与实现指南。通过具体案例分析,揭示如何避免常见陷阱,优化系统性能,确保系统的高可用性与可扩展性,助力企业在复杂多变的市场环境中保持竞争力。 ####
45 2
|
1月前
|
弹性计算 Kubernetes API
构建高效后端服务:微服务架构的深度剖析与实践####
本文深入探讨了微服务架构的核心理念、设计原则及实现策略,旨在为开发者提供一套系统化的方法论,助力其构建灵活、可扩展且易于维护的后端服务体系。通过案例分析与实战经验分享,揭示了微服务在提升开发效率、优化资源利用及增强系统稳定性方面的关键作用。文章首先概述了微服务架构的基本概念,随后详细阐述了其在后端开发中的应用优势与面临的挑战,最后结合具体实例,展示了如何从零开始规划并实施一个基于微服务的后端项目。 ####
|
1月前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
2月前
|
Cloud Native Devops 云计算
云计算的未来:云原生架构与微服务的革命####
【10月更文挑战第21天】 随着企业数字化转型的加速,云原生技术正迅速成为IT行业的新宠。本文深入探讨了云原生架构的核心理念、关键技术如容器化和微服务的优势,以及如何通过这些技术实现高效、灵活且可扩展的现代应用开发。我们将揭示云原生如何重塑软件开发流程,提升业务敏捷性,并探索其对企业IT架构的深远影响。 ####
50 3

热门文章

最新文章