镜像是Docker三大组件之一。Docker运行容器之前需要本地宿主机上存在该镜像,如果本地宿主机上不存在该镜像,那么Docker会从镜像仓库中下载该镜像!接下来记录一下如何管理镜像,包括下载镜像、列出镜像等:

获取镜像

Docker Hub上有大量的高质量的镜像可以使用,接下来将记录一下怎么获取这些镜像。获取镜像的命令格式如下:

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

格式说明:

  • OPTIONS:选项。可以使用如下OPTIONS:
    • -a, –all-tags:从镜像仓库中下载所有被标记的镜像
    • –disable-content-trust:跳过验证
  • NAME:仓库名
  • TAG:标签
  • DIGEST:数据摘要

接下来,我们下载一个Ubuntu 16.04版本的镜像:

root@ubuntu:~# docker pull ubuntu:16.04
16.04: Pulling from library/ubuntu
b234f539f7a1: Pull complete 
55172d420b43: Pull complete 
5ba5bbeb6b91: Pull complete 
43ae2841ad7a: Pull complete 
f6c9c6de4190: Pull complete 
Digest: sha256:b050c1822d37a4463c01ceda24d0fc4c679b0dd3c43e742730e2884d3c582e3a
Status: Downloaded newer image for ubuntu:16.04

上面的命令中,未指定具体的地址和端口,因此会在Docker Hub中获取镜像。16.04为标签名。

从下载过程中,先后下载了5个文件,是因为镜像是由多层存储所构成,所以,下载也是一层层的去下载,并非单一文件。下载过程中,给出了每一层ID的前12位,并且下载结束后,给出该镜像完整的sha256的摘要,以确保下载的一致性

运行

有了镜像之后,我们可以以此为基础运行一个容器。以上面的ubuntu:16.04为例,我们可以执行如下命令:

docker run -i -t --rm ubuntu:16.04 /bin/bash

参数说明:

  • -i:允许你对容器内的标准输入进行交互
  • -t:在新容器内指定一个伪终端或终端
  • –rm:容器退出后立即删除容器。一般情况下,无需指定此参数,指定--rm可以避免浪费空间
  • ubuntu:16.04:以此镜像为基础启动容器
  • /bin/bash:指定的交互式Shell

此命令还可以进行如下简写:

docker run -it --rm ubuntu:16.04 bash

查看更多docker run的用法,我们可以使用docker run --help来进行查看

进入容器之后,我们可以在容器内执行任何所需的命令。我们可以使用exit命令获取ctrl + d来退出容器

列出镜像

想要知道本机已经下载了哪几个镜像,我们可以使用docker image ls来列出本机已经下载好了的所有镜像:

root@ubuntu:~# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              16.04               5e8b97a2a082        3 weeks ago         114MB
centos              latest              49f7960eb7e4        3 weeks ago         200MB

结构说明:

  • REPOSITORY:仓库名称
  • TAG:标签名称
  • IMAGE ID:镜像ID
  • CREATED:创建时间
  • SIZE:所占用的空间

值得注意的是,一个镜像可以对象多个标签,判断是否为同一个镜像,我们可以查看它的镜像ID,镜像ID是镜像的唯一标识,如果镜像ID一样,则表示为同一镜像!!!

仔细观察,会注意到,这里标识的所占用空间和在Docker Hub上看到的镜像大小不同,通常情况下,这里标识的所占用空间会比在Docker Hub上看到的大!这是因为Docker Hub显示的体积是压缩后的体积,在镜像上传和下载过程中,镜像是保持压缩状态的,因为Docker Hub中显示的大小是网络传输中更关心的流量大小。而docker image ls显示的是镜像下载到本地,展开的大小,准确说,是展开后各层所占空间的总和,因为镜像到本地之后,查看控件的大小,更关心的是本地磁盘占用的空间大小。

值得注意的是,docker image ls列表中所有镜像体积总和并非是所有镜像硬盘实际消耗。由于Docker镜像是多层存储结构,并且可以继承、复用,因此不同镜像因为使用相同的基础镜像,从而拥有共同的层。由于Docker使用Union FS技术,相同的层只需要保存一份即可,所以所有镜像硬盘消耗可能要比这个列表镜像大小总和要小的多。

我们可以通过如下命令来查看镜像、容器、数据卷所占用的空间:

root@ubuntu:~# docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              2                   0                   313.6MB             313.6MB (100%)
Containers          0                   0                   0B                  0B
Local Volumes       0                   0                   0B                  0B
Build Cache                                                 0B                  0B

docker image ls命令更多操作如下:

  • 显示摘要信息docker image ls默认是不输出摘要信息的,我们可以使用--digests来显示摘要信息:
root@ubuntu:~# docker image ls --digests
REPOSITORY          TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
ubuntu              16.04               sha256:b050c1822d37a4463c01ceda24d0fc4c679b0dd3c43e742730e2884d3c582e3a   5e8b97a2a082        3 weeks ago         114MB
centos              latest              sha256:b67d21dfe609ddacf404589e04631d90a342921e81c40aeaf3391f6717fa5322   49f7960eb7e4        3 weeks ago         200MB
  • 虚悬镜像: 当你使用docker image ls命令列出当前宿主机上所有已下载的镜像时,有可能会有这样一类镜像,它既没有仓库名,也没有标签名,皆为<none>。其实,这类镜像原来是有仓库名和标签的,只不过,随着官方镜像的维护,这个镜像被重新发布了,以相同仓库名和标签名重新发布了。那么仓库名和标签名被转移到了新下载的镜像身上,而旧的镜像上的名称和标签都被取消了,从而成为了<none>,这类无标签的镜像我们称之为虚悬镜像,我们可以使用如下命令来列出所有的虚悬镜像:
docker image ls -f dangling=true

一般来说,虚悬镜像已经失去了价值,可以随意删除,可以用以下命令进行删除:

docker image prune
  • 中间层镜像: 为了加速镜像构建,重复利用资源,Docker会利用中间层镜像。默认的docker image ls列表中只会显示顶层镜像,如果希望显示包括中间层镜像在内的所有镜像的话,需要加上-a参数,如:
root@ubuntu:~# docker image ls -a
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              16.04               5e8b97a2a082        3 weeks ago         114MB
centos              latest              49f7960eb7e4        3 weeks ago         200MB

这样,你会看到很多无标签的镜像,这些镜像与之前的虚悬镜像不同,这些无标签的镜像很多都是中间层镜像,是其他镜像所依赖的镜像。这些无标签镜像不应该被删除,否则上层镜像会因为依赖丢失从而导致报错

  • 列出部分镜像
# 指定仓库名列出镜像
root@ubuntu:~# docker image ls ubuntu
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              16.04               5e8b97a2a082        3 weeks ago         114MB


# 列出某个特定的镜像
root@ubuntu:~# docker image ls ubuntu:16.04
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              16.04               5e8b97a2a082        3 weeks ago         114MB
  • 过滤参数-fdocker image ls还支持强大的过滤参数--filter,简写-f
# 过滤出在此镜像之后建立的镜像,切记是建立,不是下载!-f为过滤参数,since表示此镜像之后
root@ubuntu:~# docker image ls -f since=ubuntu:16.04

# 过滤出在此镜像之前建立的镜像,切记是建立,不是下载!-f为过滤参数,before表示此镜像之前
root@ubuntu:~# docker image ls -f before=ubuntu:16.04

# 如果镜像构建时,还定义了Label,我们还可以通过label来进行过滤
root@ubuntu:~# docker image ls -f label=baidu.com.version=0.1
  • 指定格式显示: 默认情况下,docker image ls会显示一个完整的表格,里面有仓库名、标签名、创建时间、镜像ID和占用空间大小数据,但是,有时我们并不需要知道这么多信息,例如,我们只需要列出所有镜像的ID,我们可以加上一个-q参数,如下:
root@ubuntu:~# docker image ls -q
5e8b97a2a082
49f7960eb7e4

-f参数还可以与-q参数结合使用,过滤出我们想要的那些镜像的ID。

有些时候,我们并不满意docker image ls列出的表格结构,我们只需要获取镜像的ID和仓库名称,此时使用-q参数,或者不带参数似乎都不尽满意。我们可以在使用--format参数来格式化显示,只显示我们需要的信息,如下:

root@ubuntu:~# docker image ls --format "{{.Repository}}:{{.ID}}"
ubuntu:5e8b97a2a082
centos:49f7960eb7e4

如果,你想显示表格,并且拥有标题行,标题行等距离相隔,我们可以对上面的命令进行修改,如下:

root@ubuntu:~# docker image ls --format "table {{.Repository}}\t{{.ID}}"
REPOSITORY          IMAGE ID
ubuntu              5e8b97a2a082
centos              49f7960eb7e4

还可以使用.Tag.Size来显示TAG和SIZE信息。

删除镜像

如果你要删除本地已经下载的镜像,你可以使用docker image rm命令,其格式为:

docker image rm [OPTIONS] IMAGE [IMAGE...]

首先,我们先列出当前宿主机上所有已经下载好的镜像列表:

root@ubuntu:~# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              16.04               5e8b97a2a082        3 weeks ago         114MB
ubuntu              14.04               578c3e61a98c        3 weeks ago         223MB
ubuntu              latest              113a43faa138        3 weeks ago         81.2MB
centos              latest              49f7960eb7e4        3 weeks ago         200MB
  • 使用完整ID进行删除: 使用完整ID进行删除,完整ID即IMAGE ID的值,例如我们将ubuntu:14.04镜像进行删除,我们可以这样:
root@ubuntu:~# docker image rm 578c3e61a98c
  • 使用短ID进行删除: 如果处于一种无法复制的环境之下,我们需要对镜像进行删除,如果使用完整ID进行删除的话,那么久需要一个一个进行手动输入,不仅繁琐,而且还容易出错。此时我们可以使用短ID进行删除镜像,例如,我们将ubuntu:14.04镜像进行删除,我们可以这样:
# 短ID长度不做限制,但是越长越精确,避免删错镜像
root@ubuntu:~# docker image rm 578c3
  • 使用镜像名进行删除: 使用镜像名进行删除,即<仓库名>:<标签名>,如果不带标签名,默认为<仓库名>:latest。例如,我们将ubuntu:latest镜像进行删除,我们可以这样:
root@ubuntu:~# docker image rm ubuntu
Untagged: ubuntu:latest
Untagged: ubuntu@sha256:5f4bdc3467537cbbe563e80db2c3ec95d548a9145d64453b06939c4592d67b6d
Deleted: sha256:113a43faa1382a7404681f1b9af2f0d70b182c569aab71db497e33fa59ed87e6
Deleted: sha256:a9fa410a3f1704cd9061a802b6ca6e50a0df183cb10644a3ec4cac9f6421677a
Deleted: sha256:b21f75f60422609fa79f241bf80044e6e133dd0662851afb12dacd22d199233a
Deleted: sha256:038d2d2aa4fb988c06f04e3af208cc0c1dbd9703aa04905ade206d783e7bc06a
Deleted: sha256:b904d425ea85240d6af5a6c6f145e05d5e0127f547f8eb4f68552962df846e81
Deleted: sha256:db9476e6d963ed2b6042abef1c354223148cdcdbd6c7416c71a019ebcaea0edb
  • 使用摘要信息进行删除: 在上面,我们知道可以使用docker image ls --digests来获取摘要信息,我们可以根据摘要信息来进行删除镜像。例如,我们,我们将ubuntu:16.04镜像进行删除,它的摘要信息为:sha256:b050c1822d37a4463c01ceda24d0fc4c679b0dd3c43e742730e2884d3c582e3a,我们可以输入以下命令将其删除:
# ubuntu为仓库名
root@ubuntu:~# docker image rm ubuntu@sha256:b050c1822d37a4463c01ceda24d0fc4c679b0dd3c43e742730e2884d3c582e3a
Untagged: ubuntu@sha256:b050c1822d37a4463c01ceda24d0fc4c679b0dd3c43e742730e2884d3c582e3a
  • docker image ls配合删除镜像: 像其他可以承接过个实体的命令一样,可以使用docker image ls -q来配合docker image rm来实现批量删除我们需要删除的镜像:
# 删除所有镜像
root@ubuntu:~# docker image rm $(docker image ls -q)

# 删除所有仓库名为ubuntu的镜像
root@ubuntu:~# docker image rm $(docker image ls -q ubuntu)

如果仔细观察上面几个删除镜像的输出信息,你会注意到删除行为分为两类:一类是Untagged,另一类是Deleted。因此当我们按照上面的命令进行删除镜像时,实际上是在要求删除某个镜像的标签。所以首先需要将所有满足我们要求的镜像标签取消,这就是我们看到的Untagged信息。因为一个镜像可能对应多个标签,因此我们删除了所指定的标签后,还可能有其他标签指向了这个镜像,那么Deleted行为就不会发生。所以并非所有的docker rmi都会产生删除镜像的行为,有可能仅仅只是取消了某个标签而已

更多命令

命令说明
docker image ls列出镜像
docker images列出镜像
docker image ls -a列出所有镜像
docker images -a列出所有镜像
docker image rm删除镜像
docker rmi删除镜像

使用docker image --helpdocker images --help发现,docker image命令与docker images命令效果是一样的!docker image rmdocker rmi效果是一样的!

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐