docker 3 section

docker镜像的相关概念

镜像体积:

列出已经下载下来的镜像,可以使用 docker image ls 命令:

[root@work ~]# docker image ls
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos        latest              9f38484d220f        32 hours ago        202 MB

-如果仔细观察,会注意到,这里标识的所占用空间和在 Docker Hub 上看到的镜像大小不同。比如, centos:latest 显示镜像大小是202 MB ,但是在 Docker Hub 显示的却是 50MB 。
-这是因为 Docker Hub 中显示的体积是压缩后的体积。在镜像下载和上传过程中镜像是保持着压缩状态的,因此 Docker Hub 所显示的大小是网络传输中更关心的流量大小。而docker image ls 显示的是镜像下载到本地后展开的大小,准确说,是展开后的各层所占空间的总和,因为镜像到本地后,查看空间的时候,更关心的是本地磁盘空间占用的大小。
-另外一个需要注意的问题是, docker image ls 列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。由于 Docker 使用 Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多。可以通过以下命令来便捷的查看镜像、容器、数据卷所占用的空间。

[root@work ~]# docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              2                   2                   201.8 MB            0 B (0%)
Containers          2                   0                   6 B                 6 B (100%)
Local Volumes       0                   0                   0 B                 0 B

虚悬镜像:

在镜像列表中,可能看到一些特殊的镜像,镜像既没有仓库名,也没有标签,均为 <none> 。:
<none> <none> 00285df0df87 5 days ago 342 MB
这个镜像原本是有镜像名和标签的,原来为 mongo:3.2 ,随着官方镜像维护,发布了新版本后,重新 docker pull mongo:3.2 时, mongo:3.2 这个镜像名被转移到了新下载的镜像身上,而旧的镜像上的这个名称则被取消,从而成为了 <none> 。
除了 docker pull 可能导致这种情况, docker build 也同样可以导致这种现象。由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 <none> 的镜像。这类无标签镜像也被称为 虚悬镜像(dangling image) ,可以用下面的命令专门显示这类镜像:

$ docker image ls -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 00285df0df87 5 days ago 342 MB

一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用下面的命令删除:
$ docker image prune

中间层镜像:

为了加速镜像构建、重复利用资源,Docker 会利用 中间层镜像。所以在使用一段时间后,可能会看到一些依赖的中间层镜像。默认的 docker image ls 列表中只会显示顶层镜像,如果显示包括中间层镜像在内的所有镜像的话,需要加 -a 参数。
$ docker image ls -a

这样会看到很多无标签的镜像,与之前的虚悬镜像不同,这些无标签的镜像很多都是中间层镜像,是其它镜像所依赖的镜像。这些无标签镜像不应该删除,否则会导致上层镜像因为依赖丢失而出错。实际上,这些镜像也没必要删除,因为之前说过,相同的层只会存一遍,而这些镜像是别的镜像的依赖,因此并不会因为它们被列出来而多存了一份,无论如何你也会需要它们。只要删除那些依赖它们的镜像后,这些依赖的中间层镜像也会被连带删除。

只列出镜像ID:

$ docker image ls -q
5f515359c7f8
05a60462f8ba
fe9198c04d62
00285df0df87
f753707788c5
f753707788c5
1e0c3dd64ccd

删除本地镜像:

如果要删除本地的镜像,可以使用 docker image rm 命令,其格式为:
$ docker image rm [选项] <镜像1> [<镜像2> ...]

  • 可以用镜像的完整 ID,也称为长ID,来删除镜像。
  • 可以用 短 ID 来删除镜像。 docker image ls 默认列出的就已经是短ID 了,一般取前3个字符以上,只要足够区分于别的镜像就可以。
  • 可以用 镜像名 ,也就是 <仓库名>:<标签> ,来删除镜像。

用 docker image ls 命令来配合使用:
像其它可以承接多个实体的命令一样,可以使用 docker image ls -q 来配合使用 docker image rm ,这样可以成批的删除希望删除的镜像。
比如,我们需要删除所有仓库名为 redis 的镜像:
$ docker image rm $(docker image ls -q redis)
或者删除所有在 mongo:3.2 之前的镜像:
$ docker image rm $(docker image ls -q -f before=mongo:3.2)

显示镜像摘要:

[root@work ~]# docker image ls --digests
REPOSITORY              TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
docker.io/centos        latest              sha256:a81ea5364ff9199b53c7de2eda6dffbff0739116a0908c39e83d7d74b2702a71   9f38484d220f        33 hours ago        202 MB
docker.io/hello-world   latest              sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535   fce289e99eb9        2 months ago        1.84 kB

devicemapper + loop-lvm 的缺陷问题:

因为它是稀疏文件,所以它会不断增长。用户在使用过程中会注意到 /var/lib/docker/devicemapper/devicemapper/data 不断增长,而且无法控制。很多人会希望删除镜像或者可以解决这个问题,结果发现效果并不明显。原因就是这个稀疏文件的空间释放后基本不进行垃圾回收的问题。因此往往会出现即使删除了文件内容,空间却无法回收,随着使用这个稀疏文件一直在不断增长。
所以对于 CentOS/RHEL 的用户来说,在没有办法使用 UnionFS 的情况下,一定要配置 direct-lvm 给 devicemapper ,无论是为了性能、稳定性还是空间利用率。
或许有人注意到了 CentOS 7 中存在被 backports 回来的 overlay 驱动,不过 CentOS 里的这个驱动达不到生产环境使用的稳定程度,所以不推荐使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章