docker本地镜像仓库的管理
启动一个容器需要镜像,根据Dockerfile构建镜像也会下载依赖的镜像,当使用docker pull拉取了外部镜像仓库的镜像时,docker是如何管理本地镜像的数据呢?
我的虚机中docker镜像存储驱动使用的是overlay,/var/lib/docker/image/overlay2/repositories.json,这个文件是一个简单的json文件,数据格式也非常简单,Repositories下面就依次列出了本地已经存在的所有镜像。
merge目录就是经过overlay2挂载以后,容器看到的rootfs的目录结构。
root@iZt4n1u8u50jg1r5n6myn2Z:~# cat /var/lib/docker/image/overlay2/repositories.json | jq
{
"Repositories": {
"alpine": {
"alpine:3.11": "sha256:a787cb9865032e5b5a407ecdf34b57a23a4a076aaa043d71742ddb6726ec9229",
"alpine@sha256:bcae378eacedab83da66079d9366c8f5df542d7ed9ab23bf487e3e1a8481375d": "sha256:a787cb9865032e5b5a407ecdf34b57a23a4a076aaa043d71742ddb6726ec9229"
},
"bitnami/php-fpm": {
"bitnami/php-fpm:latest": "sha256:0d94e6597148af2af2cd8b894256ba21c6acb437f72518f7ce251a3ea85421d3",
"bitnami/php-fpm@sha256:dba2bb41c613c825d2e7fa88fdcd2ec662f90e1c026615c05789a1ed34a17d99": "sha256:0d94e6597148af2af2cd8b894256ba21c6acb437f72518f7ce251a3ea85421d3"
},
"busybox": {
"busybox:latest": "sha256:d23834f29b3875b6759be00a48013ba523c6a89fcbaeaa63607512118a9c4c19",
"busybox@sha256:52817dece4cfe26f581c834d27a8e1bcc82194f914afe6d50afad5a101234ef1": "sha256:d23834f29b3875b6759be00a48013ba523c6a89fcbaeaa63607512118a9c4c19"
},
"calico-node": {
"calico-node:base": "sha256:80a1a6b0a19c0d01d79fbb10ad9c17dd901106fa085958fbb75fcbf8873f08c4"
},
"calico/bird": {
"calico/bird:v0.3.3-182-g4b493986-amd64": "sha256:039b1de045060e8dad02608cc29ba9e1b144bd364fe3521dca5ce98bb2aaef47",
"calico/bird@sha256:f040de1b528e3a7fd59a7c81aa9ca6096cc4ac2564337c2ff3d52dbdf07ca9be": "sha256:039b1de045060e8dad02608cc29ba9e1b144bd364fe3521dca5ce98bb2aaef47"
},
"calico/bpftool": {
"calico/bpftool:v5.3-amd64": "sha256:bc0875ac43440ae8d7361f76d83472e3000231885866c46d2f0d7cb36c9a8368",
"calico/bpftool@sha256:2903c00eef4431140adc4655b10f5645dc1f9cc78c8a20d04682356670a02ba5": "sha256:bc0875ac43440ae8d7361f76d83472e3000231885866c46d2f0d7cb36c9a8368"
},
}
查看镜像的manifest信息
使用docker manifest inspect可以查看镜像的manifest信息,manifest描述了关于镜像存储的一些信息,mediaType表示配置描述的类型。
- config中的mediaType为container.image.v1+json,这个就表示存储镜像的配置信息是一个json类型的文件,sha256中的数字就是镜像的配置文件的id,docker inspect这个id或者使用cat命令输出该文件的内容,这两个是一致的。
- 下面的layers中的mediaType为image.rootfs.diff.tar.gzip,就表示这是镜像中的一层数据,存储格式为tar包。
root@iZt4n1u8u50jg1r5n6myn2Z:~# docker manifest inspect goharbor/harbor-db-base:dev
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 4111,
"digest": "sha256:2ed2ba057d8cabed044c54d36f918ea16673e3a289fa89c7520f57d46d7b3bfd"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 15994577,
"digest": "sha256:cb54d1184a86b82843c849bbd232f27fd0b1b012c8770baea97b5a05244b2f48"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 1080392,
"digest": "sha256:7463ba7e68d03f78269f3f2ae4f6b15cc45d72d6c15989cf0cbdfe8dd625c2d0"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 5665629,
"digest": "sha256:ba06e5eb0d9c49f23d81fa2cdcc91f792ecf3a0c27710bdcf5622cef940897bc"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 62049341,
"digest": "sha256:604a291316d51f6a760b233cb6ce9680cc36cbe464933ff258c7a1bffd9c80af"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 12733349,
"digest": "sha256:e12f21e5718e13baf221587a559b1700dee8957cb39e9ef8906846c0195535a3"
}
]
}
查看镜像的详细配置信息
使用docker inspect命令查看一个镜像的详细配置信息。
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# docker inspect google/cadvisor:v0.33.0
[
{
"Id": "sha256:752d61707eac173cfe56a23aa9de051597444286163667d60f8e6d4c63306472",
"RepoTags": [
"google/cadvisor:v0.33.0"
],
"RepoDigests": [
"google/cadvisor@sha256:47f1f8c02a3acfab77e74e2ec7acc0d475adc180ddff428503a4ce63f3d6061b"
],
"Parent": "",
"Comment": "",
"Created": "2019-02-27T18:40:08.005242894Z",
"Container": "60b721dff23e41eee7d1728fdf0d62deff5c0ee053e29ba5da556b8b4fae93fa",
"ContainerConfig": {
"Hostname": "60b721dff23e",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"8080/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GLIBC_VERSION=2.28-r0"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"ENTRYPOINT [\"/usr/bin/cadvisor\" \"-logtostderr\"]"
],
"Healthcheck": {
"Test": [
"CMD-SHELL",
"curl -f http://localhost:8080/healthz || exit 1"
],
"Interval": 30000000000,
"Timeout": 3000000000
},
"ArgsEscaped": true,
"Image": "sha256:338328de3ca3663d600e94c0a2b3aee1df611f293c858b63d2fa9fa44bd53329",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/usr/bin/cadvisor",
"-logtostderr"
],
"OnBuild": null,
"Labels": {}
},
"DockerVersion": "18.06.2-ce",
"Author": "dengnan@google.com vmarmol@google.com vishnuk@google.com jimmidyson@gmail.com stclair@google.com",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"8080/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GLIBC_VERSION=2.28-r0"
],
"Cmd": null,
"Healthcheck": {
"Test": [
"CMD-SHELL",
"curl -f http://localhost:8080/healthz || exit 1"
],
"Interval": 30000000000,
"Timeout": 3000000000
},
"ArgsEscaped": true,
"Image": "sha256:338328de3ca3663d600e94c0a2b3aee1df611f293c858b63d2fa9fa44bd53329",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/usr/bin/cadvisor",
"-logtostderr"
],
"OnBuild": null,
"Labels": null
},
"Architecture": "amd64",
"Os": "linux",
"Size": 68607708,
"VirtualSize": 68607708,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/1fc34ade9326a48261bfb2f5e3b134cc1db5b9e2f1faf7d5df5049be05d1fbd1/diff:/var/lib/docker/overlay2/5b1f40c8ed48fd43aa47d947d84eda7b80ca866aeb49c485dda326ca8eb76f76/diff",
"MergedDir": "/var/lib/docker/overlay2/8f377f94a7e3ab7c609e4054b414d346416a1f62a3ad9098ff7c0510a82212e9/merged",
"UpperDir": "/var/lib/docker/overlay2/8f377f94a7e3ab7c609e4054b414d346416a1f62a3ad9098ff7c0510a82212e9/diff",
"WorkDir": "/var/lib/docker/overlay2/8f377f94a7e3ab7c609e4054b414d346416a1f62a3ad9098ff7c0510a82212e9/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:767f936afb51c8a3ad9a96592a4be092048bb70f2ca410028a0b3f64b826acbb",
"sha256:6a395a55089d2d886fdc814cf412e20d9d279110a3eb5768550b01f61e7b9cdb",
"sha256:09c65671850474d73700a2943d1564b60036dcc84122f8ffcd6cb34a2d2f9479"
]
},
}
]
Layers中有三个sha256的数字,表示这个镜像有三层组成,最上面是最底层的,最下面是最上层的。
1、sha256:767f936afb51c8a3ad9a96592a4be092048bb70f2ca410028a0b3f64b826acbb
2、sha256:6a395a55089d2d886fdc814cf412e20d9d279110a3eb5768550b01f61e7b9cdb
3、sha256:09c65671850474d73700a2943d1564b60036dcc84122f8ffcd6cb34a2d2f9479
查找第一层的数据
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# find -name "767f936afb51c8a3ad9a96592a4be092048bb70f2ca410028a0b3f64b826acbb"
./image/overlay2/layerdb/sha256/767f936afb51c8a3ad9a96592a4be092048bb70f2ca410028a0b3f64b826acbb
./image/overlay2/distribution/v2metadata-by-diffid/sha256/767f936afb51c8a3ad9a96592a4be092048bb70f2ca410028a0b3f64b826acbb
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker#
按照公式查找第二层
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# echo -n "sha256:767f936afb51c8a3ad9a96592a4be092048bb70f2ca410028a0b3f64b826acbb sha256:6a395a55089d2d886fdc814cf412e20d9d279110a3eb5768550b01f61e7b9cdb" | sha256sum
57cbd50652751eebe058602a11d336fca0819d6394a11d032c6260fd3e811d2e -
#确认层次
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# cat ./image/overlay2/layerdb/sha256/57cbd50652751eebe058602a11d336fca0819d6394a11d032c6260fd3e811d2e/parent
sha256:767f936afb51c8a3ad9a96592a4be092048bb70f2ca410028a0b3f64b826acbb
按照公式查找第三层,chainID=sha256sum(H(chainID) diffid)
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# echo -n "sha256:57cbd50652751eebe058602a11d336fca0819d6394a11d032c6260fd3e811d2e sha256:09c65671850474d73700a2943d1564b60036dcc84122f8ffcd6cb34a2d2f9479" | sha256sum
bdb7cdf8feed1bb5298e86ea62b251f6e22f505f13238c3a06e33a50313c38cd -
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# find -name "bdb7cdf8feed1bb5298e86ea62b251f6e22f505f13238c3a06e33a50313c38cd"
./image/overlay2/layerdb/sha256/bdb7cdf8feed1bb5298e86ea62b251f6e22f505f13238c3a06e33a50313c38cd
#确认
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# cat ./image/overlay2/layerdb/sha256/bdb7cdf8feed1bb5298e86ea62b251f6e22f505f13238c3a06e33a50313c38cd/parent
sha256:57cbd50652751eebe058602a11d336fca0819d6394a11d032c6260fd3e811d2e
根据上面计算出来的chains,查看目录下的cache-id,查看对应的目录
# 计算出来的三层
1、767f936afb51c8a3ad9a96592a4be092048bb70f2ca410028a0b3f64b826acbb
2、57cbd50652751eebe058602a11d336fca0819d6394a11d032c6260fd3e811d2e
3、bdb7cdf8feed1bb5298e86ea62b251f6e22f505f13238c3a06e33a50313c38cd
# 查看第一层数据目录
cat image/overlay2/layerdb/sha256/767f936afb51c8a3ad9a96592a4be092048bb70f2ca410028a0b3f64b826acbb/cache-id
5b1f40c8ed48fd43aa47d947d84eda7b80ca866aeb49c485dda326ca8eb76f76
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# ls overlay2/5b1f40c8ed48fd43aa47d947d84eda7b80ca866aeb49c485dda326ca8eb76f76/diff/
bin dev etc home lib media mnt proc root run sbin srv sys tmp usr var
# 查看第二层的数据
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# cat image/overlay2/layerdb/sha256/57cbd50652751eebe058602a11d336fca0819d6394a11d032c6260fd3e811d2e/cache-id
1fc34ade9326a48261bfb2f5e3b134cc1db5b9e2f1faf7d5df5049be05d1fbd1
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# ls overlay2/1fc34ade9326a48261bfb2f5e3b134cc1db5b9e2f1faf7d5df5049be05d1fbd1/diff/
etc lib lib64 sbin usr var
# 查看第三层的数据
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# cat image/overlay2/layerdb/sha256/bdb7cdf8feed1bb5298e86ea62b251f6e22f505f13238c3a06e33a50313c38cd/cache-id
8f377f94a7e3ab7c609e4054b414d346416a1f62a3ad9098ff7c0510a82212e9
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# ls overlay2/8f377f94a7e3ab7c609e4054b414d346416a1f62a3ad9098ff7c0510a82212e9/diff/
usr
启动一个容器
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# docker run --entrypoint sh --rm -it google/cadvisor:v0.33.0
/ # ls
bin dev etc home lib lib64 media mnt proc root run sbin srv sys tmp usr var
查看容器id
root@iZt4n1u8u50jg1r5n6myn2Z:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
072afc5171ff google/cadvisor:v0.33.0 "sh" 13 seconds ago Up 12 seconds (health: starting) 8080/tcp goofy_colden
查看容器的相关信息
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# find -name "072afc5171ff*"
./containers/072afc5171fff6aceaf669c7ecb6df9902129f912512c7f8bfe5aac7dad748c0
./containers/072afc5171fff6aceaf669c7ecb6df9902129f912512c7f8bfe5aac7dad748c0/072afc5171fff6aceaf669c7ecb6df9902129f912512c7f8bfe5aac7dad748c0-json.log
./image/overlay2/layerdb/mounts/072afc5171fff6aceaf669c7ecb6df9902129f912512c7f8bfe5aac7dad748c0
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker#
image/overlay2/layerdb/mounts目录下有个以容器id命名的目录,有一个init-id后缀的文件,从名称上看应该是容器的一些特性化数据,做一个形象的解释是,一个进程在容器中运行,虽然被限制了很多,但是该有的配套设施还是要有的。如在docker run中添加的dns信息就会存储在这个init-id目录下的etc/resolve.conf。
# init-id和mount-id是一样的,是本层的id
# parent的id是最上面的一层。
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# cat ./image/overlay2/layerdb/mounts/072afc5171fff6aceaf669c7ecb6df9902129f912512c7f8bfe5aac7dad748c0/init-id
a7a9309e6d612f56f02aa88df32c3366f1ac65c27ca523f85b628569cc19b300-init
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker#
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# cat ./image/overlay2/layerdb/mounts/072afc5171fff6aceaf669c7ecb6df9902129f912512c7f8bfe5aac7dad748c0/mount-id
a7a9309e6d612f56f02aa88df32c3366f1ac65c27ca523f85b628569cc19b300
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker#
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# cat ./image/overlay2/layerdb/mounts/072afc5171fff6aceaf669c7ecb6df9902129f912512c7f8bfe5aac7dad748c0/parent
sha256:bdb7cdf8feed1bb5298e86ea62b251f6e22f505f13238c3a06e33a50313c38cd
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# ls ./overlay2/a7a9309e6d612f56f02aa88df32c3366f1ac65c27ca523f85b628569cc19b300-init/diff/
dev etc
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# ls overlay2/a7a9309e6d612f56f02aa88df32c3366f1ac65c27ca523f85b628569cc19b300/
diff link lower merged work
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# ls overlay2/a7a9309e6d612f56f02aa88df32c3366f1ac65c27ca523f85b628569cc19b300/diff/
root
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker# ls overlay2/a7a9309e6d612f56f02aa88df32c3366f1ac65c27ca523f85b628569cc19b300/merged/
bin dev etc home lib lib64 media mnt proc root run sbin srv sys tmp usr var
root@iZt4n1u8u50jg1r5n6myn2Z:/var/lib/docker#
下篇预告
容器启动后看到的目录只有一个,这个目录又是多个目录联合形成的,那么容器访问一个rootfs文件的流程又是怎样的呢?下篇将会深入介绍overlayfs文件系统的原理,敬请期待。