多平台Docker镜像构建教程

简介: Adrian Mouat被誉为Docker Captain,他是Container Solutions 公司的首席科学家。目前,他正开发 Trow,这是一个容器镜像注册中心,用于安全管理 Kubernetes 集群中的镜像流。

云栖号资讯:【点击查看更多行业资讯
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!

22CA1FAD_6919_451d_B8DF_7E925147EA9D

Adrian Mouat被誉为Docker Captain,他是Container Solutions 公司的首席科学家。目前,他正开发 Trow,这是一个容器镜像注册中心,用于安全管理 Kubernetes 集群中的镜像流。

当前,Docker 镜像已经成为测试和部署新的第三方软件的标准工具。Adrian 是开源 Trow 注册中心的主要开发者,而Docker 镜像则是人们安装该工具的主要方式。如果他不提供镜像,其他人最终也会推出他们自己的镜像,这样会导致重复"造轮子”,并产生维护问题。

默认情况下,我们创建的Docker 镜像运行在 linux/amd64 平台上。它适用于大多数的开发机器和云提供商,但却忽略其他平台的用户。这个群体很庞大——想想基于树莓派的家庭实验室、生产物联网设备的公司、运行在 IBM 大型机上的组织以及使用低功耗 arm64 芯片的云。

一般来说,这些平台的用户通常会构建自己的镜像或寻找其他解决方案。

那么,你该如何为这些平台构建镜像?最明显的方法是在目标平台上构建镜像。这适用于很多情况。但是如果你的目标是 s390x,我希望你有可以使用的 IBM 大型机。更常见的平台,比如树莓派、物联网设备通常电量有限,速度慢或无法构建镜像。

我们该怎么做?有两个选项:1. 目标平台仿真,2. 交叉编译。有趣的是,我发现有种方法可以将这两个选项结合的效果最好。

1.仿真

让我们从第一个选项——仿真开始。有一个很不错的项目叫 QEMU,它可以模拟很多平台。随着最近 buildx 的预览,将 QEMU 用于 Docker 变得更加容易。

https://www.qemu.org/

https://github.com/docker/buildx

QEMU 集成依赖于一个 Linux 内核特性,该特性有个稍显神秘的名字 binfmt_misc handler。当 Linux 遇到其无法识别的可执行文件格式(例如,一个用于不同体系结构的文件格式)时,它将使用该处理程序检查是否配置了什么“用户空间应用程序”来处理该格式(例如,模拟器或 VM)。如果有,它将把可执行文件传递给该应用程序。

为实现这一点,我们需要在内核中注册我们关注的平台。如果你正在使用 Docker Desktop,那么对于大多数常见平台,你就无需做这项工作。如果你正使用 Linux,你可以通过运行最新的docker/binfmt镜像,以与 Docker Desktop 相同的方式注册处理程序,例如:

docker run --privileged --rm docker/binfmt:a7996909642ee92942dcd6cff44b9b95f08dad64

完成此操作后,你可能需要重启 Docker。如果你想要对自己想注册的平台有更多控制或想使用更高深莫测的平台(例如 PowerPC),请查看 qus 项目。

https://github.com/dbhi/qus

Buildx 有两种不同的用法,但最简单的方法可能是在 Docker CLI 上启用实验性特性(如果你还没有这样做的话),编辑~/.docker/config.json文件,使其包含以下内容:

{
    ...
     "experimental": “enabled”
}

你现在应该能运行docker buildx ls,并得到类似以下的输出:

$ docker buildx ls
NAME/NODE     DRIVER/ENDPOINT             STATUS   PLATFORMS
default       docker                               
  default     default                     running  linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

让我们为另一个平台构建一个镜像,从 Dockerfile 开始:

FROM debian:buster
CMD uname -m

如果我们正常构建,运行以下命令:

$ docker buildx build -t local-build .
…
$ docker run --rm local-build
x86_64

但是,如果我们显式指定构建针对的平台,则执行以下命令:

$ docker buildx build --platform linux/arm/v7 -t arm-build .
…
$ docker run --rm arm-build
armv7l

成功!我们已经成功地在 x86_64 笔记本上构建和运行了 armv7 镜像,并且只做了很少工作。这种技术很有效,但对于更复杂的构建,你可能会发现它运行太慢,或者遇到 QEMU 中的 Bug。在这些情况下,有必要研究一下是否可以交叉编译你的镜像。

2.交叉编译

一些编译器能为 foreign platforms 生成二进制代码,最著名的包括 Go 和 Rust。通过 Trow 注册中心项目,我们发现,交叉编译是为其他平台创建镜像最快、最可靠的方法。例如,这里是 Trow armv7 镜像的 Dockerfile。

https://github.com/ContainerSolutions/trow/blob/master/docker/Dockerfile.armv7

最重要的一行是:

RUN cargo build --target armv7-unknown-linux-gnueabihf -Z unstable-options --out-dir ./out

它明确告诉 Rust,我们希望二进制文件在哪个平台上运行。然后,我们可以使用多级构建将这个二进制文件复制到目标体系结构的基本镜像中(如果是静态编译,也能使用 scratch),这样就完成了。然而,对于 Trow 注册中心,我想在最终的镜像中设置更多东西,所以最后阶段实际上开始于:

FROM --platform=linux/arm/v7 debian:stable-slim

因此,我实际上混合使用了仿真和交叉编译——交叉编译用来创建二进制文件,仿真用来运行和配置最终的镜像。

3.清单列表

在上面关于仿真的建议中,你可能已经注意到:我们使用--platform参数来设置构建平台,但是我们在 FROM 行中将镜像指定为 debian:buster。这看起来似乎没有意义——平台当然依赖于基本镜像以及它是如何构建的,而不是用户之后的决定。

这样做是因为 Docker 使用了一种叫做清单列表的东西。对于给定镜像,这些列表包含指向不同体系结构镜像的指针。因为官方的 debian 镜像有一个定义好的清单列表,当我在笔记本上拉取这个镜像时,我会自动获得 amd64 镜像,当我在树莓派上拉取它时,我将得到 armv7 镜像。

为了让用户满意,我们可以为自己的镜像创建清单。如果我们回到前面的例子,首先我们需要重新构建并将镜像推送到一个镜像库:

$ docker buildx build --platform linux/arm/v7 -t amouat/arch-test:armv7 .
…
$ docker push amouat/arch-test:armv7
…
$ docker buildx build -t amouat/arch-test:amd64 .
…
$ docker push amouat/arch-test:amd64

接下来,我们创建一个清单列表指向这两个单独的镜像,并推送它们:

$ docker manifest create amouat/arch-test:blog amouat/arch-test:amd64 amouat/arch-test:armv7
Created manifest list docker.io/amouat/arch-test:blog
$ docker manifest push amouat/arch-test:blog
sha256:039dd768fc0758fbe82e3296d40b45f71fd69768f21bb9e0da02d0fb28c67648

现在,Docker 将拉取并运行适合当前平台的镜像:

$ docker run amouat/arch-test:blog
Unable to find image 'amouat/arch-test:blog' locally
blog: Pulling from amouat/arch-test
Digest: sha256:039dd768fc0758fbe82e3296d40b45f71fd69768f21bb9e0da02d0fb28c67648
Status: Downloaded newer image for amouat/arch-test:blog
x86_64

有树莓派的读者可以试着运行这个镜像,并确认它确实能在那个平台上工作!回顾一下:并不是 Docker 镜像的所有用户都运行 amd64。使用 buildx 和 QEMU,只需额外少量工作就可以为这些用户提供支持。

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-04-14
本文作者:Adrian Mouat
本文来自:“InfoQ 微信公众号”,了解相关信息可以关注“InfoQ

相关文章
|
1月前
|
存储 运维 安全
构建高效自动化运维体系:Ansible与Docker的完美结合
【2月更文挑战第31天】 随着云计算和微服务架构的兴起,自动化运维成为保障系统稳定性和提升部署效率的关键手段。本文将详细探讨如何通过Ansible和Docker的结合来构建一个高效、可靠且易于管理的自动化运维体系。首先,介绍自动化运维的必要性及其在现代IT基础设施中的作用;然后,分别阐述Ansible和Docker的技术特点及优势;最后,提供一个基于Ansible和Docker结合使用的实践案例,以及实施过程中遇到的挑战和解决方案。
|
1月前
|
运维 Kubernetes 监控
构建高效自动化运维体系:基于Docker和Kubernetes的实践指南
【2月更文挑战第30天】 在当今快速发展的云计算时代,传统的IT运维模式已难以满足业务的敏捷性和稳定性需求。本文深入探讨了如何通过Docker容器化技术和Kubernetes集群管理工具构建一个高效、可靠的自动化运维体系。文章首先概述了容器化技术和微服务架构的基本概念,随后详细阐述了基于Docker的应用打包、部署流程,以及Kubernetes在自动化部署、扩展和管理容器化应用中的关键作用。最后,文中通过案例分析,展示了如何在实际场景中利用这些技术优化运维流程,提高系统的整体效率和可靠性。
|
1月前
|
运维 安全 网络安全
构建高效自动化运维体系:Ansible与Docker的完美融合
【2月更文挑战第30天】在当今快速迭代和持续部署的软件发展环境中,自动化运维成为确保效率和稳定性的关键。本文将探讨如何通过结合Ansible和Docker技术,构建一个高效的自动化运维体系。我们将分析Ansible的配置管理功能和Docker容器化的优势,并展示它们如何协同工作以简化部署流程,增强应用的可移植性,并提供一致性的系统环境。此外,文章还将介绍一些最佳实践,帮助读者在真实环境中实现这一整合方案。
|
2天前
|
运维 前端开发 Devops
云效产品使用报错问题之流水线打包docker镜像时报网络代理有问题如何解决
本合集将整理呈现用户在使用过程中遇到的报错及其对应的解决办法,包括但不限于账户权限设置错误、项目配置不正确、代码提交冲突、构建任务执行失败、测试环境异常、需求流转阻塞等问题。阿里云云效是一站式企业级研发协同和DevOps平台,为企业提供从需求规划、开发、测试、发布到运维、运营的全流程端到端服务和工具支撑,致力于提升企业的研发效能和创新能力。
|
4天前
|
Ubuntu Docker 索引
ubuntu 20.04 安装docker教程和安装中遇到的问题解决方案(超详细 附加图文教程)
ubuntu 20.04 安装docker教程和安装中遇到的问题解决方案(超详细 附加图文教程)
28 0
|
5天前
|
存储 运维 监控
构建高效稳定的Docker容器监控体系
【4月更文挑战第18天】 在现代微服务架构中,Docker容器已成为部署和运行应用的标准环境。随之而来的挑战是如何有效监控这些容器的性能与健康状况,确保系统的稳定性和可靠性。本文将探讨构建一个高效稳定的Docker容器监控体系的关键技术和方法,包括日志管理、性能指标收集以及异常检测机制,旨在为运维人员提供实用的指导和建议。
10 0
|
6天前
|
测试技术 Linux 网络安全
【好玩的开源项目】使用Docker部署SyncTV视频同步和共享平台
【4月更文挑战第16天】使用Docker部署SyncTV视频同步和共享平台
43 1
|
14天前
|
应用服务中间件 Docker 容器
docker 镜像常用命令
docker 镜像常用命令
34 0
|
14天前
|
Linux Shell 虚拟化
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
21 0
|
17天前
|
测试技术 Linux 数据安全/隐私保护
【Docker项目实战】使用Docker部署PicoShare共享文件平台
【4月更文挑战第5天】使用Docker部署PicoShare共享文件平台
49 4