Docker运行容器前需要本地存在对应的镜像,如果镜像没保存在本地,Docker会尝试先从默认镜像仓库下载(默认使用Docker Hub公共注册服务器的仓库),用户也可以通过配置,使用自定义的镜像仓库。
一、搜索镜像
使用docker search
命令可以搜索远端仓库中共享的镜像,默认搜索官方仓库中的镜像。
用法:docker search 关键字
支持的参数主要包括:
-f, --filter filter
:根据提供的条件过滤输出;
--format string
:使用go模板打印搜索结果;
--limit int
:最大搜索结果数(默认25)
--no-trunc
:输出信息不截断显示
如:
NAME:镜像名称
DESCRIPTION:描述
STARS:星级,代表受欢迎程度
OFFICIAL:是否为官方创建
AUTOMATED:是否自动创建
二、获取镜像
镜像是运行容器的前提,官方的Docker Hub网站已经提供了数十万个镜像供大家开放下载。
可以使用docker pull
命令直接从Docker Hub镜像源来下载镜像。该命令的格式为docker pull NAME[:TAG]
。其中,NAME是镜像仓库的名称(用来区分镜像),TAG是镜像的标签(往往用来表示版本信息)。
通常情况下,描述一个镜像需要包括“名称+标签”信息。
如: docker pull ubuntu:14.04
对于Docker镜像来说,如果不显示指定TAG,则默认会选择latest标签,这会下载仓库中新版本的镜像。
如:docker pull ubuntu
从下载过程中可以看出,镜像文件一般由若干层(layer)组成,da7391352a9b
这样的串是层的唯一id(实际上完整的id包括256比特,由64个十六进制字符组成)。使用docker pull
命令下载时会获取并输出镜像的各层信息。当不同的镜像包括相同的层时,本地仅存储层的一份内容,减小了需要的存储空间。
严格地讲,镜像的仓库名称中还应该添加仓库地址(即registry
,注册服务器)作为前缀,只是我们默认使用的是Docker Hub服务,该前缀可以忽略。
如:docker pull ubuntu
相当于docker pull registry.hub.docker.com/ubuntu:latest
,即从默认的注册服务器Docker Hub Registry中的ubuntu仓库来下载标记为latest的镜像。
如果从非官方的仓库下载,则需要在仓库名称前指定完整的仓库地址。例如从网易蜂巢的镜像源来下载ubuntu:14.04镜像,可以使用如下命令,此时下载的镜像名称为hub.c.163.com/public/ubuntu:14.04:docker pull hub.c.163.com/public/ubuntu:14.04
三、查看镜像信息
- 使用images命令列出镜像
使用docker images
命令可以列出本地主机上已有镜像的基本信息。
- REPOSITORY:来自于哪个仓库
- TAG:镜像的标签信息;标签只是标记,并不能标识镜像内容;TAG信息用来标记来自同一个仓库的不同镜像,通过TAG信息来区分发行版本。
- IMAGE ID:镜像的ID(唯一标识镜像);如果镜像ID相同,说明实际上指向同一个镜像;在使用镜像ID的时候,一般可以使用该ID的前若干个字符组成的可区分串来替代完整的ID。
- CREATED:创建时间;说明镜像后的更新时间。
- SIZE:镜像大小:优秀的镜像往往体积都较小。镜像大小信息只是表示该镜像的逻辑体积大小,实际上由于相同的镜像层本地只会存储一份,物理上占用的存储空间会小于各镜像的逻辑体积之和。
- 使用
docker tag
命令来为本地镜像任意添加新的标签。
可以看到mynginx和nginx的镜像ID是一致的,它们实际上指向同一个镜像文件,只是别名不同而已。docker tag命令添加的标签实际上起到了类似链接的作用。 - 使用inspect命令查看详细信息
使用docker inspect
命令可以获取该镜像的详细信息,包括制作者、适应架构、各层的数字摘要等:
[root@localhost ~]# docker inspect nginx:latest
[
{
"Id": "sha256:f6d0b4767a6c466c178bf718f99bea0d3742b26679081e52dbf8e0c7c4c42d74",
"RepoTags": [
"mynginx:1.0",
"nginx:latest"
],
"RepoDigests": [
"nginx@sha256:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa"
],
"Parent": "",
"Comment": "",
"Created": "2021-01-12T10:17:41.649267496Z",
"Container": "faa742a137cfbf261402d359c09203c3fd894fa49689e4f4952a657ea80d9107",
"ContainerConfig": {
"Hostname": "faa742a137cf",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.19.6",
"NJS_VERSION=0.5.0",
"PKG_RELEASE=1~buster"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"nginx\" \"-g\" \"daemon off;\"]"
],
"Image": "sha256:a5531bdc09faaa444e565e6f9ec98ed4474970ed6fdd5db6b8b255534b220689",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGQUIT"
},
"DockerVersion": "19.03.12",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.19.6",
"NJS_VERSION=0.5.0",
"PKG_RELEASE=1~buster"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"Image": "sha256:a5531bdc09faaa444e565e6f9ec98ed4474970ed6fdd5db6b8b255534b220689",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGQUIT"
},
"Architecture": "amd64",
"Os": "linux",
"Size": 132951424,
"VirtualSize": 132951424,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/17b28394f249a7743faf30e7d8117d334e8962a61c00f15de88bf80b5aff2ec6/diff:/var/lib/docker/overlay2/deb33ba0571cee63bc5566cca6620052e785262a58f8b4bdf4254b7ae89c8600/diff:/var/lib/docker/overlay2/cc583fe1e95372bdea0269c99fbbc4558baf4422903dcfd34c8d5a81a1f67341/diff:/var/lib/docker/overlay2/ae097c79795b3fc0c7eb256333591c76fedf558eb728fc0578fffd3c8e5a7611/diff",
"MergedDir": "/var/lib/docker/overlay2/932eadb0de8dc3d51363e92ba8df15478e46e6251b4df19b58d1230eaea2bdfc/merged",
"UpperDir": "/var/lib/docker/overlay2/932eadb0de8dc3d51363e92ba8df15478e46e6251b4df19b58d1230eaea2bdfc/diff",
"WorkDir": "/var/lib/docker/overlay2/932eadb0de8dc3d51363e92ba8df15478e46e6251b4df19b58d1230eaea2bdfc/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:cb42413394c4059335228c137fe884ff3ab8946a014014309676c25e3ac86864",
"sha256:1c91bf69a08b515a1f9c36893d01bd3123d896b38b082e7c21b4b7cc7023525a",
"sha256:56bc37de0858bc2a5c94db9d69b85b4ded4e0d03684bb44da77e0fe93a829292",
"sha256:3e5288f7a70f526d6bceb54b3568d13c72952936cebfe28ddcb3386fe3a236ba",
"sha256:85fcec7ef3efbf3b4e76a0f5fb8ea14eca6a6c7cbc0c52a1d401ad5548a29ba5"
]
},
"Metadata": {
"LastTagTime": "2021-03-10T15:43:46.58987369+08:00"
}
}
]
返回的是一个JSON格式的消息,如果我们只要其中一项内容时,可以使用参数-f来指定,例如,获取镜像的Architecture:
4. 使用history命令查看镜像历史,该命令将列出各层的创建信息。
docker history imagename:tag
四、删除镜像
使用docker rmi
命令可以删除镜像,命令格式为docker rmi IMAGE [IMAGE...]
,其中IMAGE可以为标签或ID。
如
注:出现上图情况是因为有依赖该镜像的容器被创建
当使用docker rmi
命令,并且后面跟上镜像的ID(也可以是能进行区分的部分ID串前缀)时,会先尝试删除所有指向该镜像的标签,然后删除该镜像文件本身。
注意:当有该镜像创建的容器存在时,镜像文件默认是无法被删除的。如果要想强行删除镜像,可以使用-f参数。注意,通常并不推荐使用-f参数来强制删除一个存在容器依赖的镜像。正确的做法是,先删除依赖该镜像的所有容器,再来删除镜像。
五、创建镜像
创建镜像的方法主要有三种:基于已有镜像的容器创建、基于本地模板导入、基于Dockerfile创建
- 基于已有镜像的容器创建
该方法主要是使用docker commit
命令。命令格式为docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
,主要选项包括:
-a, --author="":作者信息;
-c, --change=[]:提交的时候执行Dockerfile指令,包括CMD|ENTRYPOINT|ENV|EXPOSE|LABEL|ONBUILD|USER|VOLUME|WORKDIR等;
-m, --message="":提交消息;
-p, --pause=true:提交时暂停容器运行。
演示:
启动一个镜像,并在其中进行修改操作
注意该容器ID为86e9872a262a(容器ID与镜像ID不同)。
此时该容器与原centos镜像生成的容器已经不同,可以使用docker commit
命令来提交为一个新的镜像。
提交时可以使用ID或名称来指定容器:
成功了将返回新创建镜像的ID信息。可以运行测试test文件是否存在。
- 基于本地模板导入
用户也可以直接从一个操作系统模板文件导入一个镜像,主要使用docker import
命令。命令格式为docker import [OPTIONS] file|URL|-[REPOSITORY[:TAG]]
。
要直接导入一个镜像,可以使用OpenVZ提供的模板来创建,或者用其他已导出的镜像模板来创建。OPENVZ模板的下载地址为:https://download.openvz.org/template/precreated/
演示:
下载centos-7-x86_64.tar.gz的模板压缩包,之后使用docker import命令导入:
- 基于Dockerfile创建
该内容过多,后续单独用一篇文章写
六、导出和载入镜像
用户可以使用docker save
和docker load
命令来存出和载入镜像
- 导出镜像
之后用户就可以复制该文件将镜像分享给其他人使用 - 载入镜像
或
这将导入镜像及其相关的元数据信息(包括标签等)。导入成功后,可以使用docker images
命令进行查看。
七、上传镜像
用户可以通过docker push
命令,把自己创建的镜像上传到仓库中来共享。默认上传到Docker Hub官方仓库(需要登录),官网地址:https://hub.docker.com。
也可以搭建一个私有仓库在内部共享镜像
命令格式为:docker push NAME[:TAG] | [REGISTRY_HOST[:REGISTRY_PORT]/]NAME[:TAG]
-
申请docker hub账号
-
登录dockers hub,点击create a repository
-
为存在于本地的镜像打标签,命令如下:
docker tag <existing-image> <hub-user>/<repo-name>[:<tag>]
,这里的tag不指定就是latest。
其中:
XXXXXX是用户名
test是仓库名称
2.0是tag版本 -
在本地登录docker hub账号:
5.上传镜像:docker push <hub-user>/<repo-name>:<tag>
6.验证:
1)登录到docker hub查看:
2)使用命令拉取镜像查看是否成功:docker pull <hub-user>/<repo-name>:<tag>
注:一个仓库只能有一种镜像,但是可以有多个不同版本(可以理解为仓库名就是镜像名,仓库不同,镜像不同,同一仓库有同一镜像的多个版本)
多个仓库:
test仓库(镜像)不同tag: