Docker容器镜像
Docker容器镜像操作
查看本地容器镜像
# 下面两个命令都可以用来查看本地容器镜像列表
docker images
docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest eea7b3dcba7e 2 weeks ago 187MB
centos latest 5d0da3dc9764 24 months ago 231MB
docker容器镜像会占用本地存储空间,建议搭建其它存储系统挂载到本地以便解决占用大量本地存储的问题
docker容器镜像默认存储在 /var/lib/docker,可以自定义,上面安装的docker,镜像文件位置在 /data/docker
ls /data/docker
buildkit containers engine-id image network overlay2 plugins runtimes swarm tmp volumes
搜索Docker Hub容器镜像
命令行搜索
docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos DEPRECATED; The official build of CentOS. 7640 [OK]
kasmweb/centos-7-desktop CentOS 7 desktop for Kasm Workspaces 39
bitnami/centos-base-buildpack Centos base compilation image 0 [OK]
couchbase/centos7-systemd centos7-systemd images with additional debug… 8 [OK]
continuumio/centos5_gcc5_base 3
datadog/centos-i386 0
dokken/centos-7 CentOS 7 image for kitchen-dokken 5
dokken/centos-8 CentOS 8 image for kitchen-dokken 3
spack/centos7 CentOS 7 with Spack preinstalled 1
...
Docker Hub Web界面搜索
Docker 容器镜像下载
docker pull mysql
Docker容器镜像删除方法
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest eea7b3dcba7e 2 weeks ago 187MB
mysql latest 99afc808f15b 3 weeks ago 577MB
centos latest 5d0da3dc9764 24 months ago 231MB
# 下面两个命令都可以用来删除镜像
docker rmi centos
docker rmi eea7b3dcba7e
Untagged: centos:latest
Untagged: centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Deleted: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
Deleted: sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest eea7b3dcba7e 2 weeks ago 187MB
mysql latest 99afc808f15b 3 weeks ago 577MB
Docker容器镜像介绍
Docker Image
- Docker 镜像是只读的容器模板,是Docker容器基础
- 为Docker容器提供了静态文件系统运行环境(rootfs)
- 是容器的静止状态
- 容器是镜像的运行状态
联合文件系统
定义
- 联合文件系统(union filesystem)
- 联合文件系统是实现联合挂载技术的文件系统
- 联合挂载技术可以实现在一个挂载点同时挂载多个文件系统,将挂载点的原目录与被挂载内容进行整合,使得最终可见的文件系统包含整合之后的各层文件和目录
图解
Docker Overlay2
容器文件系统有多种存储驱动实现方式:aufs,devicemapper,overlay,overlay2 等,本次以overlay2为例进行说明。
概念
- registry/repository: registry 是 repository 的集合,repository 是镜像的集合。
- image:image 是存储镜像相关的元数据,包括镜像的架构,镜像默认配置信息,镜像的容器配置信息等等。它是“逻辑”上的概念,并无物理上的镜像文件与之对应。
- layer:layer(镜像层) 组成了镜像,单个 layer 可以被多个镜像共享。
查看Docker Host存储驱动方式
docker info | grep overlay
Storage Driver: overlay2
Network: bridge host ipvlan macvlan null overlay
了解images分层
docker rmi nginx
docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
52d2b7f179e3: Pull complete
fd9f026c6310: Pull complete
055fa98b4363: Pull complete
96576293dd29: Pull complete
a7c4092be904: Pull complete
e3b6889c8954: Pull complete
da761d9a302b: Pull complete
Digest: sha256:104c7c5c54f2685f0f46f3be607ce60da7085da3eaa5ad22d3d9f01594295e9c
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
可以看到上述下载的镜像分为7层,如何找到这7层存储在Docker Host哪个位置呢?
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest eea7b3dcba7e 3 weeks ago 187MB
ls /data/docker/image/overlay2/
distribution imagedb layerdb repositories.json
/data/docker/image/overlay2/录是查找的入口,非常重要。它存储了镜像管理的元数据。
- repositories.json 记录了 repo 与镜像 ID 的映射关系
- imagedb 记录了镜像架构,操作系统,构建镜像的容器 ID 和配置以及 rootfs 等信息
- layerdb 记录了每层镜像层的元数据。
通过短 ID 查找 repositories.json 文件,找到镜像 nginx 的长 ID,通过长 ID 在 imagedb 中找到该镜像的元数据:
cat /data/docker/image/overlay2/repositories.json | grep eea7b3dcba7e
{"Repositories":{"nginx":{"nginx:latest":"sha256:eea7b3dcba7ee47c0d16a60cc85d2b977d166be3960541991f3e6294d795ed24","nginx@sha256:104c7c5c54f2685f0f46f3be607ce60da7085da3eaa5ad22d3d9f01594295e9c":"sha256:eea7b3dcba7ee47c0d16a60cc85d2b977d166be3960541991f3e6294d795ed24"}}}
cat /data/docker/image/overlay2/imagedb/content/sha256/eea7b3dcba7ee47c0d16a60cc85d2b977d166be3960541991f3e6294d795ed24
...
"os":"linux","r
ootfs":{"type":"layers","diff_ids":["sha256:511780f88f80081112aea1bfdca6c800e1983e401b338e20b2c6e97f384e4299",
"sha256:4713cb24eeff341d0c36343149beba247572a5ff65c2be5b5d9baafb345c7393","sha256:d0a62f56ef413f60049bc87e43e6
0032b2a2ab8d931e15b86ee0286c85ae91a2","sha256:8a7e12012e6f60450e6d2d777b2a2c2256d34a0ccd84d605f72cc5329a87c8b8
","sha256:e161c3f476b5199ab13856c7e190ed12a6562b7be059c7026ae9f594e1abbcaf","sha256:6fb960878295b567d25900b590
157b976d080340caeaa8bf8c46d38c01b4537d","sha256:563c64030925e9016a2329d3a2b7d47b0c90931baf5d2d0aa926c4c8d94ab8
94"]}}
这里仅保留我们想要的元数据 rootfs。在 rootfs 中看到 layers 有7层,这7层即对应镜像的7层镜像层。并且,自上而下分别映射到容器的底层到顶层。找到了镜像的7层,接下来的问题是每层的文件内容在哪里呢?
layerdb 元数据会给我们想要的信息,通过底层 diff-id: 511780f88f80081112aea1bfdca6c800e1983e401b338e20b2c6e97f384e4299我们查到最底层镜像层的 cache_id,通过 cache_id 即可查找到镜像层的文件内容:
ls /data/docker/image/overlay2/layerdb/sha256/511780f88f80081112aea1bfdca6c800e1983e401b338e20b2c6e97f384e4299
cache-id diff size tar-split.json.gz
cat /data/docker/image/overlay2/layerdb/sha256/511780f88f80081112aea1bfdca6c800e1983e401b338e20b2c6e97f384e4299/cache-id
70a84b873ced20488b785519f7422caddcad5d5028ceb1258c2bb764c33d8ccb
cat /data/docker/image/overlay2/layerdb/sha256/511780f88f80081112aea1bfdca6c800e1983e401b338e20b2c6e97f384e4299/diff
sha256:511780f88f80081112aea1bfdca6c800e1983e401b338e20b2c6e97f384e4299
使用 cacheId 查找文件内容
ls /data/docker/overlay2/70a84b873ced20488b785519f7422caddcad5d5028ceb1258c2bb764c33d8ccb
committed diff link
ls /data/docker/overlay2/70a84b873ced20488b785519f7422caddcad5d5028ceb1258c2bb764c33d8ccb/diff
bin dev home lib32 libx32 mnt proc run srv tmp var
boot etc lib lib64 media opt root sbin sys usr
上面示例中,镜像元数据和镜像层内容是分开存储的。因此通过 cache-id 我们需要到 /data/docker/overlay2 目录下查看镜像层内容,它就存在 diff 目录下,其中 link 存储的是镜像层对应的短 ID,后面会看到它的用场。
找到了镜像层的最底层,接着查找镜像层的“中间层”,发现在 layerdb 目录下没有 diff-id 4713cb24eeff341d0c36343149beba247572a5ff65c2be5b5d9baafb345c7393的镜像层:
ls /data/docker/image/overlay2/layerdb/sha256/4713cb24eeff341d0c36343149beba247572a5ff65c2be5b5d9baafb345c7393
ls: cannot access ... No such file or directory
这是因为 docker 引入了内容寻址机制,该机制会根据文件内容来索引镜像和镜像层。docker 利用 rootfs 中的 diff_id 计算出内容寻址的 chainID,通过 chainID 获取 layer 相关信息,最终索引到镜像层文件内容。
对于最底层镜像层其 diff_id 即是 chainID。因此我们可以查找到它的文件内容。除最底层外,chainID 需通过公式 chainID(n) = SHA256(chain(n-1) diffID(n)) 计算得到,计算“中间层” chainID:
echo -n "sha256:511780f88f80081112aea1bfdca6c800e1983e401b338e20b2c6e97f384e4299 sha256:4713cb24eeff341d0c36343149beba247572a5ff65c2be5b5d9baafb345c7393" | sha256sum -
49bfd4a4ea578aefcacdfd87efdc4999d6a4e4b7f00322484cac67ff7671389e -
根据 “中间层” chainID 查找文件内容:
ls /data/docker/image/overlay2/layerdb/sha256/49bfd4a4ea578aefcacdfd87efdc4999d6a4e4b7f00322484cac67ff7671389e
cache-id diff parent size tar-split.json.gz
cat /data/docker/image/overlay2/layerdb/sha256/49bfd4a4ea578aefcacdfd87efdc4999d6a4e4b7f00322484cac67ff7671389e/cache-id
417f018435117a528ed4963f4e46facd1268c987efae80839b542e6d9607a59c
cat /data/docker/image/overlay2/layerdb/sha256/49bfd4a4ea578aefcacdfd87efdc4999d6a4e4b7f00322484cac67ff7671389e/diff
sha256:4713cb24eeff341d0c36343149beba247572a5ff65c2be5b5d9baafb345c7393
cat /data/docker/image/overlay2/layerdb/sha256/49bfd4a4ea578aefcacdfd87efdc4999d6a4e4b7f00322484cac67ff7671389e/parent
sha256:511780f88f80081112aea1bfdca6c800e1983e401b338e20b2c6e97f384e4299
# 镜像层文件内容,这里用到的是上面的cache-id
ls /data/docker/overlay2/417f018435117a528ed4963f4e46facd1268c987efae80839b542e6d9607a59c
committed diff link lower work
ls /data/docker/overlay2/417f018435117a528ed4963f4e46facd1268c987efae80839b542e6d9607a59c/diff/
docker-entrypoint.d etc tmp usr var
# 镜像层文件内容短 ID
cat /data/docker/overlay2/417f018435117a528ed4963f4e46facd1268c987efae80839b542e6d9607a59c/link
POGTJHLPQKI72V3SCWS2N7YTXV
# “父”镜像层文件内容短 ID
cat /data/docker/overlay2/417f018435117a528ed4963f4e46facd1268c987efae80839b542e6d9607a59c/lower
l/5DEMHARECNUU5RZ77ANSDDSRFW
找到最底层文件内容和“中间层”文件内容,再去找最顶层文件内容就变的不难了
Docker容器与镜像
通过 docker run 命令启动一个镜像为 nginx的容器:
docker run -d nginx:latest
61dde6968cc64be7b4f7ead16d0e0f4481fbdbee6992142a55b6ae76e3a75b75
docker ps | grep nginx
61dde6968cc6 nginx:latest "/docker-entrypoint.…" 21 seconds ago Up 20 seconds 80/tcp modest_benz
mount | grep overlay
overlay on /data/docker/overlay2/6d2134a30675c66750138f069bce3b3a465b4b6e29d26dd42899125e49ab5c64/merged type overlay (rw,relatime,lowerdir=/data/docker/overlay2/l/6VHRCIJBQBRPME2ETJUFGVIBDK:/data/docker/overlay2/l/E63C6HLNVMQUKGJB623YHPKK3I:/data/docker/overlay2/l/WR6JLMCYXFUR6YTCLEISZSN37W:/data/docker/overlay2/l/4BUITPTAAHX2AHG4WRSJPVD35B:/data/docker/overlay2/l/CGJNFHYZTCIWSSWXLXEPJWLFBE:/data/docker/overlay2/l/W5EIOLLWFUVLJBZI7SLSCOY3J4:/data/docker/overlay2/l/POGTJHLPQKI72V3SCWS2N7YTXV:/data/docker/overlay2/l/5DEMHARECNUU5RZ77ANSDDSRFW,upperdir=/data/docker/overlay2/6d2134a30675c66750138f069bce3b3a465b4b6e29d26dd42899125e49ab5c64/diff,workdir=/data/docker/overlay2/6d2134a30675c66750138f069bce3b3a465b4b6e29d26dd42899125e49ab5c64/work)
可以看到,启动容器会 mount 一个 overlay 的联合文件系统到容器内。这个文件系统由三层组成:
- lowerdir:只读层,即为镜像的镜像层。
- upperdir:读写层,该层是容器的读写层,对容器的读写操作将反映在读写层。
- workdir: overlayfs 的内部层,用于实现从只读层到读写层的 copy_up 操作。
- merge:容器内作为同一视图联合挂载点的目录。
这里需要着重介绍的是容器的 lowerdir 镜像只读层,查看只读层的短 ID:
lowerdir=
/data/docker/overlay2/l/6VHRCIJBQBRPME2ETJUFGVIBDK:
/data/docker/overlay2/l/E63C6HLNVMQUKGJB623YHPKK3I:
/data/docker/overlay2/l/WR6JLMCYXFUR6YTCLEISZSN37W:
/data/docker/overlay2/l/4BUITPTAAHX2AHG4WRSJPVD35B:
/data/docker/overlay2/l/CGJNFHYZTCIWSSWXLXEPJWLFBE:
/data/docker/overlay2/l/W5EIOLLWFUVLJBZI7SLSCOY3J4:
/data/docker/overlay2/l/POGTJHLPQKI72V3SCWS2N7YTXV:
/data/docker/overlay2/l/5DEMHARECNUU5RZ77ANSDDSRFW
镜像层只有7层这里的短 ID 却有8个?在 /data/docker/overlay2/l 目录下我们找到了答案:
cd /data/docker/overlay2/l
ls
4BUITPTAAHX2AHG4WRSJPVD35B CGJNFHYZTCIWSSWXLXEPJWLFBE W5EIOLLWFUVLJBZI7SLSCOY3J4
5DEMHARECNUU5RZ77ANSDDSRFW E63C6HLNVMQUKGJB623YHPKK3I WR6JLMCYXFUR6YTCLEISZSN37W
6VHRCIJBQBRPME2ETJUFGVIBDK POGTJHLPQKI72V3SCWS2N7YTXV ZYRDU2NDGHXYNUPHQFBNX5UGUT
ls -l 6VHRCIJBQBRPME2ETJUFGVIBDK/
total 0
drwxr-xr-x 4 root root 43 Sep 6 19:43 dev
drwxr-xr-x 2 root root 66 Sep 6 19:43 etc
ls -l E63C6HLNVMQUKGJB623YHPKK3I/
total 0
drwxr-xr-x 2 root root 41 Aug 16 17:50 docker-entrypoint.d
ls -l WR6JLMCYXFUR6YTCLEISZSN37W/
total 0
drwxr-xr-x 2 root root 41 Aug 16 17:50 docker-entrypoint.d
ls -l 4BUITPTAAHX2AHG4WRSJPVD35B/
total 0
drwxr-xr-x 2 root root 38 Aug 16 17:50 docker-entrypoint.d
ls -l CGJNFHYZTCIWSSWXLXEPJWLFBE/
total 0
drwxr-xr-x 2 root root 45 Aug 16 17:50 docker-entrypoint.d
ls -l W5EIOLLWFUVLJBZI7SLSCOY3J4/
total 4
-rwxrwxr-x 1 root root 1620 Aug 16 17:50 docker-entrypoint.sh
ls -l POGTJHLPQKI72V3SCWS2N7YTXV/
total 4
drwxr-xr-x 2 root root 6 Aug 16 17:50 docker-entrypoint.d
drwxr-xr-x 19 root root 4096 Aug 16 17:50 etc
drwxrwxrwt 2 root root 6 Aug 16 17:50 tmp
drwxr-xr-x 7 root root 66 Aug 14 08:00 usr
drwxr-xr-x 5 root root 41 Aug 14 08:00 var
ls -l 5DEMHARECNUU5RZ77ANSDDSRFW/
total 4
lrwxrwxrwx 1 root root 7 Aug 14 08:00 bin -> usr/bin
drwxr-xr-x 2 root root 6 Jul 15 00:00 boot
drwxr-xr-x 2 root root 6 Aug 14 08:00 dev
drwxr-xr-x 29 root root 4096 Aug 14 08:00 etc
drwxr-xr-x 2 root root 6 Jul 15 00:00 home
lrwxrwxrwx 1 root root 7 Aug 14 08:00 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Aug 14 08:00 lib32 -> usr/lib32
lrwxrwxrwx 1 root root 9 Aug 14 08:00 lib64 -> usr/lib64
lrwxrwxrwx 1 root root 10 Aug 14 08:00 libx32 -> usr/libx32
drwxr-xr-x 2 root root 6 Aug 14 08:00 media
drwxr-xr-x 2 root root 6 Aug 14 08:00 mnt
drwxr-xr-x 2 root root 6 Aug 14 08:00 opt
drwxr-xr-x 2 root root 6 Jul 15 00:00 proc
drwx------ 2 root root 37 Aug 14 08:00 root
drwxr-xr-x 3 root root 18 Aug 14 08:00 run
lrwxrwxrwx 1 root root 8 Aug 14 08:00 sbin -> usr/sbin
drwxr-xr-x 2 root root 6 Aug 14 08:00 srv
drwxr-xr-x 2 root root 6 Jul 15 00:00 sys
drwxrwxrwt 2 root root 6 Aug 14 08:00 tmp
drwxr-xr-x 14 root root 160 Aug 14 08:00 usr
drwxr-xr-x 11 root root 139 Aug 14 08:00 var
后7个文件夹分别对应镜像的7层镜像层文件内容,它们分别映射到镜像层的 diff 目录。第一个6VHRCIJBQBRPME2ETJUFGVIBDK,映射的是容器的初始化层 init,该层内容是和容器配置相关的文件内容,它是只读的。
启动了容器,docker 将镜像的内容 mount 到容器中。那么,如果在容器内写文件会对镜像有什么影响呢?
容器内写文件
不难理解,镜像层是只读的,在容器中写文件其实是将文件写入到 overlay 的可读写层。
这里有几个 case 可以测试:
- 读写层不存在该文件,只读层存在。
- 读写层存在该文件,只读层不存在。
- 读写层和只读层都不存在该文件。
我们简单构建一种读写层和只读层都不存在的场景:
# 会进入容器中
docker run -it centos:latest bash
touch test.txt
ls
bin etc lib lost+found mnt proc run srv test.txt usr
dev home lib64 media opt root sbin sys tmp var
# Ctrl p q 退出容器环境
查看读写层是否有该文件:
# 查看镜像是否有变化
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest eea7b3dcba7e 3 weeks ago 187MB
centos latest 5d0da3dc9764 24 months ago 231MB
cat /data/docker/image/overlay2/repositories.json | grep 5d0da3dc9764
{"Repositories":{"centos":{"centos:latest":"sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6","centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177":"sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6"},"nginx":{"nginx:latest":"sha256:eea7b3dcba7ee47c0d16a60cc85d2b977d166be3960541991f3e6294d795ed24","nginx@sha256:104c7c5c54f2685f0f46f3be607ce60da7085da3eaa5ad22d3d9f01594295e9c":"sha256:eea7b3dcba7ee47c0d16a60cc85d2b977d166be3960541991f3e6294d795ed24"}}}
cat /data/docker/image/overlay2/imagedb/content/sha256/5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
...
"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59"]}}
ls /data/docker/image/overlay2/layerdb/sha256/74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59
cache-id diff size tar-split.json.gz
cat /data/docker/image/overlay2/layerdb/sha256/74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59/cache-id
ef08c508b300cbf16d9cdc51191f54e2fa0797808110804c8237b8e1a0324556
cat /data/docker/image/overlay2/layerdb/sha256/74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59/diff
sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59
# 下面使用的是上面的cache-id
ls /data/docker/overlay2/ef08c508b300cbf16d9cdc51191f54e2fa0797808110804c8237b8e1a0324556
committed diff link
ls /data/docker/overlay2/ef08c508b300cbf16d9cdc51191f54e2fa0797808110804c8237b8e1a0324556/diff/
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 查看容器是否有变化
mount | grep overlay
overlay on /data/docker/overlay2/fa4b9ff3334fa16e1e069ca86abb3963a255f3a1a6ec6fa91422b84981ddefd9/merged type overlay (rw,relatime,lowerdir=/data/docker/overlay2/l/WQ26CLGP2ONNXFNLU3MLSTV2TH:/data/docker/overlay2/l/GEWNRFWQCWPPBGEAXMKFCVK3WL,upperdir=/data/docker/overlay2/fa4b9ff3334fa16e1e069ca86abb3963a255f3a1a6ec6fa91422b84981ddefd9/diff,workdir=/data/docker/overlay2/fa4b9ff3334fa16e1e069ca86abb3963a255f3a1a6ec6fa91422b84981ddefd9/work)
ls -l /data/docker/overlay2/l/
...
lrwxrwxrwx 1 root root 72 Sep 7 08:08 RKFVMCTQGNHQKBI3P4CDCOT2OM -> ../fa4b9ff3334fa16e1e069ca86abb3963a255f3a1a6ec6fa91422b84981ddefd9/diff
lrwxrwxrwx 1 root root 72 Sep 6 17:46 W5EIOLLWFUVLJBZI7SLSCOY3J4 -> ../3b66c106cd5738902740035e99ae1ed1c8831b1de82e110931356caecbf22d68/diff
...
ls /data/docker/overlay2/fa4b9ff3334fa16e1e069ca86abb3963a255f3a1a6ec6fa91422b84981ddefd9/diff
etc lost+found mnt run srv test.txt usr
ls /data/docker/overlay2/fa4b9ff3334fa16e1e069ca86abb3963a255f3a1a6ec6fa91422b84981ddefd9/merged
bin etc lib lost+found mnt proc run srv test.txt usr
dev home lib64 media opt root sbin sys tmp var
Docker容器镜像操作命令
docker commit
上节提到容器内写文件会反映在 overlay 的可读写层,那么读写层的文件内容可以做成镜像吗?
可以。docker 通过 commit 和 build 操作实现镜像的构建。commit 将容器提交为一个镜像,build 在一个镜像的基础上构建镜像。
使用 commit 将上节的容器提交为一个镜像:
# Ctrl p q 退出容器环境
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
16907ddf5b9f centos:latest "bash" 42 minutes ago Up 42 minutes thirsty_elbakyan
docker commit 16907ddf5b9f
sha256:e2bb9af57c619dcd348aa058c5886f356a8ef23ccda54ed0286c190c227bd67c
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> e2bb9af57c61 18 seconds ago 231MB
image 短 ID e2bb9af57c61 即为容器提交的镜像,查看镜像的 imagedb 元数据:
cat /data/docker/image/overlay2/imagedb/content/sha256/e2bb9af57c619dcd348aa058c5886f356a8ef23ccda54ed0286c190c227bd67c
...
"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59","sha256:caa183522ca08242f94e1ac48140d80a56408b39c98bdfcca76911ef1c0b2665"]}}
可以看到镜像层自上而下的前1个镜像层 diff_id 和 centos 镜像层 diff_id 是一样的,说明每层镜像层可以被多个镜像共享。而多出来的一层镜像层内容即是上节我们写入文件的内容:
echo -n "sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59 sha256:caa183522ca08242f94e1ac48140d80a56408b39c98bdfcca76911ef1c0b2665" | sha256sum -
3e589464f2c041cd88b0f6a8dca47e3ac88f29902568e77dc46df648f35f2698 -
ls /data/docker/image/overlay2/layerdb/sha256/3e589464f2c041cd88b0f6a8dca47e3ac88f29902568e77dc46df648f35f2698
cache-id diff parent size tar-split.json.gz
cat /data/docker/image/overlay2/layerdb/sha256/3e589464f2c041cd88b0f6a8dca47e3ac88f29902568e77dc46df648f35f2698/cache-id
69b2a494c5d8f2aa9f1354b9fcfc6e573230d334b764a42df2ba5f4dd9c5dfd2
# 下面使用的是上面的cache-id
ls /data/docker/overlay2/69b2a494c5d8f2aa9f1354b9fcfc6e573230d334b764a42df2ba5f4dd9c5dfd2
diff link lower work
ls /data/docker/overlay2/69b2a494c5d8f2aa9f1354b9fcfc6e573230d334b764a42df2ba5f4dd9c5dfd2/diff
etc lost+found mnt run srv test.txt usr
docker save
导出容器镜像,方便分享
docker save -o centos.tar centos:latest
ls
centos.tar
docker load
把他人分享的容器镜像导入到本地,这通常是容器镜像分发方式之一。
docker load -i centos.tar
docker export
把正在运行的容器导出
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
16907ddf5b9f centos:latest "bash" About an hour ago Up About an hour thirsty_elbakyan
docker export -o centos7.tar 16907ddf5b9f
ls
centos7.tar
docker import
导入使用docker import导入的容器做为本地容器镜像。
ls
centos7.tar
docker import centos7.tar centos7:v1
sha256:92224c57d28a2a083973d2c78299bc6a6d5edccaf957314656256c44b0430345
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7 v1 92224c57d28a 18 seconds ago 231MB
通过docker save与docker load及docker export与docker import分享容器镜像都是非常麻烦的,有没有更方便的方式分享容器镜像呢?