为什么需要 Docker 多架构(而不是由 Docker 引擎抽象差异)

Raf*_*yng 12 cpu-architecture docker docker-image docker-engine

简洁版本

我想知道为什么需要为多种架构创建 Docker 镜像的技术原因。此外,还不清楚这里的重点是为每个 CPU 架构还是为操作系统创建映像。操作系统不应该抽象架构吗?

长版

我能理解为什么 Docker Engine 必须移植到多种架构。它是一个与操作系统交互、进行系统调用的软件,最终它只是针对特定体系结构表示为特定指令集中的指令序列的代码。因此,Docker 引擎必须移植到多个操作系统/架构,就像必须移植 Microsoft Word 一样。

同样的事情也会发生在 JVM 或 VirtualBox 上。

但是,与 Docker 不同的是,为 Windows 上的 JVM 编写的软件可以在 Linux 上运行。JVM 会抽象底层操作系统/架构的差异,并在两个平台上运行相同的代码。

为什么 Docker 镜像不是这样?为什么 Docker 引擎不能抽象出差异并提供通用接口,这样镜像本身就不需要与特定的操作系统/架构兼容?

这是一个决定(比如“让我们为每个架构制作不同的镜像,因为 X 原因更好”),还是 Docker 工作方式的结果(比如“我们需要这样做,因为 Docker 需要 Y”)?

笔记

  • 我没有哭“天啊,为什么??”。这不是咆哮或批评,我只是在寻找不同架构需要不同图像的技术解释。
  • 我不是问如何创建多架构图像。
  • 我不是在寻找像“需要多架构图像,以便您可以在各种平台上运行图像”这样的答案,它回答“有什么用?”,而不是“为什么需要它?” (这是我的问题)。

除此之外,当你看到一张图片时,它的os/arch摘要中通常会有一个,如下所示:

docker 镜像摘要

图像的具体目标是什么?操作系统、架构,还是两者兼而有之?操作系统不应该抽象底层架构吗?


编辑:我开始假设每个架构需要不同的图像:图像将包含其中的应用程序。假设它将包含 Go 编译器。Go编译器本身是一个二进制文件,必须已编译到不同的架构。的镜像x86-64将包含编译为 的 Go 编译器x86-64,等等。它是否正确?如果这是正确的,这是唯一的原因吗?

Pet*_*des 1

为什么 Docker 引擎不能抽象出差异并提供一个通用的接口

性能将是一个主要因素。通过模拟一些不直接映射到 Windows API 的 POSIX 事物,考虑在 Windows 之上提供 POSIX API 时 Cygwin 对于某些事物的速度有多慢。(例如fork()/exec单独执行,而不是CreateProcess)。

这只是兼容性;生成的二进制文件特定于 Windows 上的 Cygwin。如果您想在运行时执行此操作(二进制兼容而不是源兼容),那就更糟糕了。


Docker 还需要在各种操作系统之上提供高效的可移植 JIT 编译虚拟机,尤其是跨各种 CPU ISA(例如 x86-64 与 AArch64),甚至不共享通用机器代码。

如果 Docker 走了这条路,它实际上只是重新发明了一个基于 JVM 或 .NET CLR 字节码的虚拟机。

或者更有可能的是,它不会重新发明轮子,而是只使用现有的虚拟机并在其上添加映像管理。但它无法与用 C 编写的本机程序一起工作,除非将它们转换为 Java 或 CLR 字节码。