镜像、容器、仓库是Docker的三大核心概念,而镜像是Docker3大核心概念中最重要的。Docker运行容器前需要本地存在对应的镜像,如果镜像不存在,Docker会尝试先从默认镜像仓库下载(默认使用Docker Hub公共注册服务器中的仓库,下载的镜像默认存储在/var/lib/docker/目录下),用户也可以通过配置,使用自定义的镜像仓库。

1.搜索镜像

搜索镜像命令:docker search [option] keyword。支持的命令选项主要包括:
(1).-f,—filter filter:过滤输出内容
(2).—format string:格式化输出内容
(3).—limit int:限制输出结果个数,默认25个
(4).—no-trunc:不截断输出结果

例子:

  1. #搜索官方提供的带nginx关键字的镜像,且限制搜索结果个数为20个
  2. docker search --filter=is-official=true --limit=20 nginx
  3. #搜索收藏数超过4的关键字包括tensorflow的镜像
  4. docker search -f=start=4 tensorflow

docker search jdk搜索jdk的列表如下图:
11111111.png
NAME:镜像名称
DESCRIPTION:镜像描述
STARS:收藏数量
OFFICIAL:是否官方创建
AUTOMATED:是否自动创建

2.查看所有镜像列表

使用docker images 和docker images ls命令都能列出本地主机已有镜像列表。

REPOSITORY:标志镜像来源于那个仓库
TAG:镜像的标签信息,TAG信息用于标记来自同一仓库的不同镜像。例如ubuntu仓库中有多个镜像,通过TAG信息来区分发行版本,如18.04、18.10等
IMAGE ID:镜像id,如果两个镜像的ID相同,那么说明它们实际上指向了同一个镜像,只是具有不同标签名称而已
CREATED:创建时间,说明镜像最后的更新时间
SIZE:镜像大小,优秀的镜像往往体积较小

images完整命令为:docker images [options],images子命令主要支持如下选项:
(1).-a, —all=true|false:列出所有(包括临时文件)镜像文件,默认为否;
(2).—digests=true|false:列出镜像的数字摘要值,默认为否;
(3).-f, —filter=[]:过滤列出的镜像,如dangling=true只显示没有被使用的镜像;也可指定带有特定标注的镜像等;
(4).—format=”TEMPLATE”:控制输出格式,如.ID代表ID信息,.Repository代表仓库信息等;
(5).—no-trunc=true|false:对输出结果中太长的部分是否进行截断,如镜像的ID信息,默认为是;
(6).-q, —quiet=true|false:仅输出ID信息,默认为否。
其中,还支持对输出结果进行控制的选项,如-f. —filter=[]、—no-trunc=true|false、-q、—quiet=true|false等。
更多子命令选项还可以通过man docker-images来查看。

2.1使用tag命令添加镜像标签

为了方便在后续工作中使用特定镜像,还可以使用docker tag命令来为本地镜像任意添加新的标签,事实上为镜像添加标签其实就是起别名,源镜像与添加标签的镜像的镜像ID是相同,它们实际上都指向同一个镜像,只是别名不同而已。docker tag命令添加的标签实际上起到了类似链接的作用。

#为镜像打tag命令为,NAME表示镜像名称,:TAG表示镜像的tag,TARGETNAME表示镜像打tag别名,:TAG表示镜像打tag别名后的tag
docker tag NAME[:TAG] TARGETNAME[:TAG]
#例子:为java:8镜像打tag,别名为myjava:8,注意:打的tag名不能是大写或拥有特殊符号
docker tag java:8 myjava:8

例子示意图:
22222.png

2.2使用inspect命令查看镜像详细信息

使用docker[image]inspect命令可以获取该镜像的详细信息,包括制作者、适应架构、各层的数字摘要等

#查看镜像详细信息命令,NAME表示镜像名称,此命令可以获取镜像详细信息,如执行者、适应架构、各层的数字摘要等等
docker inspect NAME[:TAG]
#例子:获取java:8镜像详细信息
docker inspect java:8
#结果,返回一个JSON格式的信息
[
{
"Id": "sha256:d23bdf5b1b1b1afce5f1d0fd33e7ed8afbc084b594b9ccf742a5b27080d8a4a8",
"RepoTags": [
"java:8",
"myjava:8"
],
"RepoDigests": [
"java@sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d"
],
"Parent": "",
"Comment": "",
"Created": "2017-01-17T00:52:54.890877145Z",
"Container": "4b4ab1e131616e04a88f26f9811e5847dd0c3ec5f8178b634b388d3c510ee606",
"ContainerConfig": {
"Hostname": "33842653d6db",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"LANG=C.UTF-8",
"JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64",
"JAVA_VERSION=8u111",
"JAVA_DEBIAN_VERSION=8u111-b14-2~bpo8+1",
"CA_CERTIFICATES_JAVA_VERSION=20140324"
],
"Cmd": [
"/bin/sh",
"-c",
"/var/lib/dpkg/info/ca-certificates-java.postinst configure"
],
"ArgsEscaped": true,
"Image": "sha256:7cfe1ce37b990ea20d6377b8901f5ffccd463ed2f965e9730d834e693b53baec",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": [],
"Labels": {}
},
"DockerVersion": "1.12.3",
"Author": "",
"Config": {
"Hostname": "33842653d6db",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"LANG=C.UTF-8",
"JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64",
"JAVA_VERSION=8u111",
"JAVA_DEBIAN_VERSION=8u111-b14-2~bpo8+1",
"CA_CERTIFICATES_JAVA_VERSION=20140324"
],
"Cmd": [
"/bin/bash"
],
"ArgsEscaped": true,
"Image": "sha256:7cfe1ce37b990ea20d6377b8901f5ffccd463ed2f965e9730d834e693b53baec",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": [],
"Labels": {}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 643195347,
"VirtualSize": 643195347,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/7389f526c8464327ce02bcf6e059003403799ccf2a1d0704d120e2cb68438397/diff:/var/lib/docker/overlay2/c5ec74d4ca6eb22740ae3141edc0929335e6e173482d9f546e01ac32df69b36f/diff:/var/lib/docker/overlay2/19daf89abacaf96f92799d68dded17e1f6773c064a389858528534928574df2c/diff:/var/lib/docker/overlay2/bd7a6866a41c12f6753a41fd5798f85479b13b8021f984a0edf6382f5b376df8/diff:/var/lib/docker/overlay2/a6809e37eaf5df9794e32737a83870f5cfb3e5f706018745278b98e3f1493bc9/diff:/var/lib/docker/overlay2/b9ba62147cc46c3eea6310a5e48db9e8f8dd0d294e4d59c8cd1ffebf59502745/diff:/var/lib/docker/overlay2/b2b0deb7b63bd216d2e638e134e5b394f7bd9a6df3fe449911f71581cec77166/diff",
"MergedDir": "/var/lib/docker/overlay2/fc40dddba8b772f2414f0a8261ed71c1b9943395c7bb4f3051d635f4fcb0adb6/merged",
"UpperDir": "/var/lib/docker/overlay2/fc40dddba8b772f2414f0a8261ed71c1b9943395c7bb4f3051d635f4fcb0adb6/diff",
"WorkDir": "/var/lib/docker/overlay2/fc40dddba8b772f2414f0a8261ed71c1b9943395c7bb4f3051d635f4fcb0adb6/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:a2ae92ffcd29f7ededa0320f4a4fd709a723beae9a4e681696874932db7aee2c",
"sha256:0eb22bfb707db44a8e5ba46a21b2ac59c83dfa946228f04be511aba313bdc090",
"sha256:30339f20ced009fc394410ac3360f387351641ed40d6b2a44b0d39098e2e2c40",
"sha256:ce6c8756685b2bff514e0b28f78eedb671380084555af2b3833e54bb191b262a",
"sha256:a3483ce177ce1278dd26f992b7c0cfe8b8175dd45bc28fee2628ff2cf063604c",
"sha256:6ed1a81ba5b6811a62563b80ea12a405ed442a297574de7440beeafe8512a00a",
"sha256:c3fe59dd955634c3fa1808b8053353f03f4399d9d071be015fdfb98b3e105709",
"sha256:35c20f26d18852b74cc90afc4fb1995f1af45537a857eef042a227bd8d0822a3"
]
},
"Metadata": {
"LastTagTime": "2020-08-07T13:17:00.716285878-04:00"
}
}
]
#上面命令获取的信息太多了,如果想获取信息一项时,可以通过-f命令制定,如下面的命令
docker inspect -f {{".Id"}} java:8
#结果
sha256:d23bdf5b1b1b1afce5f1d0fd33e7ed8afbc084b594b9ccf742a5b27080d8a4a8

2.3使用history命令查看镜像历史

既然镜像文件由多个层组成,那么怎么知道各个层的内容具体是什么呢?这时候可以使用history子命令,该命令将列出各层的创建信息。可以通过docker history [options] keyword命令查看镜像历史

#查看镜像历史语法
docker history NAME[:TAG]
#例子:查看java:8镜像的历史
docker history java:8
#结果
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
d23bdf5b1b1b        3 years ago         /bin/sh -c /var/lib/dpkg/info/ca-certificate…   419kB
           3 years ago         /bin/sh -c set -x  && apt-get update  && apt…   352MB
           3 years ago         /bin/sh -c #(nop)  ENV CA_CERTIFICATES_JAVA_…   0B
           3 years ago         /bin/sh -c #(nop)  ENV JAVA_DEBIAN_VERSION=8…   0B
           3 years ago         /bin/sh -c #(nop)  ENV JAVA_VERSION=8u111       0B
           3 years ago         /bin/sh -c #(nop)  ENV JAVA_HOME=/usr/lib/jv…   0B
           3 years ago         /bin/sh -c {   echo '#!/bin/sh';   echo 'set…   87B
           3 years ago         /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0B
           3 years ago         /bin/sh -c echo 'deb http://deb.debian.org/d…   55B
           3 years ago         /bin/sh -c apt-get update && apt-get install…   1.29MB
           3 years ago         /bin/sh -c apt-get update && apt-get install…   123MB
           3 years ago         /bin/sh -c apt-get update && apt-get install…   44.3MB
           3 years ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
           3 years ago         /bin/sh -c #(nop) ADD file:89ecb642d662ee7ed…   123MB

3.获取镜像

这里先例举一个安装jdk8镜像的例子,如果不显示指定镜像的TAG,则默认会选择latest标签(latest标签意味着该镜像的内容是不稳定的,不建议在生产环境中使用latest标记的镜像),那么在安装时会使用最新版本,java目前最新版本是14,安装指定版本的镜像一般要查看镜像的版本列表。
获取镜像命令是:docker [image] pull [options] NAME:[TAG]。image是可选的,一般不写,NAME是镜像的名称,而TAG就是镜像的标签(一般指镜像的版本)

安装java8的例子:

docker pull java:8

镜像文件一般由若干层(layer)组成,6c953ac5d795这样的串是层的唯一id(实际上完整的id包括256比特,64个十六进制字符组成)。使用docker pull命令下载中会获取并输出镜像的各层信息。当不同的镜像包括相同的层时,本地仅存储了层的一份内容,减小了存储空间。
你可能会问在不同的镜像仓库服务器的情况下,会出现镜像重名的情况。严格地讲,镜像的仓库名称中还应该添加仓库地址(即registry,注册服务器)作为前缀,只是默认使用的是官方Docker Hub服务,该前缀可以忽略。

如果你想从非官方的仓库下载镜像,则需要在仓库名称前指定完整的仓库地址。例如从网易蜂巢的镜像源来下载ubuntu:18.04镜像,可以使用如下命令,此时下载的镜像名称为hub.c.163.com/public/ubuntu:18.04,那么docker获取命令为:

docker pull hub.c.163.com/public/ubuntu:18.04

pull命令的子选项为:
(1).-a, —all-tags=true|false:是否获取仓库中的所有镜像,默认为否;
(2).—disable-content-trust:取消镜像的内容校验,默认为真。
另外,有时需要使用镜像代理服务来加速Docker镜像获取过程,可以在Docker服务启动配置中增加—registry-mirror=proxy_URL来指定镜像代理服务地址(如https://registry.docker-cn.com)。

4.删除和清理镜像

4.1删除镜像

使用docker rmi或docker image rm命令可以删除镜像,命令格式为docker rmi [IMAGE…],IMAGE可以为是标签或ID。支持选包括
(1).-f, -force:强制删除镜像,即使有容器依赖它。
(2).-no-prune:不要清理未带标签的父镜像。

使用标签删除镜像:

docker rmi java:8 mysql:8

使用镜像id删除镜像,首先通过docker images查询到IMAGE ID,假设java:8的镜像id是d23bdf5b1b1b,那么删除命令就是:docker rmi d23bdf5b1b1b

4.2清理镜像

使用docker image prune命令临时镜像或未使用的镜像。支持选项包括:
(1).-a, -all:删除所有无用镜像,不光是临时镜像;
(2).-filter filter:只清理符合给定过滤器的镜像;
(3).-f, -force:强制删除镜像,而不进行提示确认。

例子:docker image prune -f,此命令会自动清理临时的遗留镜像文件层,最后会提示释放的存储空间。

5.创建镜像

创建镜像的方法主要有3种:基于已有镜像的容器创建、基于本地模板导入、基于Dockerfile创建。

5.1 基于已有容器创建镜像

此方法主要使用docker [container] commit命令创建镜像。
命令格式为docker [container] commit [OPTIONS] CONTAINER [REPOSITORY [:TAG]],主要选项包括:
❑ -a, —author=””:作者信息;
❑ -c, —change=[]:提交的时候执行Dockerfile指令,包括CMD|ENTRYPOINT|E NV|EXPOSE|LABEL|ONBUILD|USER|VOLUME|WORKDIR等;
❑ -m, —message=””:提交消息;
❑ -p, —pause=true:提交时暂停容器运行。

例子:
第一步新建一个容器,并在其中进行修改文件操作。例如,创建一个test文件后并退出

[root@localhost  zxp]# docker run -it java:8 /bin/bash 
root@3bc2b85eb056:/# touch test
root@3bc2b85eb056:/# exit

上面命令所产生的容器ID:为3bc2b85eb056,此时该容器与原java:8镜像相比,发生了改变,可以使用docker [container] commit命令提交一个新的镜像,提交时可以使用ID或名称来指定容器:

#提交镜像命令,-m 表示提交信息,-a 表示作者信息,3bc2b85eb056是指定已有容器Id,newimage:1是提交后新镜像的镜像名称
docker commit -m "基于已有容器创建镜像" -a "zxp" 3bc2b85eb056 newimage:1
#上面命令执行后,会返回创建镜像的ID信息,例如
sha256:2c7c473806042e15c7d2253829c1d59def5396e9c1ca3a782bc6931b4220916d

查看镜像列表,列表中含有刚刚创建的镜像:
1111111123123.png

5.2 基于本地模板导入

用户也可以直接从一个操作系统模板文件导入一个镜像,主要使用docker [container] import命令。命令格式为docker [image] import [OPTIONS] file|URL|-[REPOSITORY [:TAG]]

要直接导入一个镜像,可以使用OpenVZ提供的模板来创建,或者用其他已导出的镜像模板来创建。OPENVZ模板的下载地址为http://openvz.org/Download/templates/precreated

5.3 基于Dockerfile:

6.存出和载入镜像

6.1 存出镜像

#存出镜像命令,此命令支持-o、-output string参数,导出镜像到指定文件中
docker save [options] NAME[:TAG]
#例子
docker save -o java_8.tar java:8

效果图(命令执行后,当前目录生成了一个java_8.tar的文件):

33.png

6.2 载入镜像

#载入镜像命令。此命令支持-i -input string选项,从指定文件中读取镜像内容
docker load [options] NAME:[:TAG]
#例子 或者 docker load < java_8.tar
docker load -i java_8.tar

示意图:
3123123.png

7.上传镜像

使用docker push命令可以上传镜像到仓库,默认上传到Docker Hub官方仓库(需要登录)

#先注册docker Hub账号,输入以下命令登录docker
docker login
#上传镜像的命令
docker push NAME[:TAG] | [REGISTRY_HOST[:REGISTRY_PORT]/]NAME[:TAG]
#例子先打个tag
docker tag java:8 zxp/java:8
#上传到docker hub
docker push zxp/java:8

8.镜像相关的命令

#获取镜像,例子:docker pull java:8
docker pull NAME[:Tag]
#查看镜像,例子:docker search --filter=is-official=true --limit=20 nginx
docker search [option] keyword
#查看镜像列表
docker images
#删除镜像。根据TAG删除镜像:docker rmi java:8 mysql:8。根据镜像id删除镜像:docker rmi 镜像ID
docker rmi [image...]
#清理镜像
docker image prune
#基于已有容器创建镜像。例子:docker commit -m "基于已有容器创建镜像" -a "zxp" 3bc2b85eb056 newimage:1
docker commit -m "m表示提交信息" -a "表示作者信息" 容器ID或容器名称 NEWNAME[:TAG]
#保存镜像到本地。例子:docker save -o java_8.tar java:8,-o表示保存的输出路径
docker save [options] NAME[:TAG]
#载入镜像。例子:docker load -i java_8.tar,-i表示载入的输入路径
docker load [options] NAME:[TAG]
#上传镜像。例如:docker push zxp/java:8,zxp/java:8是我打tag后镜像
docker push NAME[:TAG] | [REGISTRY_HOST[:REGISTRY_PORT]/]NAME[:TAG]