1. 开启 Docker 的 experimental 特性
这里先开启 Docker 的 experimental 特性,方便下文使用相关命令。编辑文件 vim ~/.docker/config.json
,增加如下内容:
1
2
3
4
|
{
"experimental": "enabled",
"debug": true
}
|
注意,这里不是 /etc/docker/daemon.json
文件,也不需要重启 Docker 。
2. Docker 镜像
从 Docker 1.10 、 Registry 2.3 开始,Docker 引入了 manifest 用于描述镜像的元数据。
2.1 Dockerfile 如何转换成镜像
如上图,Dockerfile 中的每行命令,在构建镜像时都会关联一个 layer 。layer 是对镜像层的简单包装。这些镜像层在存储时,会得到复用,也就是说多个镜像使用到一个镜像层时,仅存储一份。这里面还有一些概念上的细节,可以暂时忽略。
2.2 Docker 与 Registry 如何传输镜像
镜像的元数据信息包括 size 、digest、layers 等信息。Docker 与 Registry 推拉镜像时,首先会传输 manifest 信息,仅当镜像层在当前环境中不存在时,才会进行网络传输,否则直接复用本地镜像层。
2.3 manifest 的文件结构
直接查看镜像的 manifest
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
docker manifest inspect jenkins/jnlp-slave
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 12327,
"digest": "sha256:9b5976169d3504ea796a4af75f8648db9a500e8b9351ee19276031108c59f429"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 50382041,
"digest": "sha256:f15005b0235fa8bd31cc6988c4f2758016fe412d696e81aecf73e52be079f19e"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 7812166,
"digest": "sha256:41ebfd3d2fd0de99b1c63aa36a507bf5555481d06e571d84ed84440d30671494"
},
...
]
}
|
通过 manifest.list
这个 mediaType
,可以将多个镜像整合为一个。在不同的 architecture 和 os 条件下,Docker 会自动拉取适配当前环境的镜像。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
docker manifest inspect maven
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 1579,
"digest": "sha256:3c5d1c8795c96b775723cf912b297850feb1fc8f4b98ec2eda4303f3a6277310",
"platform": {
"architecture": "amd64",
"os": "linux"
}
}
]
}
|
3. 常见的几种多架构镜像的组织方式
不同的 OS 和 CPU 能运行的镜像会有差别。OS 层面,主要可以分为 Windows 和 类 Linux 的镜像。CPU 层面,主要有 amd64 、 arm 、ppc64le 、 s390x 等架构的镜像。amd64 也就是 x86-64 ,通常作为默认的架构,不用特意指明 amd64 和 linux 。
3.1 通过 namespace 区分不同架构
格式 namespaces-{ARCH}-{OS}/image:tag
1
|
shaowenchen-amd64/coredns:latest
|
1
|
shaowenchen-arm/coredns:latest
|
3.2 通过 image name 区分不同架构
格式 namespaces/image-{ARCH}-{OS}:tag
1
|
shaowenchen/coredns-amd64:latest
|
1
|
shaowenchen/coredns-arm:latest
|
3.3 通过 tag name 区分不同架构
格式 namespaces/image:tag-{ARCH}-{OS}
1
|
shaowenchen/coredns:latest-amd64
|
1
|
shaowenchen/coredns:latest-arm
|
4. manifest list 管理多架构镜像
manifest list 是一个镜像清单列表,用来存放不同架构的镜像信息。简单点说,就是新建了一个拉取镜像的入口,关联了不同架构的镜像,没有任何新的镜像层生成。
1
2
3
|
docker push shaowenchen/coredns:coredns-amd64
docker push shaowenchen/coredns:coredns-arm
docker push shaowenchen/coredns:coredns-arm64
|
否则,下面的步骤会报错 no such manifest: docker.io/shaowenchen/coredns:coredns-amd64
1
2
3
4
5
6
|
docker manifest create shaowenchen/coredns:latest
shaowenchen/coredns:coredns-amd64
shaowenchen/coredns:coredns-arm
shaowenchen/coredns:coredns-arm64 --amend
Created manifest list docker.io/shaowenchen/coredns:latest
|
1
|
docker manifest annotate shaowenchen/coredns:latest shaowenchen/coredns:coredns-arm --arch arm
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
docker manifest inspect shaowenchen/coredns:latest
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 739,
"digest": "sha256:242d440e3192ffbcecd40e9536891f4d9be46a650363f3a004497c2070f96f5a",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 739,
"digest": "sha256:e9e08bce9d74a48723518a476f67ada25d00ed69dd3719c3fde41b10d390b0d0",
"platform": {
"architecture": "arm",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 739,
"digest": "sha256:969a21696cff473cb4d36854b15118885fd414394d09444cfd111213fabcd982",
"platform": {
"architecture": "amd64",
"os": "linux"
}
}
]
}
|
1
2
3
|
docker manifest push shaowenchen/coredns:latest
sha256:bcdaff4935b922edd8f415323e04d3a77374f5ddabe0a59d649fd0b6be4ad5ef
|
在各种架构下,都可以使用同一条命令,拉取镜像:
1
|
docker pull shaowenchen/coredns:latest
|
这给部署带来了极大的便利,不需要给镜像拼接 architecture 和 os 信息。不同架构下,可以使用同一套部署程序。
5. 参考
- https://docs.docker.com/engine/reference/commandline/manifest/