Docker镜像/容器里面有什么?

28
考虑到Docker镜像/容器存在各种不同的版本,如Ubuntu、CentOS、CoreOS等,我很好奇一个镜像/容器实际上由什么组成,以及它与主机操作系统共享什么?哪里是分界线?
例如,我可以下载基础的Ubuntu镜像并在CentOS主机上运行它。接着,当我查看Ubuntu容器内部时,我可以看到它看起来和感觉就像Ubuntu服务器(文件系统布局等)。但是如果我运行uname命令,我会看到内核和类似于CentOS主机的东西...
显然,我知道所有容器都共享底层内核。但是除此之外,还有什么是与主机操作系统共享的,又有什么是属于镜像/容器的呢?
例如,内核是主机的一部分,文件系统布局是镜像/容器的一部分... 是否有规范定义这个问题呢?
2个回答

39

区分镜像容器文档)可能会有所帮助。 镜像是静态的,仅存在于磁盘上。 容器镜像的运行实例,它包括自己的进程树以及RAM和其他运行时资源。

镜像是由图层和关于创建容器时如何组装这些图层的元数据逻辑分组的。其中一部分元数据是每个图层都知道其父ID。

那么,图层中包含什么? 存储在父级中添加的文件(和目录)。 还有特殊文件(“whiteout”),表示从父级中删除了某些东西。

当您通过docker run命令运行镜像时,docker创建一个容器:按正确顺序解压缩所有图层,创建与主机分离的新“root”文件系统。 docker也会读取镜像元数据,并启动在创建镜像时指定的“entrypoint”或“command”,以启动一个新的进程子树。从容器内部看,第一个进程似乎是树的根,但从主机上可以看到它是进程的子树。

根文件系统是使一个Linux发行版与另一个不同的关键所在(也可能有一些内核模块的差异,以及引导加载程序/启动文件系统的差异,但这些通常对运行中的进程不可见)。 内核与主机共享,并且实际上仍在容器内部管理其通常的职责。 但根文件系统是不同的,因此当您在容器内部时,它看起来和感觉像Docker图像中的任何发行版。

容器不仅有自己的文件系统和进程树,还有自己的逻辑网络接口以及可选的RAM和CPU时间分配。作为操作者,您可以控制容器,决定是否与主机共享网络接口,给予无限制的RAM和CPU访问权限,甚至将设备、文件和目录从主机挂载到容器中。默认情况下是保持隔离的,但您可以根据需要打破隔离模型。


谢谢,这非常有帮助。我之前对于图像是什么以及它与主机操作系统的关系感到很困惑。网站上的文档似乎没有很好地解释这一点,但是你在这里的回答解决了我的问题。 - Perishable Dave

6

Docker是对LXC Linux容器的封装,相关文档会详细说明共享和非共享的内容。

一般来说,主机机器可以从文件系统到进程等方面看到/包含容器中的所有内容。您可以在主机vm上发出ps命令并查看容器内的进程。

请记住,Docker容器不是虚拟机-因此一切都实际上在主机上本地运行,并直接使用主机内核。每个容器都有自己的用户名称空间(类似于旧版的根牢房)。有工具/功能可确保容器仅查看其自己的进程,将其自己的文件系统分层到主机文件系统上,并将网络堆栈管道传输到主机网络堆栈。


因此,容器特定的内容是通过内核命名空间实现的?所以,像每个容器都有自己的pid命名空间、mnt命名空间、net命名空间.....?其他所有内容都与主机共享吗? - Nigel Poulton
确切地说,有一些方法可以调整容器,您可以直接使用主机堆栈,但除此之外,所有内容都是命名空间。 - Usman Ismail
5
自三月份起,Docker 默认情况下不再依赖于 LXC。 - icecrime
那么这将是我的下一个问题。我知道docker的默认执行驱动程序现在是libcontainer(而不是LXC)... 我相信Usman也知道。但是LXC文档是否仍然提供了一个良好的地方来查找底层细节呢? - Nigel Poulton
2
此外,libcontainer 包装了现有的 Linux 容器 API,特别是 cgroupsnamespaces。cgroups 提供资源级别的隔离:CPU、内存、块 I/O、网络。namespaces 提供内核级别的隔离:进程、网络、用户 ID、文件系统。更多信息请参考这里 - Howard Lee
各位,这些评论今天还有多少相关性呢?也许有很大的变化,是时候给出新的答案了吗? - Nakilon

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