我们是否可以有一个多级Dockerfile,其中来自的图像可能属于不同的linux操作系统发行版

我们是否可以有一个多级Dockerfile,其中来自的图像可能属于不同的linux操作系统发行版,linux,docker,docker-multi-stage-build,Linux,Docker,Docker Multi Stage Build,是否可以使用多级Dockerfile,其中第一个基本映像属于Ubuntu,第二个属于Alpine。我知道,使用此Dockerfile生成的最终映像无法在Ubuntu平台上执行,因为它还包含Alpine指令,如果在Alpine上执行,也是如此。但我仍想确认情况是否如此 例如,下面是我的示例Dockerfile: FROM some-ubuntu-base-image:latest RUN apt-get update && apt-get install -y my-ubunt

是否可以使用多级
Dockerfile
,其中第一个基本映像属于Ubuntu,第二个属于Alpine。我知道,使用此Dockerfile生成的最终映像无法在Ubuntu平台上执行,因为它还包含Alpine指令,如果在Alpine上执行,也是如此。但我仍想确认情况是否如此

例如,下面是我的示例Dockerfile:

FROM some-ubuntu-base-image:latest 

RUN apt-get update && apt-get install -y my-ubuntu-package

FROM some-alpine-base-image:latest

RUN apk add my-alpine-package

............
.............

首先,没有什么可以阻止Alpine映像在Ubuntu docker主机上运行。这些是在同一Linux内核上运行的不同文件系统,共享内核不会影响运行不同分发二进制文件/库的能力

从多阶段部分来看,您可以为每个状态使用您想要的任何图像,它们彼此独立。多阶段不是合并映像的方法,在第二阶段开始时(除非该阶段来自第一阶段输出),您在该第二阶段的文件系统中没有来自第一阶段的任何内容


您将遇到的问题是,如果在文件系统中依赖于其他文件(例如库)的阶段之间复制文件。最常见的问题是试图在使用musl的Alpine系统上运行针对libc编译的二进制文件。

是的,确实如此。但是,这可能会导致问题:如果使用动态链接,则复制的可执行文件可能需要一个库的版本,该版本在创建该库的阶段可用,但在最终映像的分发时不可用。然而,对于静态编译的语言/程序(如Go),这并不是一个大问题,因为它们基本上将使用的库捆绑到可执行文件中


如果可以,你应该避免这样做。除特定情况外,这是一种不兼容风险,没有太大价值。

是的,确实如此。事实上,官方使用了golang(基于debian)和alpine。你关于不能在多个平台上运行二进制文件的断言也是不正确的。但这怎么可能呢?我的意思是,从构建的角度来看,它不起作用,因为如果你在顶部声明一个ubuntu基础映像,然后运行两个apt get for dependencies,然后从一些alpine映像中下载你使用的文件,然后使用很少的apk,如果构建在基于ubuntu的服务器上运行,它将无法识别apk。因此,构建将立即失败。现在回到容器执行,如果您将两个不同的基于linux操作系统的映像打包到一个最终映像下,然后将其作为容器运行,那么这将如何工作?最终映像只包括构建的最后一个阶段-所有之前的阶段都不在最终映像中。它们就在那里,所以你可以在它们里面做一些事情,然后只在最终映像中保留它的一小部分——就像编译你的程序而不必在最终映像中保留编译器一样。它确实有效。构建是否“在基于ubuntu的服务器上运行”与
apk
是否在Dockerfile中工作完全无关。谢谢BMitch!但是你如何建立一个像我问题中那样的码头工人形象呢。如果我在像jenkins这样使用ubuntu操作系统的CI平台上运行它,它将无法从一些alpine基础映像中识别在下面声明的apk命令:latest@Ashley我无法在这里重现你的错误。你能提供一个可复制的Dockerfile,其他人可以运行它来生成你看到的错误吗?@Ashley一定要在可复制的Dockerfile中包含错误消息。看起来我看的是错误的。它确实在我的jenkins上构建得很好,基本上是使用一个pod模板和很少的容器来支持构建所需的特定于操作系统的库。因此,上面示例中的dockerfile在ubuntu平台或alpine平台上构建得很好,与您使用的linux平台无关。