Atlantis
GitHub Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

3.1 什么是容器镜像

1. 基础中的基础

Docker 容器镜像是一个标准化包,其中包含用于运行容器的所有文件、二进制文件、库和配置文件。它有两个重要原则:

  1. 镜像是不可变的,创建镜像后就无法修改,我们只能创建新镜像或在其上添加修改
  2. 容器镜像由层(layer)组成。每个层表示一组文件系统更改,比如添加、删除或修改文件

2. 镜像格式变更历史

alt text

  1. 2013 年:Docker V1 镜像, Docker 早期使用的格式,它使用一个 JSON 文件来描述镜像的内容和元数据,没有正式的规范定义,主要依赖于 Docker 自身实现。
  2. 2014 年:Docker V2 镜像,为了解决早期格式的缺陷,Docker 推出了 V2 镜像格式,它使用一个 Manifest 文件来描述镜像的内容和元数据,Docker V2 镜像还引入了分层镜像的概念,允许镜像共享底层层,从而节省存储空间。使用 Docker 存储镜像时常用的镜像格式,只支持存储单架构镜像。
  3. 2015 年:OCI 镜像,为了推动容器技术的标准化,Linux 基金会发起了 Open Container Initiative (OCI) 项目,旨在制定容器镜像和运行时的开放标准,OCI 镜像格式提供了一个标准化的容器镜像格式,使用一个 Index 文件来描述镜像的内容和元数据。使用 Podman 或者 Containerd 存储镜像时常用的格式,可支持存储多架构镜像。

除此之外还有过渡时期的 V2S1 镜像,不过已经和 V1 镜像一起废弃掉了。

目前来说,最广泛使用的还是 Dcoker V2 镜像(即 V2S2 镜像),它可以与 OCI 镜像相互转换。

而关于单机构与多架构镜像,简单来讲,单机构镜像的 JSON 文件记录镜像的所有 layer,而多架构镜像的 JSON 文件则是一个指向不通架构镜像 JSON 文件的索引文件。

下面是容器镜像的配置文件示例。

2.1 docker image v2s2

单架构镜像 mediaType:application/vnd.docker.distribution.manifest.v2+json

{
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "schemaVersion": 2,
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "digest": "sha256:75998344564a3a1caf58c505a5eb2a17d503a42fd1b15a293363606caa000dff",
      "size": 2337
   },
   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "digest": "sha256:a1d0c75327776413fa0db9ed3adcdbadedc95a662eb1d360dad82bb913f8a1d1",
         "size": 83518086
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "digest": "sha256:212e715ac508161704c0019aa708bce93a3b8891c711495d08ab4bfb464994e7",
         "size": 314
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "digest": "sha256:d26e1fffa6d4080baffa7417ad1203f0e061f0dff7d369e941c8b39b173afd9a",
         "size": 382
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "digest": "sha256:33d5ad432634ff3e2d9baf4142fe4dae1a6a84a03196766644886e8629071f23",
         "size": 5780666
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "digest": "sha256:c682cd36129013cb229093216fdb073c21d464c4e1b9050abbe5ab213aa9b43d",
         "size": 612
      }
   ]
}

多架构镜像 mediaType:application/vnd.docker.distribution.manifest.list.v2+json

{
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "schemaVersion": 2,
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "digest": "sha256:34dac0b2740e6db39e36475ec1ec5e0003a180efb297a10fd21afd06215aa1ad",
         "size": 1361,
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "digest": "sha256:e0283088329195882098141a65691fe9986d8aca402e01f1ac57b4d4b03a455a",
         "size": 1361,
         "platform": {
            "architecture": "arm64",
            "os": "linux"
         }
      }
   ]
}

2.2 oci image

单架构镜像 mediaType:application/vnd.oci.image.manifest.v1+json

{
    "schemaVersion": 2,
    "mediaType": "application/vnd.oci.image.manifest.v1+json",
    "config": {
        "mediaType": "application/vnd.oci.image.config.v1+json",
        "digest": "sha256:274cb4311a4dc9d6eea256fa218e794261b7616e0e5066dcddb8bb88bc9061f7",
        "size": 2303
    },
    "layers": [
        {
            "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
            "digest": "sha256:a1d0c75327776413fa0db9ed3adcdbadedc95a662eb1d360dad82bb913f8a1d1",
            "size": 83518086
        },
        {
            "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
            "digest": "sha256:212e715ac508161704c0019aa708bce93a3b8891c711495d08ab4bfb464994e7",
            "size": 314
        },
        {
            "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
            "digest": "sha256:d26e1fffa6d4080baffa7417ad1203f0e061f0dff7d369e941c8b39b173afd9a",
            "size": 382
        },
        {
            "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
            "digest": "sha256:33d5ad432634ff3e2d9baf4142fe4dae1a6a84a03196766644886e8629071f23",
            "size": 5780666
        },
        {
            "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
            "digest": "sha256:c682cd36129013cb229093216fdb073c21d464c4e1b9050abbe5ab213aa9b43d",
            "size": 612
        }
    ]
}

多架构镜像 mediaType:application/vnd.oci.image.index.v1+json

{
    "schemaVersion": 2,
    "mediaType": "application/vnd.oci.image.index.v1+json",
    "manifests": [
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:4179e0db7990e3413dba49b8aa4d3eb8dafdea27eded45b71bf0464011c10a19",
            "size": 1027,
            "platform": {
                "architecture": "amd64",
                "os": "linux"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:fcab338e0277b95e6396e8f6e8d8312e73f8889a0acb23a7b3a45e319e58adef",
            "size": 1027,
            "platform": {
                "architecture": "arm64",
                "os": "linux"
            }
        }
    ]
}

3. 存储驱动变更历史

容器镜像存储在本地时,也需要对应的存储驱动,以下是常见的 storage driver 整合到 Docker 中的大致时间点:

Storage Driver 整合时间 备注
AUFS 2013 年 Docker 早期版本默认,但从未被 Linux 内核主线合并
Device Mapper 2014 年 早期版本可选,Red Hat 系 Linux 发行版常用
ZFS 2014 年 较早版本可选,Solaris 和 FreeBSD 等操作系统常用
Btrfs 2015 年 较早版本可选,拥有很多高级特性
OverlayFS 2016 年 Docker 1.12 版本开始成为主流,目前 Docker 默认和推荐

4. 参考资料

  1. 深入浅出容器镜像的一生
  2. K8S 1.20 弃用 Docker 评估之 Docker 和 OCI 镜像格式的差别
  3. OCI Image Spec 镜像格式规范