docker_practice/image/list.md
Kang HuaiShuai 5cb92f63cf
Update title style
Signed-off-by: Kang HuaiShuai <khs1994@khs1994.com>
2019-11-06 14:58:03 +08:00

153 lines
8.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 列出镜像
要想列出已经下载下来的镜像可以使用 `docker image ls` 命令
```bash
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 5f515359c7f8 5 days ago 183 MB
nginx latest 05a60462f8ba 5 days ago 181 MB
mongo 3.2 fe9198c04d62 5 days ago 342 MB
<none> <none> 00285df0df87 5 days ago 342 MB
ubuntu 18.04 f753707788c5 4 weeks ago 127 MB
ubuntu latest f753707788c5 4 weeks ago 127 MB
```
列表包含了 `仓库名``标签``镜像 ID``创建时间` 以及 `所占用的空间`
其中仓库名标签在之前的基础概念章节已经介绍过了**镜像 ID** 则是镜像的唯一标识一个镜像可以对应多个 **标签**因此在上面的例子中我们可以看到 `ubuntu:18.04` `ubuntu:latest` 拥有相同的 ID因为它们对应的是同一个镜像
## 镜像体积
如果仔细观察会注意到这里标识的所占用空间和在 Docker Hub 上看到的镜像大小不同比如`ubuntu:18.04` 镜像大小在这里是 `127 MB`但是在 [Docker Hub](https://hub.docker.com/r/library/ubuntu/tags/) 显示的却是 `50 MB`。这是因为 Docker Hub 中显示的体积是压缩后的体积。在镜像下载和上传过程中镜像是保持着压缩状态的,因此 Docker Hub 所显示的大小是网络传输中更关心的流量大小。而 `docker image ls` 显示的是镜像下载到本地后,展开的大小,准确说,是展开后的各层所占空间的总和,因为镜像到本地后,查看空间的时候,更关心的是本地磁盘空间占用的大小。
另外一个需要注意的问题是`docker image ls` 列表中的镜像体积总和并非是所有镜像实际硬盘消耗由于 Docker 镜像是多层存储结构并且可以继承复用因此不同镜像可能会因为使用相同的基础镜像从而拥有共同的层由于 Docker 使用 Union FS相同的层只需要保存一份即可因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多
你可以通过以下命令来便捷的查看镜像容器数据卷所占用的空间
```bash
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 24 0 1.992GB 1.992GB (100%)
Containers 1 0 62.82MB 62.82MB (100%)
Local Volumes 9 0 652.2MB 652.2MB (100%)
Build Cache 0B 0B
```
## 虚悬镜像
上面的镜像列表中还可以看到一个特殊的镜像这个镜像既没有仓库名也没有标签均为 `<none>`
```bash
<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)** 可以用下面的命令专门显示这类镜像
```bash
$ docker image ls -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 00285df0df87 5 days ago 342 MB
```
一般来说虚悬镜像已经失去了存在的价值是可以随意删除的可以用下面的命令删除
```bash
$ docker image prune
```
## 中间层镜像
为了加速镜像构建重复利用资源Docker 会利用 **中间层镜像**所以在使用一段时间后可能会看到一些依赖的中间层镜像默认的 `docker image ls` 列表中只会显示顶层镜像如果希望显示包括中间层镜像在内的所有镜像的话需要加 `-a` 参数
```bash
$ docker image ls -a
```
这样会看到很多无标签的镜像与之前的虚悬镜像不同这些无标签的镜像很多都是中间层镜像是其它镜像所依赖的镜像这些无标签镜像不应该删除否则会导致上层镜像因为依赖丢失而出错实际上这些镜像也没必要删除因为之前说过相同的层只会存一遍而这些镜像是别的镜像的依赖因此并不会因为它们被列出来而多存了一份无论如何你也会需要它们只要删除那些依赖它们的镜像后这些依赖的中间层镜像也会被连带删除
## 列出部分镜像
不加任何参数的情况下`docker image ls` 会列出所有顶层镜像但是有时候我们只希望列出部分镜像`docker image ls` 有好几个参数可以帮助做到这个事情
根据仓库名列出镜像
```bash
$ docker image ls ubuntu
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 f753707788c5 4 weeks ago 127 MB
ubuntu latest f753707788c5 4 weeks ago 127 MB
```
列出特定的某个镜像也就是说指定仓库名和标签
```bash
$ docker image ls ubuntu:18.04
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 f753707788c5 4 weeks ago 127 MB
```
除此以外`docker image ls` 还支持强大的过滤器参数 `--filter`或者简写 `-f`之前我们已经看到了使用过滤器来列出虚悬镜像的用法它还有更多的用法比如我们希望看到在 `mongo:3.2` 之后建立的镜像可以用下面的命令
```bash
$ docker image ls -f since=mongo:3.2
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 5f515359c7f8 5 days ago 183 MB
nginx latest 05a60462f8ba 5 days ago 181 MB
```
想查看某个位置之前的镜像也可以只需要把 `since` 换成 `before` 即可
此外如果镜像构建时定义了 `LABEL`还可以通过 `LABEL` 来过滤
```bash
$ docker image ls -f label=com.example.version=0.1
...
```
## 以特定格式显示
默认情况下`docker image ls` 会输出一个完整的表格但是我们并非所有时候都会需要这些内容比如刚才删除虚悬镜像的时候我们需要利用 `docker image ls` 把所有的虚悬镜像的 ID 列出来然后才可以交给 `docker image rm` 命令作为参数来删除指定的这些镜像这个时候就用到了 `-q` 参数
```bash
$ docker image ls -q
5f515359c7f8
05a60462f8ba
fe9198c04d62
00285df0df87
f753707788c5
f753707788c5
1e0c3dd64ccd
```
`--filter` 配合 `-q` 产生出指定范围的 ID 列表然后送给另一个 `docker` 命令作为参数从而针对这组实体成批的进行某种操作的做法在 Docker 命令行使用过程中非常常见不仅仅是镜像将来我们会在各个命令中看到这类搭配以完成很强大的功能因此每次在文档看到过滤器后可以多注意一下它们的用法
另外一些时候我们可能只是对表格的结构不满意希望自己组织列或者不希望有标题这样方便其它程序解析结果等这就用到了 [Go 的模板语法](https://gohugo.io/templates/go-templates/)。
比如下面的命令会直接列出镜像结果并且只包含镜像ID和仓库名
```bash
$ docker image ls --format "{{.ID}}: {{.Repository}}"
5f515359c7f8: redis
05a60462f8ba: nginx
fe9198c04d62: mongo
00285df0df87: <none>
f753707788c5: ubuntu
f753707788c5: ubuntu
1e0c3dd64ccd: ubuntu
```
或者打算以表格等距显示并且有标题行和默认一样不过自己定义列
```bash
$ docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
IMAGE ID REPOSITORY TAG
5f515359c7f8 redis latest
05a60462f8ba nginx latest
fe9198c04d62 mongo 3.2
00285df0df87 <none> <none>
f753707788c5 ubuntu 18.04
f753707788c5 ubuntu latest
```