Docker镜像
Varsion

Docker镜像

Docker镜像 (image) 由多个层组成,每层叠加之后,在外部看来就像是一个完整的独立的对象。镜像内部是一个精简的操作系统 (OS) ,同时还包含应用运行所必须的文件和一些依赖包。

镜像就像停止运行的容器(类)。实际上,可以停止某个容器的运行,并从中创建新的镜像。

镜像与容器

从顶层设计层面来讲,一旦容器从镜像启动之后,二者之间就变成了一种相互依赖的关系,在由该镜像启动的容器全部停止之前,该镜像是无法被删除的。

容器的目的就是运行应用或者服务,这意味着容器的镜像中必须包含应用/服务运行所必需的操作系统和应用文件。但是,容器又追求快速和小巧,这意味着构建镜像的时候通常需要裁剪掉不不掉的部分,保持较小的体积。

镜像与分层

Docker 镜像由一些 松耦合 的只读镜像层组成:

Docker镜像

Docker 负责堆叠这些镜像层,并且将它们表示为单个统一的对象。

查看镜像分层的方式可以通过该命令展示

1
docker image inspect image-name

通过 Ubuntu:14.0 镜像演示,提取了输出中的关于镜像层的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
{
///
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:f2fa9f4cf8fd0a521d40e34492b522cee3f35004047e617c75fadeb8bfd1e6b7",
"sha256:45d8dc025525eb83384fbb6f3d49bac2e85f690a17f7fc9ab4d013e7236703bd",
"sha256:e156c976a2ba450a30da0df824a204113c6afcf773cb09bfa186f88cd63f19dd"
]
},
///
}
]

所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新内容的时候,就会在当前镜像层之上,创建新的镜像层

添加额外的镜像层后的镜像

当某个文件被删除或者被替换掉,镜像内部就会类似为这样

三层镜像

这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。

Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs、ZFS。顾名思义,每种存储引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。

Docker 在 Windows 上仅支持 windowsfilter 一种存储引擎,该引擎基于 NTFS 文件系统之上实现了分层和 CoW。

从系统的角度看三层镜像:

从系统角度看三层镜像

共享镜像层

​ 多个镜像之间可以共享镜像层(的确也会这样做),这样可以有效节省空间并提升性能。

​ 当 Docker 拉取同一个镜像的不同版本的时候,Docker 会注意到这些不同版本的镜像层之间由部分是十分相同或者说是一样的,就会共享这些镜像层。

如前所述,Docker 在 Linux 上支持很多存储引擎(Snapshotter)。每个存储引擎都有自己的镜像分层、镜像层共享以及写时复制(CoW)技术的具体实现。

​ 但是,其最终效果和用户体验是完全一致的。尽管 Windows 只支持一种存储引擎,还是可以提供与 Linux 相同的功能体验。

多层架构镜像

​ 多层架构镜像(Multi-architecture Image)的出现解决了镜像有可能因为当前运行环境的架构不匹配

​ Docker(镜像和镜像仓库服务)规范目前支持多架构镜像,这意味着某个镜像仓库标签(repository:tag)下的镜像同时支持多种架构。

​ 简单的来讲,就是一个镜像标签之下可以支持多个平台和架构

​ 为了实现这个特性,镜像仓库服务 API 支持两种重要的结构:Manifest 列表(新)和 Manifest

Manifest 列表是指某个镜像标签支持的架构列表。其支持的每种架构,都有自己的 Mainfest 定义,其中列举了该镜像的构成。

​ 假设要在 Raspberry Pi(基于 ARM 架构的 Linux)上运行 Docker。在拉取镜像的时候,Docker 客户端会调用 Docker Hub 镜像仓库服务相应的 API 完成拉取。

​ 如果该镜像有 Mainfest 列表,并且存在 Linux on ARM 这一项,则 Docker Client 就会找到 ARM 架构对应的 Mainfest 并解析出组成该镜像的镜像层加密 ID。然后从 Docker Hub 二进制存储中拉取每个镜像层。

​ 所有官方镜像都支持 Manifest 列表。但是,全面支持各种架构的工作仍在推进当中。

​ 创建支持多架构的镜像需要镜像的发布者做更多的工作。同时,某些软件也并非跨平台的。在这个前提下,Manifest 列表是可选的——在没有 Manifest 列表的情况下,镜像仓库服务会返回普通的 Manifest

  • Post title:Docker镜像
  • Post author:Varsion
  • Create time:2021-01-24 17:14:20
  • Post link:https://blog.varsion.cn/post/913d1c8d.html
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
Comments