所有docker映像都需要基本映像吗?

时间:2020-08-19 01:56:52

标签: docker dockerfile

我是docker的新手,试图了解基本映像的概念。为了详细说明我的问题,我想以MySQL为例。我可以在MySQL Dockerfile中看到它使用ubuntu作为基本映像。是否有必要使用linux基本映像?

我的理解是,当我们使用常规操作系统(例如Ubuntu)时,MySQL将使用linux系统调用对持久性存储执行读/写操作。因此,我希望docker中的MySQL会这样做,希望对MySQL所在的Ubuntu映像进行的系统调用将被docker转换为主机内核OS进行的系统调用。我的理解正确吗?

这意味着ubuntu映像没有内核,因此坐在ubuntu映像之上的应用程序认为它在ubuntu上运行,除了对内核主机OS进行系统调用外,这种理解是正确的?

2 个答案:

答案 0 :(得分:2)

Docker镜像并不严格要求基本镜像。

您可以使用FROM从头开始启动Dockerfile。这指示Docker构建不带任何内容的映像作为第一层。

请参阅:https://hub.docker.com/_/scratch

这就是您要在图像中插入所有想要的二进制文件时要做的事情。

如果您查看Ubuntu映像,您将看到它从头开始:

https://github.com/tianon/docker-brew-ubuntu-core/blob/3d44d0b838eeb78c5baee976a4a529976b326878/bionic/Dockerfile

Docker容器基本上只是主机OS上的命名空间和cgroup,它们隔离一组资源。没有单独的内核或系统调用转换。它们是仅在隔离状态下直接在主机内核上运行的进程。

为了说明这一点,可以在运行某些容器的情况下在主机上运行systemd-cgtop。您正在运行的容器将显示在控制组/ docker / YOUR_CONTAINERS_ID下,您可以看到每个容器正在消耗哪些资源,以与运行常规top命令时在控制组中运行的进程相同的方式查看。

之所以可以在几乎可以运行Docker的任何种类的linux上运行几乎任何种类的linux容器的原因是因为内核在各个发行版之间都是兼容的。这就是为什么必须安装Linux vm才能在Windows和Mac中运行Docker的原因。

有关更多详细信息,请参见:https://superuser.com/questions/889472/docker-containers-have-their-own-kernel-or-not

答案 1 :(得分:1)

在这种情况下,Linux发行版只是一堆文件,并没有要求在Docker映像中具有“发行版”。

让我们采用一个简单的经典C程序:

#include <stdio.h>
int main(int args, char **argv) {
  printf("Hello, world!\n");
  return 0;
}

在典型的Linux系统上,gcc将产生一个ELF二进制文件,该文件说它需要一个库libc.so.6才能运行。当程序调用{​​{1}}时,该实现在该库中;当该库代码最终进行系统调用以写入文件描述符1时,它将被转发到内核。

在Docker中,所有容器都共享主机的内核,但是具有独立的隔离文件系统。因此,只要映像包含二进制文件及其依赖的所有共享库,它通常就不需要Linux发行版本身。 (内核不是映像的一部分,如果您运行的是Ubuntu Docker映像,则不会存在“ Ubuntu内核”;它会使用主机使用的任何内容。)

如果这对您有意义,并且您正在使用可编译为本地二进制文件(C,C ++,Go,Rust)的语言,则通常可以生成静态二进制文件并构建Docker映像printf()包含 only 那个二进制文件(没有“发行版”,没有库,没有shell;请注意不要使用Docker FROM scratch形式,因为它将运行CMD string,而您不会没有/bin/sh -c 'string')。或者,如果您对自己的操作有信心,则可以构建一个映像/bin/sh,其中包含FROM scratch加载程序和所需的共享库,而不是本身的发行版

/lib/ld-linux.so