什么是Docker的"scratch"镜像?

55

我是docker的新手,正在尝试文档中的第一个hello world示例。据我所知,hello-world镜像基于scratch镜像。请问有人可以解释一下scratch镜像的工作原理吗?据我所知,它基本上是空白的。那么在hello-world镜像中如何执行二进制文件呢?


簡單來說,Scratch圖像不包含任何內容,完全是零位元組。 - Joe.wang
3个回答

60

scratch 镜像是 Docker 中最基本的镜像。所有其他镜像都是以此为基础祖先。实际上,scratch 镜像是空的,不包含任何文件夹或文件...

scratch 镜像主要用于构建其他基础镜像。例如,debian 镜像就是从 scratch 构建而来的:

FROM scratch
ADD rootfs.tar.xz /
CMD ["bash"]

rootfs.tar.xz文件包含了所有的文件系统文件。Debian镜像将文件系统文件夹添加到空白的scratch镜像中。

我理解scratch镜像是基本上是空白的,那么hello-world镜像是如何执行二进制文件的呢?

scratch镜像是空白的。实际上,添加到scratch镜像中的hello-world可执行文件是静态编译的,这意味着它是自包含的,不需要任何额外的库来执行。

正如Docker官方文档所述:

假设您从Docker GitHub示例C源代码构建了“hello”可执行文件示例,并使用-static标志进行了编译,则可以使用以下命令构建此Docker镜像:docker build --tag hello

这确认了hello-world可执行文件是静态编译的。有关静态编译的更多信息,请阅读这里


11
对于C程序员的注释,“……这意味着它是自包含的,不需要任何额外的库”,这意味着甚至没有glibc,因此没有printf。你只能使用系统调用。如果你想知道为什么hello.c 使用了syscall,那么这篇文章会更详细地介绍。 - jrh
如果“草稿图像为空”,那么我们能否完全省略它? - flow2k
刚刚问了问题并得到了答案:https://dev59.com/q7bna4cB1Zd3GeqPhtUp - flow2k

4
有点晚了,但是我想补充一下@yamenk的答案。Scratch并不是技术上的图像,而只是一个引用。构建容器镜像的方式是利用底层内核仅提供存在于内核中的工具和系统调用。因为在Linux中一切都是文件,所以您可以将任何独立的二进制文件或整个操作系统作为文件添加到此文件系统中。这意味着从Scratch创建镜像时,技术上是指主机系统的内核以及加载在其上的所有文件。这就是为什么从Scratch构建也是no-op操作,当添加单个二进制文件时,镜像的大小仅为该二进制文件的大小加上一些开销。在容器中执行镜像时可以分配的资源是通过利用cgroups功能实现的,网络使用Linux网络命名空间技术。

0
简而言之,官方的scratch镜像是空的,没有任何字节。但是容器实例并不像容器镜像那样为空。即使scratch镜像是空的,当类似runC这样的容器从一个由scratch构建的镜像中运行一个实例时,它需要比在dockfile中看到的更多的东西(如rootfs等)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接