0%

Docker 镜像的使用

获取镜像

docker pull 命令用于从Docker Registry 中获取指定镜像到当前服务器中, 命令格式为:

1
2
3
4
5
6
7
[root@VM-0-13-centos ~]# docker pull --help
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Pull an image or a repository from a registry
Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
--help Print usage

上面的NAME就是Docker Image 的资源地址, 就像URL一样, 那么docker pull 命令可以表示为docker pull dockerRegistry:port/repository:tag.

  • 默认dockerRegistry 为官方库Docker Hub, 域名为docker.io;
  • 默认repository 为官方镜像library;
  • 默认 taglatest;

所以 docker pull docker.io/library/nginx == docker pull nginx;

1
2
3
4
5
6
7
8
9
10
11
12
[root@VM-0-13-centos ~]# docker pull nginx
Using default tag: latest
Trying to pull repository docker.io/library/nginx ...
latest: Pulling from docker.io/library/nginx
bd159e379b3b: Pull complete
8d634ce99fb9: Pull complete
98b0bbcc0ec6: Pull complete
6ab6a6301bde: Pull complete
f5d8edcd47b1: Pull complete
fe24ce36f968: Pull complete
Digest: sha256:2f770d2fe27bc85f68fd7fe6a63900ef7076bc703022fe81b980377fe3d27b70
Status: Downloaded newer image for docker.io/nginx:latest

从上面的docker log 可以发现, 首先使用了默认tag latest, 并随后表示从docker.io/library/nginx 库获得对应镜像;

查看镜像

docker image ls 命令, 用于查看当前服务器上存在的镜像;

1
2
3
4
5
6
7
8
9
[root@VM-0-13-centos ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 33a05755d7f3 35 minutes ago 142 MB
docker.io/nginx latest 51086ed63d8c 21 hours ago 142 MB
docker.io/ubuntu 18.04 71cb16d32be4 34 hours ago 63.1 MB
<none> <none> 618d482e06b4 2 months ago 52.6 MB
<none> <none> 4c0257ee9d10 2 months ago 5.53 MB
docker.io/ubuntu latest 27941809078c 4 months ago 77.8 MB
docker.io/centos latest 5d0da3dc9764 12 months ago 231 MB

列表中包含项有: 仓库名, 标签, 镜像ID, 创建时间, 占用空间大小; 镜像ID 是镜像的唯一标识, 需要注意的是一个镜像可以包含有多个标签;

  • 关于镜像体积:

    1. Docker Hub 上的镜像体积, 通常小于本地所占空间, 这是由于Docker Hub 显示的为压缩体积, 在镜像下载与上传时使用, 本地空间为解压后的体积;

    2. docker image ls 显示的镜像体积之和, 并非一定是所有镜像的实际硬盘消耗; 这是由于Docker Image 采用多层存储接口, 允许相同层的复用与继承; 可以通过 docker system df 查看镜像, 容器, 存储卷所占用的空间;

      1
      2
      3
      4
      5
      [root@VM-0-13-centos ~]# docker system df
      TYPE TOTAL ACTIVE SIZE RECLAIMABLE
      Images 7 6 566.5 MB 210.4 MB (37%)
      Containers 13 2 9.852 MB 9.85 MB (99%)
      Local Volumes 0 0 0 B 0 B
  • 关于虚悬镜像:

    上面的镜像列表中, 存在两个仓库名与标签均为<none> 的镜像, 这就是虚悬镜像; 这些镜像,原本是存在仓库名与标签的, 两种情况下会导致为<none>;

    • docker pull: 例如官方镜像进行了维护, 发布了新版本, 重新拉取镜像A 后, A 的仓库名与标签迁移到新下载A'的镜像上, 原镜像A 相关属性置为<none>;
    • docker build: 构建一个同名,同标签的镜像 A' 会导致原镜像A, 相关属性置为<none>;

    可以通过 docker image ls -f dangling=true 查看虚悬镜像:

    1
    2
    3
    4
    [root@VM-0-13-centos ~]# docker image ls -f dangling=true
    REPOSITORY TAG IMAGE ID CREATED SIZE
    <none> <none> 618d482e06b4 2 months ago 52.6 MB
    <none> <none> 4c0257ee9d10 2 months ago 5.53 MB

    通常来说, 虚悬镜像没有价值, 可以通过 docker image prune 命令删除:

    1
    2
    3
    4
    [root@VM-0-13-centos ~]# docker image prune
    WARNING! This will remove all dangling images.
    Are you sure you want to continue? [y/N] y
    Total reclaimed space: 0 B
  • 关于中间层镜像:

    通过docker image ls -a 可以看到中间层镜像, docker image ls 默认显示顶层镜像;很多无标签的镜像是中间层镜像, 这些镜像并不是虚悬镜像, 也无法删除;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [root@VM-0-13-centos ~]# docker image ls -a
    REPOSITORY TAG IMAGE ID CREATED SIZE
    nginx v2 33a05755d7f3 About an hour ago 142 MB
    docker.io/nginx latest 51086ed63d8c 21 hours ago 142 MB
    docker.io/ubuntu 18.04 71cb16d32be4 34 hours ago 63.1 MB
    <none> <none> 618d482e06b4 2 months ago 52.6 MB
    <none> <none> 1eaace73d9c9 2 months ago 5.53 MB
    <none> <none> 4c0257ee9d10 2 months ago 5.53 MB
    <none> <none> 0dd3d5655279 2 months ago 5.53 MB
    docker.io/ubuntu latest 27941809078c 4 months ago 77.8 MB
    <none> <none> e66264b98777 4 months ago 5.53 MB
    docker.io/centos latest 5d0da3dc9764 12 months ago 231 MB

    可以看到的镜像变多了;

  • 查看部分镜像:

    仅列举, 细节可看官方文档;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    docker image ls ubuntu
    // 获得仓库名为 ubuntu 的镜像
    docker image ls ubuntu:18.04
    // 获得仓库名为ubuntu 版本为 18.04 的镜像
    docker image ls -f since=mongo:3.2
    // 查看在 mongo:3.2 镜像之后下载的所有
    docker image ls -f before=mongo:3.2
    // 查看在 mongo:3.2 镜像之前下载的所有
    docker image ls -f label=0.1
    // 查看特定标签的镜像
  • 格式化镜像输出:

    仅列举, 细节可看官方文档;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@VM-0-13-centos ~]# docker image ls --format "table {{.ID}}\t{{.Repository}}"
    IMAGE ID REPOSITORY
    33a05755d7f3 nginx
    51086ed63d8c docker.io/nginx
    71cb16d32be4 docker.io/ubuntu
    618d482e06b4 <none>
    4c0257ee9d10 <none>
    27941809078c docker.io/ubuntu
    5d0da3dc9764 docker.io/centos

    删除镜像

docker image rm 用于删除镜像:

1
2
3
4
5
6
7
8
9
[root@VM-0-13-centos ~]# docker image rm --help
Usage: docker image rm [OPTIONS] IMAGE [IMAGE...]
Remove one or more images
Aliases:
rm, rmi, remove
Options:
-f, --force Force removal of the image
--help Print usage
--no-prune Do not delete untagged parents

命令中的IMAGE 可以是 镜像短ID, 镜像长ID, 镜像名, 镜像摘要, 例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@VM-0-13-centos ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 33a05755d7f3 About an hour ago 142 MB
docker.io/nginx latest 51086ed63d8c 22 hours ago 142 MB
docker.io/ubuntu 18.04 71cb16d32be4 35 hours ago 63.1 MB
<none> <none> 618d482e06b4 2 months ago 52.6 MB
<none> <none> 4c0257ee9d10 2 months ago 5.53 MB
docker.io/ubuntu latest 27941809078c 4 months ago 77.8 MB
docker.io/centos latest 5d0da3dc9764 12 months ago 231 MB
[root@VM-0-13-centos ~]# docker image rm 5d0da3dc9764
Untagged: docker.io/centos:latest
Untagged: docker.io/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Deleted: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
Deleted: sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59

这里采用ID 方式删除对应Image;其余的方式, 不赘述, 可通过文档或博客方式快速应用;需要注意的是上面的删除Log 中存在两种行为: UntaggedDeleted ;

1
2
3
4
5
6
7
8
如果观察上面这几个命令的运行输出信息的话,你会注意到删除行为分为两类,一类是 Untagged,另一类是 Deleted。我们之前介绍过,镜像的唯一标识是其 ID 和摘要,而一个镜像可以有多个标签。

因此当我们使用上面命令删除镜像的时候,实际上是在要求删除某个标签的镜像。所以首先需要做的是将满足我们要求的所有镜像标签都取消,这就是我们看到的 Untagged 的信息。因为一个镜像可以对应多个标签,因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像,如果是这种情况,那么 Delete 行为就不会发生。所以并非所有的 docker image rm 都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已。

当该镜像所有的标签都被取消了,该镜像很可能会失去了存在的意义,因此会触发删除行为。镜像是多层存储结构,因此在删除的时候也是从上层向基础层方向依次进行判断删除。镜像的多层结构让镜像复用变得非常容易,因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。直到没有任何层依赖当前层时,才会真实的删除当前层。这就是为什么,有时候会奇怪,为什么明明没有别的标签指向这个镜像,但是它还是存在的原因,也是为什么有时候会发现所删除的层数和自己 docker pull 看到的层数不一样的原因。

除了镜像依赖以外,还需要注意的是容器对镜像的依赖。如果有用这个镜像启动的容器存在(即使容器没有运行),那么同样不可以删除这个镜像。之前讲过,容器是以镜像为基础,再加一层容器存储层,组成这样的多层存储结构去运行的。因此该镜像如果被这个容器所依赖的,那么删除必然会导致故障。如果这些容器是不需要的,应该先将它们删除,然后再来删除镜像。
-- Docker 入门与实战