3.1 什么是容器镜像
Docker 容器镜像是一个标准化包,其中包含用于运行容器的所有文件、二进制文件、库和配置文件。它有两个重要原则:
- 镜像是不可变的,创建镜像后就无法修改,我们只能创建新镜像或在其上添加修改
- 容器镜像由层(layer)组成。每个层表示一组文件系统更改,比如添加、删除或修改文件
- 2013 年:Docker V1 镜像, Docker 早期使用的格式,它使用一个 JSON 文件来描述镜像的内容和元数据,没有正式的规范定义,主要依赖于 Docker 自身实现。
- 2014 年:Docker V2 镜像,为了解决早期格式的缺陷,Docker 推出了 V2 镜像格式,它使用一个 Manifest 文件来描述镜像的内容和元数据,Docker V2 镜像还引入了分层镜像的概念,允许镜像共享底层层,从而节省存储空间。使用 Docker 存储镜像时常用的镜像格式,只支持存储单架构镜像。
- 2015 年:OCI 镜像,为了推动容器技术的标准化,Linux 基金会发起了 Open Container Initiative (OCI) 项目,旨在制定容器镜像和运行时的开放标准,OCI 镜像格式提供了一个标准化的容器镜像格式,使用一个 Index 文件来描述镜像的内容和元数据。使用 Podman 或者 Containerd 存储镜像时常用的格式,可支持存储多架构镜像。
除此之外还有过渡时期的 V2S1 镜像,不过已经和 V1 镜像一起废弃掉了。
目前来说,最广泛使用的还是 Dcoker V2 镜像(即 V2S2 镜像),它可以与 OCI 镜像相互转换。
而关于单机构与多架构镜像,简单来讲,单机构镜像的 JSON 文件记录镜像的所有 layer,而多架构镜像的 JSON 文件则是一个指向不通架构镜像 JSON 文件的索引文件。
下面是容器镜像的配置文件示例。
单架构镜像 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"
}
}
]
}
单架构镜像 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"
}
}
]
}
容器镜像存储在本地时,也需要对应的存储驱动,以下是常见的 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 默认和推荐 |