Docker: 基础镜像

10

我正在尝试理解Docker的概念,但有一件事我无法理解:

据我所知,镜像(因此也是容器)可以从不同的Linux发行版中实例化,例如Ubuntu、CentOS等。

假设在主机上运行标准的Ubuntu 14.04,

  • 如果我使用的容器不是从同一个发行版实例化而来会发生什么情况?
    • 不是14.04版本的?
    • 不是Ubuntu(或任何其他基于Debian的)吗?
    • 使用不同的基础镜像有什么缺点吗? (假设我使用以Ubuntu为基础镜像的Image A,使用Debian作为基础镜像的Image B和使用CentOS作为基础镜像的Image C)?

奖励问题:如果开发人员没有在Docker Hub描述中指定基础镜像,我如何确定使用了哪个基础镜像?

提前感谢您!

3个回答

9

Docker自Docker 0.9版本起不再使用LXC,而是采用内置的执行驱动程序libcontainer(现在被称为runc),通过操作命名空间、控制组、权限、apparmor配置文件、网络接口和防火墙规则等方式以一致且可预测的方式运行,无需依赖LXC或任何其他用户空间软件包。

Docker镜像代表一组文件,将作为容器在其自己的内存、磁盘和用户空间中运行,同时访问主机内核。
这与虚拟机不同,虚拟机不访问主机内核,但通过其虚拟化管理程序包含自己的硬件/软件堆栈。
容器只需在主机上设置限制(磁盘、内存、CPU)。而实际的虚拟机必须构建一个全新的主机。

该Docker镜像(文件组)可以是任何内容,只要满足以下条件:

这意味着一个镜像可以是任何东西:另一个 Linux 发行版,甚至是单个可执行文件。例如,任何使用 go 编译的可执行文件(https://golang.org/)都可以打包在自己的 Docker 镜像中,而不需要任何 Linux 发行版:

FROM scratch
COPY my_go_exe /
ENTRYPOINT /my_go_exe

scratch 是一个“空”镜像,而Go可执行文件是静态链接的,因此它是自包含的,并且仅依赖于对内核的系统调用。


谢谢您的答复,现在清楚多了!那么,为什么人们一直说最好从同一个基本图像实例化所有图像呢?Chris Pitman在这个线程中给出了相当合理的答案,您是否同意他所说的? - SmxCde
1
只要你的内核足够“新”(3.14或更高版本),基础镜像就不会有影响。从相同的基础镜像开始只有助于在主机上不占用太多空间 /var/lib/docker/images,但除此之外,你可以使用任意数量的基础镜像。(带有Chris关于安全性的警告) - VonC

6
主机操作系统和Docker容器之间共享的主要内容是内核。从不同的发行版/版本运行Docker容器的主要风险在于它们可能依赖于主机系统上不存在的内核功能,例如,如果容器期望比主机安装的内核更新的内核,则会出现问题。
理论上,Linux内核是向后兼容的。只要主机内核比容器内核新,它应该可以工作。
从操作角度来看,每次您开始依赖于不同的基本映像,这是需要监视更新和安全问题的另一个依赖项。标准化一个发行版可减轻您的运营团队在下一个重大漏洞被发现时的工作量。

1

Docker使用LXC,这是一种操作系统级别的虚拟化方法,可以在控制主机上使用单个Linux内核运行多个隔离的Linux系统(容器)。

您可以将其与计算机上的VM进行比较,在其中启动另一个Linux发行版,它不必与主机操作系统相同。因此,如果您的主机操作系统与容器的基础映像相同,则没有任何影响。

在Docker中,容器是由层构建的。 Dockerfile中的每个步骤(命令)表示一个层,这些层依次应用。第一步是应用基本操作系统层,该层由FROM指示。

因此,为了回答您的奖励问题,您可以查看所使用的容器的Dockerfile(这是DockerHub上的第三个选项卡),并在第一个语句中查看基础映像(操作系统)。


谢谢你的回答!但是到目前为止,你所说的对我来说有点混淆。自从我开始学习Docker以来,我看到他们将自己定位为不是VM的软件,例如看看这张图片:http://i.imgur.com/MJHfm1c.jpg,而你说它是某种在操作系统层面上的VM或类似于它。我知道我的问题可能很傻,但我不是运维或任何类型的Linux人员,所以对此感到抱歉;) - SmxCde
也许如果您能够解释真正的虚拟机和Docker与LXC的区别,或者使用相同的发行版作为主机机器,以及为所有Docker容器使用相同的基础镜像的优点,那对我来说会更清晰一些。据我所知,这是推荐的做法...谢谢! - SmxCde

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