Docker 镜像的使用:获取、查看、搜索、删除、创建、存出和载入、上传
镜像是 Docker 三大核心概念中最重要的。Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在, Docker 会尝试先从默认镜像仓库下载(默认使用 Docker Hub 公共注册服务器中的仓库),用户也可以通过配置,使用自定义的镜像仓库。
一、获取镜像
镜像是运行容器的前提,官方的 Docker Hub 网站已经提供了数十万个镜像供大家开放下载。可以使用 Docker 镜像的 pull 子命令来下载镜像。格式如下:
docker [image] pull NAME [: TAG]
- NAME 是镜像仓库名称(用来区分镜像)
- TAG 是镜像的标签(往往用来表示版本信息)
通常情况下,描述一个镜像需要包括“名称+标签”信息。
如获取一个 Ubuntu 18.04 系统的基础镜像可以使用如下的命令:
$ docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
... ...
对于 Docker 镜像来说,如果不显式指定 TAG, 则默认会选择 latest 标签,会下载仓库中最新版本的镜像。
下载过程中可以看出,镜像文件一般由若干层 (layer) 组成, 6c953ac5d795 这样的串是层的唯一 id (实际上完整的 id 包括 256 比特, 64 个十六进制字符组成)。使用 docker pull 命令下载中会获取并输出镜像的各层信息。当不同的镜像包括相同的层时,本地仅存
储了层的一份内容,减小了存储空间。
严格来说,镜像的仓库名称中还应该添加仓库地址(即 registry, 注册服务器)作为前缀,只是默认使用的是官方 Docker-Hub 服务,该前缀可以忽略。如下:
docker pull ubuntu:18.04 命令相当于 docker pull regisry.hub.docker.com/ubuntu:18.04,即从默认的注册服务器 Docker Hub Registy 中的 ubuntu 仓库来下载标记为 18.04 的镜像。
如果从非官方的仓库下载,则需要在仓库名称前指定完整的仓库地址。如从网易蜂巢的镜像源来下载镜像,可以使用如下命令,此时下载的镜像名称为 hub.c.163.com/public/ubuntu:18.04
$ docker pull hub.c.163.com/public/ubuntu:18.04
pull 子命令支持的选项主要包括:
- -a, --all-tags=true|false: 是否获取仓库中的所有镜像,默认为否;
- --disable-content-trust:取消镜像的内容校验,默认为真。
另外,有时需要使用镜像代理服务来加速 Docker 镜像获取过程,可以在 Docker 服务启动配置中增加 --regisry-mirror==proxy_URL 来指定镜像代理服务地址。
二、查看镜像信息
Docker 查看镜像的子命令包括 ls、tag、inspect等。
1、 使用 images 命令列出镜像
使用 docker images 或者 docker image ls 命令可以列出本地主机上已有镜像的基本信息。如下:
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
app_server latest fe9b4f782e3a 15 hours ago 672MB
<none> <none> d167787bebe1 17 hours ago 685MB
mysql 5.7.41 0018a8d83892 4 months ago 455MB
mysql latest 4073e6a6f542 4 months ago 530MB
ubuntu latest 08d22c0ceb15 4 months ago 77.8MB
ubuntu 15.10 9b9cb95443b5 7 years ago 137MB
- REPOSITORY 镜像来自于哪个仓库,比如 ubuntu 表示 ubuntu 系列的基础镜像;
- TAG 镜像的标答信息,比如 18.04、latest 表示不同的版本信息。标签只是标记,并不能标识镜像内容;
- IMAGE ID 镜像的 ID(唯一标识镜像),如果两个镜像的 ID 相同,说明它们实际上指向了同一个镜像,只是具有不同标签名称而已;
- CREATED 创建时间,说明镜像最后的更新时间;
- SIZE 镜像大小,优秀的镜像往往体积都较小。
其中镜像的 ID 信息十分重要,它唯一标识了镜像。在使用镜像 ID 的时候,一般可以使用该 ID 的前若干个字符组成的可区分串来替代完整的 ID;TAG 信息用于标记来自同一个仓库的不同镜像。例如 ubuntu 仓库中有多个镜像,通过TAG 信息来区分发行版本,如 18.04 18.10 等。镜像大小信息只是表示了该镜像的逻辑体积大小,实际上由于相同的镜像层本地只会存储一份,物理上占用的存储空间会小于各镜像逻辑体积之和。
images 子命令主要支持如下选项
- -a, --all=true|false: 列出所有(包括临时文件)镜像文件,默认为否;
- --digests=true|false: 列出镜像的数字摘要值,默认为否;
- -f, --filter=[]:过滤列出的镜像,如 dangling=true 只显示没有被使用的镜像;也可指定带有特定标注的镜像等;
- --format="TEMPLATE":控制输出格式,如.ID 代表 ID 信息,Repository代表仓库信息等;
- --no-trunc=true|false :对输出结果中太长的部分是否进行截断,如镜像的 ID 信息,默认为是;
- -q,--quiet=true|false :仅输出 ID 信息,默认为否。
更多子命令选项还可以通过 man docker-images 来查看。
2、使用 tag 命令添加镜像标签
使用 docker tag 命令来为本地镜像添加新的标签。例如,添加一个新的 myubuntu:latest 镜像标签:
# docker tag ubuntu:lates myubuntu:lates
再次使用 docker images 列出本地主机上镜像信息,可以看到多了一个 myubuntu:latest 标签的镜像:
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
app_server latest fe9b4f782e3a 15 hours ago 672MB
<none> <none> d167787bebe1 17 hours ago 685MB
mysql 5.7.41 0018a8d83892 4 months ago 455MB
mysql latest 4073e6a6f542 4 months ago 530MB
myubuntu latest 08d22c0ceb15 4 months ago 77.8MB
ubuntu latest 08d22c0ceb15 4 months ago 77.8MB
ubuntu 15.10 9b9cb95443b5 7 years ago 137MB
之后,用户就可以直接使用 myubuntu:latest 来表示这个镜像了。myubuntu:latest 镜像的 ID 与 ubuntu:latest 是完全一致的,它们实际上指向了同一个镜像文件,只是别名不同而已。 docker tag 命令添加的标签实际上起到了类似链接的作用。
3、使用 inspect 命令查看详细信息
使用 docker [image] inspect 命令可以获取该镜像的详细信息,包括制作者、适应架构、各层的数字摘要等,如下:
# docker image inspect ubuntu:15.10
... ...
上面返回的是一个 JSON 格式的消息,如果我们只要其中一项内容时,可以使用 -f 来指定,例如,获取镜像的 Architecture:
# docker image inspect -f {{".Architecture"}} ubuntu:15.10
amd64
4、使用 history 命令查看镜像历史
使用 history 子命令,该命令将列出各层的创建信息。例如,查看 ubuntu:15.10 镜像的创建过程,可以使用如下命令:
# docker history ubuntu:15.10
IMAGE CREATED CREATED BY SIZE COMMENT
9b9cb95443b5 7 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 7 years ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$… 1.86kB
<missing> 7 years ago /bin/sh -c rm -rf /var/lib/apt/lists/* 0B
<missing> 7 years ago /bin/sh -c set -xe && echo '#!/bin/sh' > /… 745B
<missing> 7 years ago /bin/sh -c #(nop) ADD file:d5d47c6a963e950e7… 137MB
注意,过长的命令被自动截断了,可以使用前面提到的 --no-trunc 选项来输出完整命令。
三、搜寻镜像
使用 docker search 命令可以搜索 Docker Hub 官方仓库中的镜像。语法如下:
docker search [option] keyword
选项:
- -f, --filter filter: 过滤输出内容;
- --format string: 格式化输出内容;
- --limit int:限制输出结果个数,默认为 25 个;
- --no-trunc :不截断输出结果。
例如,搜索官方提供的带 nginx 关键字的镜像,如下所示:
# docker search --filter=is-official=true nginx
再比如,搜索所有收藏数超过4的、关键词包括 tensorflow 的镜像:
$ docker search --filter=stars=4 tensorflow
四、删除和清理镜像
1、使用标签删除镜像
使用 docker rmi 或 docker image rm 命令可以删除镜像。
命令格式:docker rmi IMAGE [IMAGE...]
其中 IMAGE 可以为标签或 ID
选项:
- -f, -force :强制删除镜像,即使有容器依赖它;
- -no-prune: 不要清理未带标签的父镜像。
例如
# docker rmi busybox:latest
2、使用镜像 ID 来删除镜像
当使用 docker rmi 命令,并且后面跟上镜像的 ID(也可以是能进行区分的部分 ID 前缀)时,会先尝试删除所有指向该镜像的标签,然后删除该镜像文件本身。注意,当有该镜像创建的容器存在时,镜像文件默认是无法被删除的。
使用 docker ps -a 命令可以看到本机上存在的所有容器:
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c9ec18d27340 app_server "java -jar /app_serv…" 15 hours ago Up 15 hours 0.0.0.0:8090->8090/tcp, :::8090->8090/tcp app_serverx
f1ad0fb8ea16 d167787bebe1 "java -jar /app_serv…" 17 hours ago Exited (0) 17 hours ago app_server2
d1fb6350d55d d167787bebe1 "java -jar /app_serv…" 17 hours ago Exited (0) 17 hours ago app_server1
ab76d4e804c0 d167787bebe1 "java -jar /app_serv…" 18 hours ago Exited (0) 18 hours ago app_server
试图删除镜像, Docker 会提示有容器正在运行,无法删除。如果要想强行删除镜像,可以使用 -f 参数:
$ docker rmi -f ubuntu:15.10
注意,通常并不推荐使用 -f 参数来强制删除一个存在容器依赖的镜像。正确的做法是先删除依赖该镜像的所有容器,再来删除镜像。如下:
首先删除容器 ID 为 a21c0840213e 的容器:
$ docker rm a2lc0840213e
然后使用镜像 ID 来删除镜像:
$ docker rmi 8flbd2lbd25c
3、清理镜像
使用 Docker 一段时间后,系统中可能会遗留一些临时的镜像文件,以及一些没有被使用的镜像,可以通过 docker image prune 命令来进行清理。
支持选项包括:
- -a, -all: 删除所有无用镜像,不光是临时镜像;
- -filter filter: 只清理符合给定过滤器的镜像;
- -f, -force: 强制删除镜像,而不进行提示确认。
例如,如下命令会自动清理临时的遗留镜像文件层,最后会提示释放的存储空间:
$ docker image prune -f
...
Total reclaimed space: 1.4 GB
五、创建镜像
创建镜像的方法主要有三种:基于已有镜像的容器创建、基于本地模板导入、基于 Dockerfile 创建。
1、基于已有容器创建
该方法主要是使用 docker [container] commit 命令。
命令格式:docker [container] commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
选项包括:
- -a, --author="":作者信息;
- -c, --change=[]:提交的时候执行 Dockerfile 指令,包括 CMD|ENTRYPOINT|ENV|EXPOSE|LABEL|ONBUILD|USER|VOLUME|WORKDIR 等;
- -m, --message="":提交消息;
- -p, --pause=true:提交时暂停容器运行。
实例:创建一个新镜像。
首先,启动一个镜像,并在其中进行修改操作。例如,创建一个 test 文件,之后退出,如下:
[root@localhost ~]# docker run -it ubuntu:18.04 /bin/bash
root@3c3c4a522b56:/# touch test
root@3c3c4a522b56:/# exit
exit
[root@localhost ~]#
其容器的 ID 为 3c3c4a522b56,如果此时该容器与已有的 ubuntu:18.04 镜像相比,已经发生了改变,可以使用 docker [container] commit 命令来提交为一个新的镜像。提交时可以使用 ID 或名称来指定容器:
$ docker container commit -m "Added a new file" -a "Docker Newbee" 3c3c4a522b56 test:0.1
9e9c814023bcffc3e67e892a235afe61b02f66a947d2747f724bd317dda02f27
顺利的话,会返回新创建镜像的 ID 信息。此时查看本地镜像列表,会发现新创建的镜像已经存在了。
2、基于本地模板导入
用户也可以直接从一个操作系统模板文件导入一个镜像,主要使用 docker [container] import 命令。
命令格式:docker [image] import [OPTIONS] file|URL|-[REPOSITORY[:TAG]]
要直接导入一个镜像,可以使用 OpenVZ 提供的模板来创建,或者用其他已导出的镜像模板来创建。 OPENVZ 模板的下载地址为 http://openvz.org/Download/templates/precreated
例如,下载了 ubuntu-18.04 的模板压缩包,之后使用以下命令导入即可:
$ cat ubuntu-18.04-x86_64-minimal.tar.gz | docker impert-ubuntu:18.04
然后查看新导入的镜像,已经在本地存在了。
3、基于 Dockerfile 创建
基于 Dockerfile 创建是最常见的方式。 Dockerfile 是一个文本文件,利用给定的指令描述基于某个父镜像创建新镜像的过程。
下面给出 Dockerfile 的一个简单示例,基于 debian:stretch-slim 镜像安装 Python 3 环境,构成一个新的 Python:3 镜像:
FROM debian:stretch-slim
LABEL version="1.0" maintainer="docker user <docker_user@github>"
RUN apt-get update && \
apt-get install -y Python3 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
创建镜像的过程可以使用 docker [image] build 命令,编译成功后本地将多出一个 Python:3 镜像:
$ docker image build -t Python:3
Successfully built 4bl0f46eacc8
Successfully agged PY hon:3
$ docker images | grep python
六、存出和载入镜像
使用 docker [image] save 和 docker [image] load 命令可以用来存出和载入镜像。
1、存出镜像
如果要导出镜像到本地文件,可以使用 docker [image] save 命令。该命令支持-o、-output string 参数,导出镜像到指定的文件中。
例如,导出本地的 ubuntu:18.04 镜像为文件 ubuntu_18.04.tar ,如下:
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL ZE
ubun 18.04 0458a4468cbc 2 weeks ago 188·MB
...
$ docker save -o ubuntu_18.04.tar ubuntu:18.04
之后,用户就可以通过复制 ubuntu_18.04.tar 文件将该镜像分享给他人。
2、载入镜像
可以使用 docker [image] load 将上面导出的 tar 文件再导入到本地镜像库。支持 -i、input-string 选项,从指定文件中读入镜像内容。
例如,从文件 ubuntu_18.04.tar 导入镜像到本地镜像列表,如下所示:
$ docker load -i ubuntu_18.04.tar
或者:
$ docker load < ubuntu_18.04.tar
这将导入镜像及其相关的元数据信息(包括标签等)。导入成功后,可以使用 docker images 命令进行查看,与原镜像一致。
七、上传镜像
使用 docker [image] push 命令上传镜像到仓库,默认上传到 Docker Hub 官方仓库(需要登录)。
命令格式:docker [image] push NAME[:TAG] | [REGISTRY_HOST[: REGISTRY_PORT]/]NAME[:TAG]
用户在 Docker Hub 网站注册后可以上传自制的镜像。
例如,用户 user 上传本地的 test:latest 镜像,可以先添加新的标签 user/test:latest ,然后用 docker [image] push 命令上传镜像,如下:
$ docker tag test:latest user/test:latest
$ docker push user/test:latest
The push refers to a repository [docker.io/user/test]
Sending image list
Please login prior push:
Username:
Password:
Email:
第一次上传时,会提示输入登录信息或进行注册,之后登录信息会记录到本地~/.docker目录下。