镜像
镜像是Docker的三大核心概念之一。
Docker运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker会尝试先从默认镜像
仓库下载(默认使用Docker Hub公共注册服务器中的仓库),用户也可以通过配置,使用自定义的镜像仓库。
本篇文章要讲的是围绕镜像这一核心概念的具体操作,包含以下几个方面:
- 如何使用pull命令从Docker Hub仓库中下载镜像文件到本地
- 如何查看本地已有的镜像信息
- 如何在远端仓库使用search命令进行搜索和过滤
- 如何删除镜像标签和镜像文件
- 如何创建用户定制的镜像并且保存为外部文件,最后如何向Docker Hub仓库推送自己的镜像文件。
3.1 获取镜像
镜像是Docker容器运行的前提。
我们可以使用docker pull命令从网络上下载镜像。该命令的格式为docker pull NAME[:TAG]。对于Docker镜像来说,如果不显式地指定TAG,则默认会选择latest标签,即下载仓库中最新版本的镜像。
[root@private_vpn docker_test]# pwd
/docker_test
[root@private_vpn docker_test]# ls -l
total 0
[root@private_vpn docker_test]# docker pull ubuntu
Using default tag: latest
Trying to pull repository docker.io/library/ubuntu ...
latest: Pulling from docker.io/library/ubuntu
660c48dd555d: Pull complete
4c7380416e78: Pull complete
421e436b5f80: Pull complete
e4ce6c3651b3: Pull complete
be588e74bd34: Pull complete
Digest: sha256:7c67a2206d3c04703e5c23518707bdd4916c057562dd51c74b99b2ba26af0f79
[root@private_vpn docker_test]# ls -l
total 0
[root@private_vpn docker_test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/ubuntu latest 20c44cd7596f 7 days ago 122.8 MB
docker.io/centos latest d123f4e55e12 3 weeks ago 196.6 MB
根据上面的显示可以看出,pull完镜像后并没有在当前目前保存下一个文件,然后使用docker images
命令可以看出刚才pull下的镜像。
参数释义:
REPOSITORY: 来自哪个仓库,比如ubuntu仓库、centos仓库
TAG: 镜像的标签信息,如 latest
IMAGE ID: 镜像的ID号(唯一)
CREATE: 镜像创建的时间
SIZE: 镜像的大小
为了更方便的在后续工作种使用某个镜像,还可以使用docker tag
命令位本地镜像添加新的标签。
docker tag IMAGEID(镜像id) REPOSITORY:TAG(仓库:标签)
[root@private_vpn docker_test]# docker tag d123f4e55e12 docker.io/centos:CentOS7
[root@private_vpn docker_test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/ubuntu latest 20c44cd7596f 7 days ago 122.8 MB
docker.io/centos CentOS7 d123f4e55e12 3 weeks ago 196.6 MB
docker.io/centos latest d123f4e55e12 3 weeks ago 196.6 MB
3.2 查看镜像
查看镜像本地已有的镜像,比较简单,一条命令:
docker images
3.3 使用search命令进行搜索远端仓库镜像
使用docker search 命令可以搜索远端仓库中共享的镜像,默认搜索官方仓库中的镜像。用法为docker search TERM,支持的参数主要包括:
--automated=true|false: 仅显示自动创建的镜像,默认为否
--no-trunc=true|false: 输出信息不截断显示,默认为否
-s,--stars=X: 指定只显示评价为指定星级以上的镜像,默认为0,即输出所有镜像。
eg: 搜索所有自动创建的评价为3+的带nginx关键字的镜像,如下所示:
docker search --automated -s 3 nginx
3.4 删除镜像
使用镜像ID删除镜像
当使用docker rmi 命令后面跟上镜像ID(也可以是ID能进行区分的部分前缀串或镜像的标签)时,会尝试删除所有指向该镜像的标签,然后删除该镜像文件本身。
eg:
[root@private_vpn docker_test]# docker tag d123f4e55e12 docker.io/centos:CentOS7
[root@private_vpn docker_test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/ubuntu latest 20c44cd7596f 7 days ago 122.8 MB
docker.io/centos CentOS7 d123f4e55e12 3 weeks ago 196.6 MB
docker.io/centos latest d123f4e55e12 3 weeks ago 196.6 MB
[root@private_vpn docker_test]# docker rmi d123f4e55e12
Error response from daemon: conflict: unable to delete d123f4e55e12 (must be forced) - image is referenced in one or more repositories
[root@private_vpn docker_test]#
[root@private_vpn docker_test]# docker rmi -f d123f4e55e12
Untagged: docker.io/centos:CentOS7
Untagged: docker.io/centos:latest
Untagged: docker.io/centos@sha256:4565fe2dd7f4770e825d4bd9c761a81b26e49cc9e3c9631c58cfc3188be9505a
Deleted: sha256:d123f4e55e1200156d9cbcf4421ff6d818576e4f1e29320a408c72f022cfd0b1
Deleted: sha256:cf516324493c00941ac20020801553e87ed24c564fb3f269409ad138945948d4
根据上面可以看出先删除了我新创建的tag,然后删除镜像文件本身,值得注意的是另外添加了标签的镜像在常规删除的时候会报错,只有强制删除才起作用。
注意:当有该镜像创建的容器存在时,镜像文件默认是无法被删除的,例如:
现在我来删除已经存在的ubuntu镜像:
[root@private_vpn docker_test]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ebc03d33db4e 20c44cd7596f "/bin/bash" 9 minutes ago Exited (1) 8 minutes ago loving_mahavira
[root@private_vpn docker_test]# docker rmi 20c44cd7596f
Error response from daemon: conflict: unable to delete 20c44cd7596f (must be forced) - image is being used by stopped container ebc03d33db4e
看得出无法删除。那就试试强制删除,对于正在被容器使用的镜像慎用。
[root@private_vpn docker_test]# docker rmi -f 20c44cd7596f
Untagged: docker.io/ubuntu:latest
Untagged: docker.io/ubuntu@sha256:7c67a2206d3c04703e5c23518707bdd4916c057562dd51c74b99b2ba26af0f79
Deleted: sha256:20c44cd7596ff4807aef84273c99588d22749e2a7e15a7545ac96347baa65eda
[root@private_vpn docker_test]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ebc03d33db4e 20c44cd7596f "/bin/bash" 11 minutes ago Exited (1) 10 minutes ago loving_mahavira
[root@private_vpn docker_test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
看的出来镜像已经被删除,容器还在运行。
进入容器:
[root@private_vpn docker_test]# docker attach ebc03d33db4e
You cannot attach to a stopped container, start it first
可以看出此时容器已经进不去了,所以对于被容器使用的镜像的删除要慎重。
对于以上的实验,很多命令暂时未涉及,后面会讲到。此篇文章的例子主要是说明容器和镜像的关系。
综上,如果我们要删除镜像正确的操作步骤应该是:
- 先确认机器上存在的容器。
docker ps -a
- 然后删除依赖镜像的容器
docker rm 容器ID
- 最后再删除相关镜像文件
docker rmi 镜像ID
eg:
[root@private_vpn docker_test]# cat /tmp/docker.txt
www
[root@private_vpn docker_test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/centos latest d123f4e55e12 3 weeks ago 196.6 MB
[root@private_vpn docker_test]# docker run -t -i d123f4e55e12 /bin/bash
[root@ef6e7768c6e2 /]# ls -l /tmp/
total 4
-rwx------ 1 root root 836 Sep 11 15:53 ks-script-q6TWGF
-rw------- 1 root root 0 Sep 11 15:51 yum.log
[root@ef6e7768c6e2 /]#
上面看出我已经进入到新启动的容器内了。
exit退出容器
然后按照上面的步骤来正确的删除容器。
[root@private_vpn docker_test]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ef6e7768c6e2 d123f4e55e12 "/bin/bash" 2 minutes ago Exited (127) About a minute ago infallible_boyd
[root@private_vpn docker_test]# docker rm ef6e7768c6e2
ef6e7768c6e2
[root@private_vpn docker_test]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@private_vpn docker_test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/centos latest d123f4e55e12 3 weeks ago 196.6 MB
[root@private_vpn docker_test]# docker rmi d123f4e55e12
Untagged: docker.io/centos:latest
Untagged: docker.io/centos@sha256:4565fe2dd7f4770e825d4bd9c761a81b26e49cc9e3c9631c58cfc3188be9505a
Deleted: sha256:d123f4e55e1200156d9cbcf4421ff6d818576e4f1e29320a408c72f022cfd0b1
Deleted: sha256:cf516324493c00941ac20020801553e87ed24c564fb3f269409ad138945948d4
[root@private_vpn docker_test]#
[root@private_vpn docker_test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
测试成功。
3.5 创建镜像
创建镜像的方法主要有3种:基于已有镜像的容器创建、基于本地模板导入、基于Dockerfile创建。
此处先熟悉下前两种方式,而基于Dockerfile的创建方法会在后面详细说明。
1.基于已有镜像的容器创建
该方法主要是使用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=ture: 提交时暂停容器运行。
下面将演示如何使用该命令创建一个新镜像。首先,启动一个镜像,并在其中进行修改操作,可以创建一个test文件,之后退出:
基于centos镜像创建一个容器,并直接(-d参数)放入后台运行
[root@private_vpn ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/nginx latest 9e7424e5dbae 13 days ago 108.5 MB
docker.io/nuagebec/ubuntu latest 7c2ea61fd57e 2 weeks ago 329.4 MB
docker.io/ubuntu latest 20c44cd7596f 2 weeks ago 122.8 MB
docker.io/centos latest d123f4e55e12 4 weeks ago 196.6 MB
[root@private_vpn ~]# docker run -itd d123 /bin/bash #直接放入后台运行
375fb5e3f2baa65c002754ab339ae8291d88233821b7db0dddf2f43fd195dd38
[root@private_vpn ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
375fb5e3f2ba d123 "/bin/bash" 5 seconds ago Up 4 seconds admiring_rosalind
be037923b36f 7c2ea61fd57e "/bin/bash" 5 days ago Up 5 days 22/tcp cocky_blackwell
d1311a650a77 nginx "nginx -g 'daemon off" 5 days ago Up 5 days 0.0.0.0:80->80/tcp webserver
6935f8fff19c d123f4e55e12 "/bin/bash" 10 days ago Up 6 days grave_pasteur
进入容器并在相关目录下创建一个test文件且写入一定的内容:
[root@private_vpn ~]# docker exec -it 375 /bin/bash
[root@375fb5e3f2ba /]# ls -l /tmp/
total 4
-rwx------ 1 root root 836 Sep 11 15:53 ks-script-q6TWGF
-rw------- 1 root root 0 Sep 11 15:51 yum.log
[root@375fb5e3f2ba /]# echo "test123" >> /tmp/test
[root@375fb5e3f2ba /]# cat /tmp/test
test123
此时该容器跟原centos(镜像ID: d123f4e55e12)镜像相比,已经发生了变化,可以使用docker commit
命令来提交为一个新的镜像。提交时可以使用ID或名称来指定容器。
[root@private_vpn ~]# docker commit -m "Added a new file" -a "daquan" 375 test:0.1
sha256:56cb38d68ab4e5518e5a09d58abc342020342ed0244dec53b5082f80b1221a9b
[root@private_vpn ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test 0.1 56cb38d68ab4 6 seconds ago 196.6 MB
docker.io/nginx latest 9e7424e5dbae 13 days ago 108.5 MB
docker.io/nuagebec/ubuntu latest 7c2ea61fd57e 2 weeks ago 329.4 MB
docker.io/ubuntu latest 20c44cd7596f 2 weeks ago 122.8 MB
docker.io/centos latest d123f4e55e12 4 weeks ago 196.6 MB
此时可以看到多了一个镜像,ID为56cb38d68ab4。且生成了一个test仓库,tag是0.1。符合上面的命令输入。
2. 基于本地模板导入
用户也可以直接从一个操作系统模板文件导入一个镜像,主要使用docker import
命令。命令格式为docker import [options] file|URL|- [repository[:tag]]
要直接导入一个镜像,可以使用OpenVZ提供的模板来创建,或者用其他已导出的镜像模板来创建。OPENVZ模板的下载地址为https://openvz.org/Download/templates/precreated
eg: 下载了ubuntu-14.04-x86_64-minimal.tar.gz的模板压缩包后,之后使用以下命令导入:
cat ubuntu-14.04-x86_64-minimal.tar.gz|docker import - ubuntu:14.04-x86_64
如下所示:
[root@private_vpn ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test 0.1 56cb38d68ab4 17 minutes ago 196.6 MB
docker.io/nginx latest 9e7424e5dbae 13 days ago 108.5 MB
docker.io/nuagebec/ubuntu latest 7c2ea61fd57e 2 weeks ago 329.4 MB
docker.io/ubuntu latest 20c44cd7596f 2 weeks ago 122.8 MB
docker.io/centos latest d123f4e55e12 4 weeks ago 196.6 MB
[root@private_vpn ~]#
[root@private_vpn ~]# cat ubuntu-14.04-x86_64-minimal.tar.gz|docker import - ubuntu:14.04-x86_64
sha256:f52ea2cf900c9adfeae7e33010de9dd2a89a5988a883fed3377e5f962e5b6279
[root@private_vpn ~]#
[root@private_vpn ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04-x86_64 f52ea2cf900c 9 seconds ago 214.8 MB
test 0.1 56cb38d68ab4 17 minutes ago 196.6 MB
docker.io/nginx latest 9e7424e5dbae 13 days ago 108.5 MB
docker.io/nuagebec/ubuntu latest 7c2ea61fd57e 2 weeks ago 329.4 MB
docker.io/ubuntu latest 20c44cd7596f 2 weeks ago 122.8 MB
docker.io/centos latest d123f4e55e12 4 weeks ago 196.6 MB
可以看到我们刚才创建的镜像(f52ea2cf900c)已经有了,可以再以此镜像为基础创建一个容器并进入容器看看:
[root@private_vpn ~]# docker run -tid f52 /bin/bash
44eca7876e7c6806655edf539f4e1c313d109db114d5974842345798d1587f63
[root@private_vpn ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44eca7876e7c f52 "/bin/bash" 5 seconds ago Up 4 seconds ecstatic_babbage
375fb5e3f2ba d123 "/bin/bash" 29 minutes ago Up 29 minutes admiring_rosalind
be037923b36f 7c2ea61fd57e "/bin/bash" 5 days ago Up 5 days 22/tcp cocky_blackwell
d1311a650a77 nginx "nginx -g 'daemon off" 5 days ago Up 5 days 0.0.0.0:80->80/tcp webserver
6935f8fff19c d123f4e55e12 "/bin/bash" 10 days ago Up 6 days grave_pasteur
[root@private_vpn ~]#
[root@private_vpn ~]# docker exec -ti 44e /bin/bash
root@44eca7876e7c:/# ls
bin boot dev etc fastboot home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
root@44eca7876e7c:/#
root@44eca7876e7c:/# uname -r
3.10.0-327.10.1.el7.x86_64
至此,基于本地模板导入创建镜像的方式测试完了。
3.6 存出和载入镜像
用户可以使用docker save
和docker load
命令来存出和载入镜像。
1.存出镜像
如果要导出镜像到本地文件,可以使用docker save命令。例如,导出本地的ubuntu:14.04-x86_64镜像文件为Ubuntu_14.04.tar,如下所示:
[root@private_vpn ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04-x86_64 f52ea2cf900c About an hour ago 214.8 MB
test 0.1 56cb38d68ab4 About an hour ago 196.6 MB
docker.io/nginx latest 9e7424e5dbae 13 days ago 108.5 MB
docker.io/nuagebec/ubuntu latest 7c2ea61fd57e 2 weeks ago 329.4 MB
docker.io/ubuntu latest 20c44cd7596f 2 weeks ago 122.8 MB
docker.io/centos latest d123f4e55e12 4 weeks ago 196.6 MB
[root@private_vpn ~]#
[root@private_vpn ~]# docker save -o ubuntu_14.04.tar ubuntu:14.04-x86_64
[root@private_vpn ~]# ls -lh
total 291M
-rw-r--r-- 1 root root 36 Dec 2 19:08 1.txt
-rw-r--r-- 1 root root 14 Dec 6 00:48 test.txt
-rw------- 1 root root 216M Dec 6 16:11 ubuntu_14.04.tar
-rw-r--r-- 1 root root 75M Nov 27 2016 ubuntu-14.04-x86_64-minimal.tar.gz
之后,用户就可以通过复制"ubuntu_14.04.tar"文件将该镜像分享给其他人了。
那么,分享给别人后,别人又如何载入此镜像到自己的本地呢?
2. 载入镜像
可以使用docker load
将导出的tar文件再导入到本地镜像库,例如从文件"ubuntu_14.04.tar"导入镜像到本地镜像列表,如下所示:
[root@private_vpn ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test 0.1 56cb38d68ab4 About an hour ago 196.6 MB
docker.io/nginx latest 9e7424e5dbae 13 days ago 108.5 MB
docker.io/nuagebec/ubuntu latest 7c2ea61fd57e 2 weeks ago 329.4 MB
docker.io/ubuntu latest 20c44cd7596f 2 weeks ago 122.8 MB
docker.io/centos latest d123f4e55e12 4 weeks ago 196.6 MB
[root@private_vpn ~]#
[root@private_vpn ~]#
[root@private_vpn ~]# docker load --input ubuntu_14.04.tar
fd58c1324b91: Loading layer [==================================================>] 225.8 MB/225.8 MB
Loaded image: ubuntu:14.04-x86_64
[root@private_vpn ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04-x86_64 f52ea2cf900c About an hour ago 214.8 MB
test 0.1 56cb38d68ab4 About an hour ago 196.6 MB
docker.io/nginx latest 9e7424e5dbae 13 days ago 108.5 MB
docker.io/nuagebec/ubuntu latest 7c2ea61fd57e 2 weeks ago 329.4 MB
docker.io/ubuntu latest 20c44cd7596f 2 weeks ago 122.8 MB
docker.io/centos latest d123f4e55e12 4 weeks ago 196.6 MB
如上所示,镜像已载入。因为我只有一台机器做测试,所以我就先把之前的"ubuntu:14.04-x86_64"镜像文件删除了,然后再次导入"ubuntu_14.04.tar"镜像文件,可以看到创建了镜像。
这将导入镜像及其相关的元数据信息(包括标签等)。导入成功后,可以使用docker images命令进行查看。