微技术

关注技术领域,分享资讯和经验。

DockerHub跨平台下载Arm架构的镜像

Docker是一个开源的容器化平台,它可以让开发者打包应用程序及其依赖项到一个容器中,并在任何地方运行这个容器,而不用担心环境配置的问题。类比一下,就好像打包一个包裹,里面包含了应用程序和它需要的各种工具、库等等,这个包裹可以在不同的地方被运输和打开,而不需要在每个地方重新装一遍工具和库。这样,Docker可以使我们的应用程序更加容易部署、更加可移植,并且可以提高开发效率。

而DockerHub则是一个公共官方的包裹存储库,也是我们使用docker pull命令时默认的下载仓库。在这个存储库中,有官方或个人所上传的不同版本,不同架构的镜像。本次我们介绍的则是,如何在DockerHub网站下载官方arm架构的镜像。

如何使用Dokcer Hub?
以ubuntu镜像为例,当我们登录hub.docker.com后在搜索框内输入ubuntu。之后便会出来很多以
“镜像名字”/”作者或镜像内容”:”版本”(也许会有版本)
为标题的镜像。当然这只是个命名的方式,也有很多不同于这个格式的镜像。此时第一个标有OFFICIAL(官方)的镜像往往也是我们想找的,因为官方镜像有足够详细的文档、支持不同的版本与架构,可以满足大多数要求。其中当然也不乏有第三方作者制作精良的镜像,它们往往省心省力。

回到正题,进入到ubuntu官方镜像的详情页。我们可以看到映入眼帘的则是他的介绍、版本等。在左上角则是官方提供的下载命令(此命令未指定版本等信息)。

点击Tags选项卡,可以看到这是ubuntu镜像发布过的版本信息。可以进行筛选及搜索。latest标签则为最新版本的镜像,我们也可以看到有多个它所支持的OS(系统)/ARCH(架构)。右侧则有下载此版本镜像的命令,以及镜像的大小。而左侧则有每个镜像摘要值,这个值是唯一的。

如何在X86_64架构的主机上下载arm架构镜像?
计算机的CPU有不同的品牌如intel、amd等这些耳熟能详的。它们基本的架构都为X86,这个架构早期有intel制定,后续由amd进行扩展为当今主流的X86_64又名amd64。主流并非唯一,业界一直存在多种 CPU 架构,如arm架构。许多手机的CPU也都是arm64架构以及大名鼎鼎得Mac的M1、M2均是arm64架构。Linux很早就开始支持arm64架构,其社区名为aarch64。 在如今我们的科技被美国制裁。华为自研arm架构的手机及服务器芯片也均已停产,国家要迈向全国产的道路。而当下国产CPU多半使用的均为arm架构,甚至当下都无法获得armv8/v9版本的授权,但是arm架构还是会慢慢的走进大家的视野内的。

前面扯得有点远,所以我们该如何从X86_64架构的主机上下载arm架构的镜像呢?说到这就不得不提镜像是怎么区分CPU架构的了。

镜像命名区分CPU架构
CPU 构架 “规范” 名称

我们可以看到早期或者现在,也有不同架构的镜像添加 CPU 架构名作为镜像命名空间前缀。这样就可以用不同的名字下载不同架构的镜像了。

docker pull amd64/ubuntu:20.04
docker pull arm64v8/ubuntu:20.4
# 其实现在你也能pull到。

这个方法所带来的问题则很多,如CPU 构架 “规范” 名称该怎么命名?为什么x86_64不命名为amd64?arm64不命名为aarch64?

使用 Tag 后缀区分构架

解决方法则是使用 Tag 后缀区分构架,变通办法是不使用命名空间前缀,改为使用镜像名或 Tag 前缀或后缀区分。如:

docker pull ubuntu:20.04-x86_64
docker pull ubuntu:20.04-aarch64

在此情况下,我们可以直接使用docker pull 镜像名:版本@摘要值 的方式进行下载指定的镜像。

如我们要下载armv7版本的ubuntu镜像,可以直接点击左侧的摘要值进入镜像的详细页面。

在镜像名称下方则是我需要的摘要值,它是此镜像的唯一值。再下面我们可以选择不同的版本进行查看。左下方的则是构建此镜像的层,Dockerfile构建过程。而右下方则显示了镜像中包含的软件包,软件是否安全,是否有漏洞等。


现在可以使用当前命令进行下载指定版本的镜像。

docker pull ubuntu:latest@sha256:ad18cfdb19dac67bf0072dacea661a817330e5c955d081f4d09914e743ae5d4a

使用此命令查看镜像支持的架构。

docker inspect ubuntu:latest@sha256:ad18cfdb19dac67bf0072dacea661a817330e5c955d081f4d09914e743ae5d4a
# ---
"Architecture": "arm",
        "Variant": "v7",
        "Os": "linux",
        "Size": 55339361,
        "VirtualSize": 55339361,

清单列表(Manifest List) 支持多构架镜像,进行拉取arm架构镜像
容器社区提出了使用统一的镜像名支持多种 CPU 构架的方案。 2017-09-12 后, docker 使用清单列表 (Manifest List) 功能实现了这一方案。当有了这一功能,我们可以基于一个镜像命名空间。当使用docker pull 进行拉取镜像时,docker会根据当前CPU架构拉取对应的镜像。

docker pull ubuntu:20.04

当我们需要跨CPU架构拉取镜像时,如我是一个X86主机,想要拉取一个arm架构的镜像,除了刚才提到的方法。docker为我们提供了pull命令中的--platform参数,此参数可以明确指定我们需要的镜像。platform 不仅可指定 CPU 构架信息,还可以指定操作系统信息。

前面提到,镜像可以通过镜像命名空间中加入架构名称来区分镜像的架构。但带来的问题则是,不同的人可能命名规范并不相同,难以统一。现在使用清单列表的镜像在向docker镜像中心进行注册时必须按照其规范进行命名。但 platform 参数使用任意一个惯用名均可。如其注册名为arm/v7 ,而在使用platfrom参数时,指定为arm即可。

多架构与单架构拉取的镜像为同一个。
# 拉取 amd64 命名空间下的单架构镜像
docker image pull amd64/ubuntu:20.0
# 拉取多架构镜像在 x86_64 构架下的镜像
docker image pull --platform x86_64 ubuntu:20.04

创建多构架镜像
docker 使用清单列表 (Manifest List) 支持多构架镜像。

什么是清单?

将一个 docker 镜像推送到镜像注册中心后,镜像注册中心会记录镜像的存储信息,称为镜像清单 (Image Manifest) 。而清单列表则记录了多个镜像清单及其对应的平台 platform 信息。所谓多构架镜像,或多平台镜像,就是清单列表及其关联的多个单构架镜像。

创建多构架 (多平台) 镜像的操作步骤为:

创建多个单构架镜像。
将所有镜像推送到镜像注册中心,自动生成镜像清单。
汇总多个镜像清单得到清单列表,同样将清单列表推送 (存储) 到镜像注册中心上。新版本 docker 可使用 docker manifest 命令创建和推送清单列表。
Linux 支持交叉构建,即在一套环境下构建多种 CPU 构架下的镜像。为了简单起见,暂不讨论这种方案,暂采用在多个构架环境下创建各自的原生镜像的办法。

这里以创建多架构镜像 test/ubuntu:20.04 为例,介绍创建 docker 多构架镜像的实践操作步骤。

基于官方多架构镜像 ubuntu:20.04 编写 Dockerfile 。

在 x86_64 机器上构建原生镜像,推送到镜像注册中心。 docker build --pull 表示每次构建前自动拉取最新的基础镜像,基础镜像是多架构镜像 (清单列表) 时,自动更新到当前架构的最新镜像。

docker build --pull -t test/ubuntu:20.04-x86_64 .
docker push test/ubuntu:20.04-x86_64

同样,在 arm64 机器上构建原生镜像,推送到镜像注册中心。

docker build --pull -t test/ubuntu:20.04-aarch64 .
docker push test/ubuntu:20.04-aarch64

使用推送到镜像注册中心的多个镜像创建清单列表。注意,前面为每个单架构镜像添加了不同的 Tag 后缀,以方便区分引用。将清单列表推送到镜像注册中心,删除本地副本 (清单列表只有存储在镜像注册中心上才有意义) 。

docker manifest create test/ubuntu:20.04 hanyong/ubuntu:20.04-x86_64 hanyong/ubuntu:20.04-aarch64
docker manifest push test/ubuntu:20.04
docker manifest rm test/ubuntu:20.04

扩展:
docker pull 镜像存储位置在哪?

查看docker镜像默认存储位置:

根据 Docker Root Dir: /var/lib/docker显示/var/lib/docker为默认存储位置。

docker info
#---
Kernel Version: 5.4.0-26-generic
 Operating System: Ubuntu 20.04 LTS
 OSType: linux
 Architecture: x86_64
 CPUs: 4
 Total Memory: 7.748GiB
 Name: weijishu
 ID: LINI:YJJ3:WDYH:CFFN:5DBN:WM52:B57J:E6IP:VF7D:NLCV:XJR2:GF62
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/

总结
本文介绍了如何在x86_64架构的主机上下载arm架构的镜像。镜像可以通过镜像命名空间中加入架构名称来区分镜像的架构,也可以使用Tag后缀区分构架。此外,docker使用清单列表支持多构架镜像,可以使用–platform参数指定需要的镜像。本文还介绍了如何创建多构架镜像。