镜像是Docker的三大核心概念之一。Docker运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker会尝试先从默认镜像仓库下载(默认使用Docker Hub公共注册服务器中的仓库),用户也可以通过配置,使用自定义的镜像仓库。
镜像是Docker运行容器的前提。可以使用pull
命令从仓库下载镜像。命令格式:
docker [image] pull NAME [:TAG]
对于Docker镜像,如果不显示地指定TAG,则默认会选择latest标签,即下载仓库中最新版本的镜像。
另外,默认是从DockerHub的仓库中下。即:sudo docker pull registry.hub.docker.com/ubuntu:18.04
其中registry.hub.docker.com
是默认值,也不写。
下载过程中可以看出 ,镜像文件一般由若干层(layer)组成 ,6c953ac5d795这样的串是层的唯一id(实际上完整的id包括256比特,64个十六进制字符组成)。使用docker pull
命令下载中会获取并输出镜像的各层信息。当不同的镜像包括相同的层时,本地仅存储了层的 一份内容,减小了存储空间。
如果需要从其他注册服务器的仓库下载,需要在仓库名称前指定完整的仓库注册服务器地址。如:sudo docker pull dl.dockerpool.com:5000/ubuntu
。
有时需要使用镜像代理服务来加速Docker镜像获取 过程 ,可以在Docker服务启动配置中增加 --regis七ry-mirror=proxy_URL
来指定镜像代理服务地址(如https://registry.docker-en.com) 。
使用docker images
或docker image ls
命令可以列出本地主机上已有的镜像。
(base) pang@pang-HP:~$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
(base) pang@pang-HP:~$
images命令选项
更多子命令选项还可以通过man docker-images
来查看。
有的镜像列表中,还可以看到一个特殊的镜像,这个镜像既没有仓库名,也没有标签,均为。:
<none> <none> 00285df0df87 5 days ago 342 MB
这个镜像原本是有镜像名和标签的,原来为mongo:3.2,随着官方镜像维护,发布了新版本后,重新docker pull mongo:3.2
时,mongo:3.2这个镜像名被转移到了新下载的镜像身上,而旧的镜像上的这个名称则被取消,从而成为了 。
除了docker pull
可能导致这种情况,docker build
也同样可以导致这种现象。由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 的镜像。这类无标签镜像也被称为虚悬镜像(dangling image),可以用下面的命令专门显示这类镜像:
$ docker image ls -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 00285df0df87 5 days ago 342 MB
一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用下面的命令删除。
$ docker image prune
为了加速镜像构建、重复利用资源,Docker会利用中间层镜像。所以在使用一段时间后,可能会看到一些依赖的中间层镜像。默认的docker image ls
列表中只会显示顶层镜像,如果希望显示包括中间层镜像在内的所有镜像的话,需要加-a
参数。
$ docker image ls -a
这样会看到很多无标签的镜像,与之前的虚悬镜像不同,这些无标签的镜像很多都是中间层镜像,是其它镜像所依赖的镜像。这些无标签镜像不应该删除,否则会导致上层镜像因为依赖丢失而出错。实际上,这些镜像也没必要删除,因为之前说过,相同的层只会存一遍,而这些镜像是别的镜像的依赖,因此并不会因为它们被列出来而多存了一份,无论如何你也会需要它们。只要删除那些依赖它们的镜像后,这些依赖的中间层镜像也会被连带删除。
不加任何参数的情况下,docker image ls
会列出所有顶层镜像,但是有时候我们只希望列出部分镜像。docker image ls
有好几个参数可以帮助做到这个事情。
$ docker image ls ubuntu
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 329ed837d508 3 days ago 63.3MB
ubuntu bionic 329ed837d508 3 days ago 63.3MB
$ docker image ls ubuntu:18.04
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 329ed837d508 3 days ago 63.3MB
除此以外,docker image ls
还支持强大的过滤器参数--filter
,或者简写-f
。之前我们已经看到了使用过滤器来列出虚悬镜像的用法,它还有更多的用法。比如,我们希望看到在mongo:3.2之后建立的镜像,可以用下面的命令:
$ docker image ls -f since=mongo:3.2
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 5f515359c7f8 5 days ago 183 MB
nginx latest 05a60462f8ba 5 days ago 181 MB
想查看某个位置之前的镜像也可以,只需要把since
换成before
即可。
此外,如果镜像构建时,定义了LABEL
,还可以通过LABEL
来过滤。
$ docker image ls -f label=com.example.version=0.1
默认情况下,docker image ls
会输出一个完整的表格,但是我们并非所有时候都会需要这些内容。比如,删除虚悬镜像的时候,需要利用docker image ls
把所有的虚悬镜像的ID列出来,然后才可以交给docker image rm
命令作为参数来删除指定的这些镜像,这个时候就用到了-q
参数。
$ docker image ls -q
5f515359c7f8
05a60462f8ba
fe9198c04d62
00285df0df87
329ed837d508
329ed837d508
--filter
配合-q
产生出指定范围的ID列表,然后送给另一个docker命令作为参数,从而针对这组实体成批的进行某种操作的做法在Docker命令行使用过程中非常常见,不仅仅是镜像,将来我们会在各个命令中看到这类搭配以完成很强大的功能。因此每次在文档看到过滤器后,可以多注意一下它们的用法。
另外一些时候,我们可能只是对表格的结构不满意,希望自己组织列;或者不希望有标题,这样方便其它程序解析结果等,这就用到了Go的模板语法。比如,下面的命令会直接列出镜像结果,并且只包含镜像ID和仓库名:
$ docker image ls --format "{{.ID}}: {{.Repository}}"
5f515359c7f8: redis
05a60462f8ba: nginx
fe9198c04d62: mongo
00285df0df87: <none>
329ed837d508: ubuntu
329ed837d508: ubuntu
或者打算以表格等距显示,并且有标题行,和默认一样,不过自己定义列:
$ docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
IMAGE ID REPOSITORY TAG
5f515359c7f8 redis latest
05a60462f8ba nginx latest
fe9198c04d62 mongo 3.2
00285df0df87 <none> <none>
329ed837d508 ubuntu 18.04
329ed837d508 ubuntu bionic
使用docker tag
命令为本地镜像添加新的标签。如sudo docker tag hello-world hello-world1
(base) pang@pang-HP:~$ sudo docker tag hello-world hello-world1
(base) pang@pang-HP:~$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
hello-world1 latest feb5d9fea6a5 8 months ago 13.3kB
(base) pang@pang-HP:~$
hello-world和hello-world1的ID均一致,实际上也均指向同一个镜像文件,只是别名不同而已。
使用docker inspect
命令可以获取该镜像的详细信息。如:sudo docker inspect hello-world
。
(base) pang@pang-HP:~$ sudo docker inspect hello-world
[
{
"Id": "sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412",
"RepoTags": [
"hello-world1:latest",
"hello-world:latest"
],
"RepoDigests": [
"hello-world@sha256:80f31da1ac7b312ba29d65080fddf797dd76acfb870e677f390d5acba9741b17"
],
"Parent": "",
"Comment": "",
"Created": "2021-09-23T23:47:57.442225064Z",
"Container": "8746661ca3c2f215da94e6d3f7dfdcafaff5ec0b21c9aff6af3dc379a82fbc72",
"ContainerConfig": {
"Hostname": "8746661ca3c2",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
...
该命令返回的是一个JSON格式的信息,如果只需要其中一项内容时,可以使用-f
参数来指定。如:sudo docker inspect -f {{".Architecture"}} hello-world
即获取镜像的Architecture信息。
(base) pang@pang-HP:~$ sudo docker inspect -f {{".Architecture"}} hello-world
amd64
(base) pang@pang-HP:~$
既然镜像文件由多个层组成, 具体各个层的内容是什么,可以使用history
子命令, 该命令将列出各层的创建信息。
(base) pang@pang-HP:~$ sudo docker history hello-world
IMAGE CREATED CREATED BY SIZE COMMENT
feb5d9fea6a5 8 months ago /bin/sh -c #(nop) CMD ["/hello"] 0B
<missing> 8 months ago /bin/sh -c #(nop) COPY file:50563a97010fd7ce… 13.3kB
(base) pang@pang-HP:~$
使用docker search
命令可以搜索远端仓库中共享的镜像,默认搜索Docker Hub官方仓库中的镜像。语法为docker search [option] keyword
。 支持的命令选项主要包括:
以搜寻mysql镜像为例,执行命令sudo docker search mysql
,其结果如下:
(base) pang@pang-HP:~$ sudo docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 12717 [OK]
mariadb MariaDB Server is a high performing open sou… 4882 [OK]
percona Percona Server is a fork of the MySQL relati… 579 [OK]
phpmyadmin phpMyAdmin - A web interface for MySQL and M… 555 [OK]
bitnami/mysql Bitnami MySQL Docker Image 71 [OK]
linuxserver/mysql-workbench 36
linuxserver/mysql A Mysql container, brought to you by LinuxSe… 35
ubuntu/mysql MySQL open source fast, stable, multi-thread… 34
circleci/mysql MySQL is a widely used, open-source relation… 26
google/mysql MySQL server for Google Compute Engine 21 [OK]
rapidfort/mysql RapidFort optimized, hardened image for MySQL 13
vmware/harbor-db Mysql container for Harbor 10
bitnami/mysqld-exporter 3
ibmcom/mysql-s390x Docker image for mysql-s390x 2
nasqueron/mysql 1 [OK]
vitess/mysqlctld vitess/mysqlctld 1 [OK]
newrelic/mysql-plugin New Relic Plugin for monitoring MySQL databa… 1 [OK]
mirantis/mysql 0
docksal/mysql MySQL service images for Docksal - https://d… 0
drud/mysql-local-57 ddev mysql local container 0
drud/mysql 0
drud/mysql-docker-local-57 This repo has been deprecated, new tags are … 0
drud/mysql-docker-local docker containers for local womysql rk 0 [OK]
cimg/mysql 0
silintl/mysql-backup-restore Simple docker image to perform mysql backups… 0 [OK]
(base) pang@pang-HP:~$
默认的输出结果将按照星级评价进行排序,其字段含义为:
(base) pang@pang-HP:~$ sudo docker search --filter=is-official=true nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 16944 [OK]
(base) pang@pang-HP:~$
(base) pang@pang-HP:~$ sudo docker search --filter=stars=4 tensorflow
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
tensorflow/tensorflow Official Docker images for the machine learn… 2027
tensorflow/serving Official images for TensorFlow Serving (http… 123
bitnami/tensorflow-serving Bitnami Docker Image for TensorFlow Serving 25 [OK]
armswdev/tensorflow-arm-neoverse-n1 Please use "armswdev/tensorflow-arm-neoverse" 10
ibmcom/tensorflow-ppc64le Community supported ppc64le docker images fo… 6
intel/intel-optimized-tensorflow Containers with TensorFlow* optimized with o… 5
armswdev/tensorflow-arm-neoverse TensorFlow builds for AArch64 CPUs 4
(base) pang@pang-HP:~$
有两种办法:
官网查询
访问https://hub.docker.com/ 搜索centos
使用curl查询
首先,通过命令确认NAME
(base) pang@pang-HP:~/dockerfile$ sudo docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 7183 [OK]
centos/systemd systemd enabled base container. 108 [OK]
centos/mysql-57-centos7 MySQL 5.7 SQL database server 95
kasmweb/centos-7-desktop CentOS 7 desktop for Kasm Workspaces 20
centos/mongodb-36-centos7 MongoDB NoSQL database server 8
kasmweb/core-centos-7 CentOS 7 base image for Kasm Workspaces 3
continuumio/centos5_gcc5_base 3
couchbase/centos7-systemd centos7-systemd images with additional debug… 1 [OK]
spack/centos7 CentOS 7 with Spack preinstalled 1
spack/centos-stream 0
couchbase/centos-72-jenkins-core 0
fnndsc/centos-python3 Source for a slim Centos-based Python3 image… 0 [OK]
couchbase/centos-72-java-sdk 0
couchbase/centos-69-sdk-nodevtoolset-build 0
couchbase/centos-70-sdk-build 0
datadog/centos-i386 0
spack/centos6 CentOS 6 with Spack preinstalled 0
starlingx/stx-centos StarlingX centos 0
ibmcom/fhe-toolkit-centos-amd64 The IBM Fully Homomorphic Encryption (FHE) T… 0
ibmcom/fhe-toolkit-centos The IBM Fully Homomorphic Encryption (FHE) T… 0
apache/couchdbci-centos Apache CouchDB CI CentOS 0
silintl/openldap OpenLDAP base image on Centos 6 0 [OK]
bitnami/centos-extras-base 0
bitnami/centos-base-buildpack Centos base compilation image 0 [OK]
couchbase/centos-69-sdk-build
其次,将NAME替换下面命令中的XXXX字符。
curl https://registry.hub.docker.com/v1/repositories/xxxx/tags\
| tr -d '[\[\]" ]' | tr '}' '\n'\
| awk -F: -v image='xxxx' '{if(NR!=NF && $3 != ""){printf("%s:%s\n",image,$3)}}'
例如:
(base) pang@pang-HP:~/dockerfile$ curl https://registry.hub.docker.com/v1/repositories/centos/tags\
| tr -d '[\[\]" ]' | tr '}' '\n'\
| awk -F: -v image='centos' '{if(NR!=NF && $3 != ""){printf("%s:%s\n",image,$3)}}'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1745 0 1745 0 0 1253 0 --:--:-- 0:00:01 --:--:-- 1253
centos:latest
centos:5
centos:6
centos:6.10
centos:6.6
centos:6.7
centos:6.8
centos:6.9
centos:7
centos:7.0.1406
centos:7.1.1503
centos:7.2.1511
centos:7.3.1611
centos:7.4.1708
centos:7.5.1804
centos:7.6.1810
centos:7.7.1908
centos:7.8.2003
centos:7.9.2009
centos:8
centos:8.1.1911
centos:8.2.2004
centos:8.3.2011
centos:8.4.2105
centos:centos5
centos:centos5.11
centos:centos6
centos:centos6.10
centos:centos6.6
centos:centos6.7
centos:centos6.8
centos:centos6.9
centos:centos7
centos:centos7.0.1406
centos:centos7.1.1503
centos:centos7.2.1511
centos:centos7.3.1611
centos:centos7.4.1708
centos:centos7.5.1804
centos:centos7.6.1810
centos:centos7.7.1908
centos:centos7.8.2003
centos:centos7.9.2009
centos:centos8
centos:centos8.1.1911
centos:centos8.2.2004
centos:centos8.3.2011
centos:centos8.4.2105
(base) pang@pang-HP:~/dockerfile$
使用docker rmi
或docker image rm
命令可以删除镜像, 命令格式为docker rmi IMAGE [IMAGE ... ]
,其中IMAGE可以为标签或ID。
支持选项包括:
当同一个镜像拥有多个标签的时候,docker rmi
命令只是删除了该镜像多个标签中的指定标签而已,并不影响镜像文件。
例如,sudo docker rmi hello-world1
只会删除镜像副本hello-world1
。
(base) pang@pang-HP:~$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world1 latest feb5d9fea6a5 8 months ago 13.3kB
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
(base) pang@pang-HP:~$
(base) pang@pang-HP:~$ sudo docker rmi hello-world1:latest
Untagged: hello-world1:latest
(base) pang@pang-HP:~$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
(base) pang@pang-HP:~$
当镜像只剩下一个标签的时候就要小心了, 此时再使用docker rmi
命令会彻底删除镜像。
当使用docker rmi
命令, 并且后面跟上镜像的ID (也可以是能进行区分的部分ID串前缀)时,会先尝试删除所有指向该镜像的标签, 然后删除该镜像文件本身。
如同上节说将,当同一个镜像拥有多个标签的时候,使用ID删除时,因为有多个副本,所以会提示错误。
(base) pang@pang-HP:~$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world1 latest feb5d9fea6a5 8 months ago 13.3kB
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
(base) pang@pang-HP:~$
(base) pang@pang-HP:~$ sudo docker rmi feb5d9fea6a5
Error response from daemon: conflict: unable to delete feb5d9fea6a5 (must be forced) - image is referenced in multiple repositories
(base) pang@pang-HP:~$
此时可以添加-f
参数强制删除,但是要注意,此时会将镜像彻底删除包括其多个副本。
(base) pang@pang-HP:~$ sudo docker rmi feb5d9fea6a5 -f
Untagged: hello-world1:latest
Untagged: hello-world:latest
Untagged: hello-world@sha256:80f31da1ac7b312ba29d65080fddf797dd76acfb870e677f390d5acba9741b17
Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
Deleted: sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359
(base) pang@pang-HP:~$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
(base) pang@pang-HP:~$
另外注意,当有该镜像创建的容器存在时,镜像文件默认也是无法被删除的。
(base) pang@pang-HP:~$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d6f4e669c61 hello-world "/hello" About a minute ago Exited (0) About a minute ago priceless_lewin
(base) pang@pang-HP:~$ sudo docker rmi hello-world
Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container 3d6f4e669c61 is using its referenced image feb5d9fea6a5
(base) pang@pang-HP:~$
使用docker ps -a
命令可以看到本机上存在的所有容器。如果有容器是基于某个镜像产生的,如果删除该镜像则会提示如上错误。此时,也可以使用-f
参数强制删除该镜像。如:sudo docker rmi -f hello-world
。但是一般不支持使用-f
,这样会遗留一些问题。
正确的做法是,先删除依赖该镜像的所有容器, 再来删除镜像。
使用Docker一段时间后,系统中可能会遗留一些临时的镜像文件,以及一些没有被使用的镜像,可以通过docker image prune
命令来进行清理。
支待选项包括:
例如, 如下命令会自动清理临时的遗留镜像文件层, 最后会提示释放的存储空间:
$ sudo docker image prune -f
. . .
Total reclaimed space: 1.4 GB
如果观察上面这几个命令的运行输出信息的话,你会注意到删除行为分为两类,一类是Untagged,另一类是Deleted。我们之前介绍过,镜像的唯一标识是其ID和摘要,而一个镜像可以有多个标签。
因此当我们使用上面命令删除镜像的时候,实际上是在要求删除某个标签的镜像。所以首先需要做的是将满足我们要求的所有镜像标签都取消,这就是我们看到的Untagged的信息。
因为一个镜像可以对应多个标签,因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像,如果是这种情况,那么Delete行为就不会发生。所以并非所有的docker image rm
都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已。
当该镜像所有的标签都被取消了,该镜像很可能会失去了存在的意义,因此会触发删除行为。镜像是多层存储结构,因此在删除的时候也是从上层向基础层方向依次进行判断删除。镜像的多层结构让镜像复用变得非常容易,因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。直到没有任何层依赖当前层时,才会真实的删除当前层。这就是为什么,有时候会奇怪,为什么明明没有别的标签指向这个镜像,但是它还是存在的原因,也是为什么有时候会发现所删除的层数和自己docker pull
看到的层数不一样的原因。
除了镜像依赖以外,还需要注意的是容器对镜像的依赖。如果有用这个镜像启动的容器存在(即使容器没有运行),那么同样不可以删除这个镜像。之前讲过,容器是以镜像为基础,再加一层容器存储层,组成这样的多层存储结构去运行的。因此该镜像如果被这个容器所依赖的,那么删除必然会导致故障。如果这些容器是不需要的,应该先将它们删除,然后再来删除镜像。
像其它可以承接多个实体的命令一样,可以使用docker image ls -q
来配合使用docker image rm
,这样可以成批的删除希望删除的镜像。第3节介绍的很多过滤镜像列表的方式都可以拿过来使用。
比如,我们需要删除所有仓库名为redis
的镜像:
$ docker image rm $(docker image ls -q redis)
或者删除所有在 mongo:3.2 之前的镜像:
$ docker image rm $(docker image ls -q -f before=mongo:3.2)
创建镜像的方法有几种:基于已有镜像的容器创建;基于本地模板导入;基于Dockerfile创建。
主要是使用docker [container] commit
命令,其命令格式为:
docker [container] commit [OPTIONS] CONTAINER [REPOSITORY [:TAG]]
主要选项包括:
例如:
$ docker run -it ubuntu:18.04 /bin/bash
root@a925cb40b3f0:/# touch test
root@a925cb40b3f0:/# exit
# 记住容器的 ID 为 a925cb40b3£0
$ docker [container] commit -m "Added a new file" -a "Docker Newbee" a925cb40b3f0
test:0.1
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
test 0.1 9e9c814023bc 4 seconds ago 188 MB
可以直接从一个操作系统模板文件导人一个镜像,主要使用docker [container] import
命令。 命令格式为:
docker [image] import [OPTIONS] file|URL|- [REPOSITORY[:TAG ]]
要直接导人一个镜像,可以使用OpenVZ提供的模板来创建,或者用其他已导出的镜像模板来创建。
例如:
$ cat ubuntu-18.04-x86_64-minimal.tar.gz I docker import - ubuntu:lB.04
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 18.04 05ac7c0b9383 17 seconds ago 215.5 MB
基于Dockerfile创建是最常见的方式。Dockerfile是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
这里使用了docker build
命令进行镜像构建。其格式为:
docker build [选项] <上下文路径/URL/->
具体Dockerfile后续讲解,先以简单示例说明:基于debian:stretch-slim镜像安装Python3环境,构成一个新的python:3镜像
touch Dockerfile
,其内容如下: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/*
(base) pang@pang-HP:~/dockerfile$ sudo docker build -t python:3 .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM debian:stretch-slim
stretch-slim: Pulling from library/debian
73e8e0576286: Pull complete
Digest: sha256:b57dec331d7fa856af213f861750bbdec85736741d8b81ef72769cfd344739e5
Status: Downloaded newer image for debian:stretch-slim
---> a88d8e7bd33c
Step 2/3 : LABEL version="1.0" maintainer="docker user <docker_user@github>"
---> Running in 4763edb79756
Removing intermediate container 4763edb79756
---> 41180a17a248
Step 3/3 : RUN apt-get update && apt-get install -y python3 & apt-get clean && rm -rf /var/lib/apt/lists/*
---> Running in 66abe4e23da1
Removing intermediate container 66abe4e23da1
---> 763642b839b7
Successfully built 763642b839b7
Successfully tagged python:3
(base) pang@pang-HP:~/dockerfile$
(base) pang@pang-HP:~/dockerfile$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python 3 763642b839b7 8 seconds ago 55.4MB
debian stretch-slim a88d8e7bd33c 2 weeks ago 55.4MB
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
(base) pang@pang-HP:~/dockerfile$
本小节介绍Docker镜像的save
和load
子命令 。 用户可以使用docker [image] save
和docker [image] load
命令来存出和载人镜像。
如果要导出镜像到本地文件,可以使用docker [image] save
命令。 该命令支持-o
、--output string
参数 , 导出镜像到指定的文件中。
(base) pang@pang-HP:~/dockerfile$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python 3 763642b839b7 8 seconds ago 55.4MB
debian stretch-slim a88d8e7bd33c 2 weeks ago 55.4MB
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
(base) pang@pang-HP:~/dockerfile$
(base) pang@pang-HP:~/dockerfile$ sudo docker save -o hello.tar hello-world
(base) pang@pang-HP:~/dockerfile$ ll
总用量 36
drwxrwxr-x 2 pang pang 4096 6月 14 14:34 ./
drwxr-x--- 72 pang pang 4096 6月 14 14:23 ../
-rw-rw-r-- 1 pang pang 204 6月 14 14:23 Dockerfile
-rw------- 1 root root 24064 6月 14 14:34 hello.tar
(base) pang@pang-HP:~/dockerfile$
这里的filename可以为任意名称甚至任意后缀名,但文件的本质都是归档文件。
注意:如果同名则会覆盖(没有警告)
若使用gzip压缩:
(base) pang@pang-HP:~/dockerfile$ sudo docker save hello-world | gzip >hello.tar.gz
(base) pang@pang-HP:~/dockerfile$ ll
总用量 40
drwxrwxr-x 2 pang pang 4096 6月 14 14:37 ./
drwxr-x--- 72 pang pang 4096 6月 14 14:23 ../
-rw-rw-r-- 1 pang pang 204 6月 14 14:23 Dockerfile
-rw------- 1 root root 24064 6月 14 14:34 hello.tar
-rw-rw-r-- 1 pang pang 3523 6月 14 14:37 hello.tar.gz
(base) pang@pang-HP:~/dockerfile$
可以使用 docker [image] load 将导出的 tar 文件再导人到本地镜像库。支持 - Linput string 选项,从指定文件中读人镜像内容。
从文件hello.tar导人镜像到本地镜像列表,如下所示:
$ docker load -i hello.tar
或者:
$ docker load < hello.tar
这将导人镜像及其相关的元数据信息(包括标签等)。 导人成功后,可以使用docker images
命令进行查看,与原镜像一致。
结合这两个命令以及ssh
甚至pv
的话,利用Linux强大的管道,我们可以写一个命令完成从一个机器将镜像迁移到另一个机器,并且带进度条的功能:
docker save <镜像名> | bzip2 | pv | ssh <用户名>@<主机名> 'cat | docker load'
可以使用docker push
命令上传镜像到仓库,默认上传到DockerHub官方仓库(需要登录)。命令格式为:
docker 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 to push:
Username:
Password:
Email :
第一次上传时,会提示输入登录信息或进行注册,之后登录信息会记录到本地~/.docker目录下。
Docker 镜像是怎么实现增量的修改和维护的?
每个镜像都由很多层次构成,Docker使用Union FS将这些不同的层结合到一个镜像中去。通常Union FS有两个用途, 一方面可以实现不借助LVM、RAID将多个disk挂到同一个目录下,另一个更常用的就是将一个只读的分支和一个可写的分支联合在一起,Live CD正是基于此方法可以允许在镜像不变的基础上允许用户在其上进行一些写操作。
Docker在OverlayFS上构建的容器也是利用了类似的原理。