镜像是 Docker 的三大组件之一。

镜像的唯一标识是其ID 和摘要,而一个镜像可以有多个标签。

镜像是多层存储,每一层是在前一层的基础上进行的修改;而容器同样也是多层存储,是在以镜像为基础层,在其基础上加一层作为容器运行时的存储层。

Docker 运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker 会从镜像仓库下载该镜像。

本章将介绍更多关于镜像的内容,包括:

  • 从仓库获取镜像;
  • 管理本地主机上的镜像;
  • 介绍镜像实现的基本原理。

 1. 获取镜像

Docker Hub 上有大量的高质量的镜像可以用,从 Docker 镜像仓库获取镜像的命令是 docker pull 。其命令格式为:

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

2. 列出镜像

$ sudo docker image ls
仓库名                 标签        镜像 ID          创建时间            所占用的空间
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
nginx                   latest    ae2feff98a0c    3 weeks ago     133MB
hello-world          latest    bf756fb1ae65   12 months ago   13.3kB

 3. 镜像体积

便捷的查看镜像、容器、数据卷所占用的空间

$ sudo docker system df
TYPE                 TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images                  2            2         132.9MB   0B (0%)
Containers            3            0         0B        0B
Local Volumes      0            0         0B        0B
Build Cache          0            0         0B        0B

4. 虚悬镜像 

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

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

$ docker image prune

5. 中间层镜像

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

$ docker image ls -a

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

6. 列出部分镜像

不加任何参数的情况下, docker image ls 会列出所有顶级镜像,但是有时候我们只希望列出部分镜像。 docker image ls 有好几个参数可以帮助做到这个事情。
根据仓库名列出镜像

$ 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
ubuntu 14.04 1e0c3dd64ccd 4 weeks ago 188 MB

列出特定的某个镜像,也就是说指定仓库名和标签

$ 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 之后建立的镜像,可以用下面的命令:

$ 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 来过滤。

$ docker image ls -f label=com.example.version=0.1
...

7. 以特定格式显示

默认情况下, docker image ls 会输出一个完整的表格,但是我们并非所有时候都会需要这些内容。比如,刚才删除虚悬镜像的时候,我们需要利用 dockerimage ls 把所有的虚悬镜像的 ID 列出来,然后才可以交给 docker image rm命令作为参数来删除指定的这些镜像,这个时候就用到了 -q 参数。

 8. 删除本地镜像
如果要删除本地的镜像,可以使用 docker image rm 命令,其格式为: 

$ docker image rm [选项] <镜像1> [<镜像2> ...]

9.用 ID、镜像名、摘要删除镜像
其中, <镜像> 可以是 镜像短 ID 、 镜像长 ID 、 镜像名 或者 镜像摘要 。比如我们有这么一些镜像:

$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 0584b3d2cf6d 3 weeks ago 196.5 MB
redis alpine 501ad78535f0 3 weeks ago 21.03 MB
docker latest cf693ec9b5c7 3 weeks ago 105.1 MB
nginx latest e43d811ce2f4 5 weeks ago 181.5

可以用镜像的完整 ID来删除镜像。使用脚本的时候可能会用长 ID,但是人工输入就太累了,所以更多的时候是用 短 ID 来删除镜像。 docker image ls 默认列出的就已经是短 ID 了,一般取前3个字符以上,只要足够区分于别的镜像就可以了。
比如这里,如果我们要删除 redis:alpine 镜像,可以执行:

$ docker image rm 501
Untagged: redis:alpine
Untagged: redis@sha256:f1ed3708f538b537eb9c2a7dd50dc90a706f7debd7e1196c9264edeea521a86d
Deleted: sha256:501ad78535f015d88872e13fa87a828425117e3d28075d0c117932b05bf189b7
Deleted: sha256:96167737e29ca8e9d74982ef2a0dda76ed7b430da55e321c071f0dbff8c2899b
Deleted: sha256:32770d1dcf835f192cafd6b9263b7b597a1778a403a109e2cc2ee866f74adf23
Deleted: sha256:127227698ad74a5846ff5153475e03439d96d4b1c7f2a449c7a826ef74a2d2fa
Deleted: sha256:1333ecc582459bac54e1437335c0816bc17634e131ea0cc48daa27d32c75eab3
Deleted: sha256:4fc455b921edf9c4aea207c51ab39b10b06540c8b4825ba57b3feed1668fa7c7

删除本地镜像
我们也可以用 镜像名 ,也就是 <仓库名>:<标签> ,来删除镜像。

$ docker image rm centos
Untagged: centos:latest
Untagged: centos@sha256:b2f9d1c0ff5f87a4743104d099a3d561002ac500db1b9bfa02a783a46e0d366c
Deleted: sha256:0584b3d2cf6d235ee310cf14b54667d889887b838d3f3d3033acd70fc3c48b8a
Deleted: sha256:97ca462ad9eeae25941546209454496e1d66749d53dfa2ee32bf1faabd239d38

当然,更精确的是使用 镜像摘要 删除镜像。
删除本地镜像

$ docker image ls --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
node slim sha256:b4f0e0bde
b578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228 6e0c4c8e3913 3 weeks ago 214 MB
$ docker image rm node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228
Untagged: node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228

用 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)

现在让我们以定制一个 Web 服务器为例子,来讲解镜像是如何构建的。

$ docker run --name webserver -d -p 80:80 nginx

这条命令会用 nginx 镜像启动一个容器,命名为 webserver , 并且映射了 80端口,这样我们可以用浏览器去访问这个 nginx 服务器。

直接用浏览器访问的话,我们会看到默认的 Nginx 欢迎页面。如图:

docker idea 入门 docker in practice_Docker

 

现在,假设我们非常不喜欢这个欢迎页面,我们希望改成欢迎 Docker 的文字,我们可以使用 docker exec 命令进入容器,修改其内容。

$ docker exec -it webserver bash
root@3729b97e8226:/# echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
root@3729b97e8226:/# exit
exit

我们以交互式终端方式进入 webserver 容器,并执行了 bash 命令,也就是获得一个可操作的 Shell。

然后,我们用 <h1>Hello, Docker!</h1> 覆盖了/usr/share/nginx/html/index.html 的内容。

现在我们再刷新浏览器的话,会发现内容被改变了。

docker idea 入门 docker in practice_docker idea 入门_02