镜像(Image)是构建容器的基础,镜像是一种分层结构的文件系统。我们可以从仓库(Repository)中下载镜像,而仓库又保存在Registry中,Docker Hub是Docker官方提供的Registry。即可以从Docker Hub的顶层仓库中免费获取官方提供的基于镜像,又可以将自已构建的镜像存放于Docker Hub的用户仓库中。
1. 什么Docker镜像
镜像是一个只读的层(layer),由文件系统叠加构成。而镜像又是容器(Container)的构成单元,我们一般会将应用构建成标准的镜像组件,一或多个镜像叠加又构成了容器。

bootfs
Docker由文件系统叠加组成,其最底层是一个引导文件系统,即:bootfs,这个很像Linux或Unix的引导文件系统。引导文件系统负责加载容器,容器加载完成后会被移到内存中,而引导文件系统会被卸载,以留出更多的内存初始化(initrd)磁盘。
rootfs
在引导文件系统之上是root文件系统,即:rootfs。rootfs是在容器启动时,其内部可见的文件系统,其中会包含容器所需要的文件、工具、容器文件等。rootfs可以是一或多个操作系统镜像(基础镜像),如:Debian、Ubuntu、CentOS等。
在Linux系统引导过程中,系统内核启动时,会首先加载一个只读的rootfs。系统对其做完整性等检测后,再决定是否将其切换为读/写模式,或者用一种新的rootfs代替当前rootfs。Docker的设计思想与此类似,不同的是Docker不会将文件系统改为读写模式,而是利用联合加载(Union mount)技术,在rootfs之上加载更多的只读文件系统。
联合加载(Union mount)
联合加载(Union mount)是指一次加载多个文件系统,但外面看来只有一个文件系统。联合加载会将各层文件系统叠加到一起,这样最终看到的是一个包含所有文件和目录的、合并后的文件系统。
镜像(Image)
在Docker中将这种文件称为镜像(Image),或者说上Docker容器的文件系统是由多个镜像来构成的。一个镜像,可以放在另一个镜像之上。位于底层的镜像称之为父镜像,而位于最底层的镜像称之为基础镜像(Base Image)。
当从一个镜像启动容器时,Docker会从该镜像的最顶层加载一个读/写文件系统,而我们的应用就会运行于这个读/写层中。
2. 镜像(Image)的基础操作
2.1 显示所有镜像
通过镜像创建容器后,镜像从镜像仓库(Registry)下载到本地。可以通过docker images命令查看本地主机上的镜像:
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest f49eec89601e 8 days ago 129 MB
如上所示,我们在介绍Docker 容器时,使用ubuntu镜像创建容器。该镜存放于Docker Hub一个名为ubuntu的仓库中,而其下载到本地后,会被保存在/var/lib/docker目录下。
2.2 拉取(下载)镜像
使用docker run命令从镜像启动容器时,如果镜像在本地不存在,那么首先会从Docker Hub中下载该镜像。
如,我们按如下方式运行一个交互式容器后:
$ sudo docker run -i -t --name itbilu_ubuntu ubuntu /bin/bash
创建后,会在宿主机上保存了一个ubuntu镜像,其版本号为latest,即,最后一个版本的镜像。
为了加快容器启动时间,在运行容器前,可以通过docker pull命令将镜像先下载到本地。
如,拉取一个centos6版本的CentOS基础镜像:
$ sudo docker pull centos:centos6 centos6: Pulling from library/centos 32c4f4fef1c6: Pull complete Digest: sha256:1092df198d3da4faccc0660941b763ce5adf133b0ec71701b760d6f173c1f47b Status: Downloaded newer image for centos:centos6
在这个示例中,使用仓库名:版本号形式下载了一个centos镜像。如果不指定版本号,默认将下载最后一个版本,即:latest。
下载完成后,就可以通docker images命令工看到这个镜像。也可以docker images命令后指定镜像名查看:
$ sudo docker images centos REPOSITORY TAG IMAGE ID CREATED SIZE centos centos6 8315978ceaaa 3 months ago 195 MB
2.3 查找镜像
查找镜像有两种方式:Docker Hub在线查找镜像、docker search命令查找。
在线查找镜像
可以通过Docker Hub官网在线查找镜像:
如,通过centos关键字可以搜索到名称中含有该关键字的相关镜像:

docker search命令查找
还可以使用docker search命令查找镜像。命令格式如下:
docker search [OPTIONS] TERM
如,通过centos关键字查找镜像:
$ sudo docker search centos NAME DESCRIPTION STARS OFFICIAL AUTOMATED centos The official build of CentOS. 3063 [OK] jdeathe/centos-ssh CentOS-6 6.8 x86_64 / CentOS-7 7.3.1611 x8... 57 [OK] jdeathe/centos-ssh-apache-php CentOS-6 6.8 x86_64 - Apache / PHP-FPM / P... 25 [OK] nimmis/java-centos This is docker images of CentOS 7 with dif... 23 [OK] consol/centos-xfce-vnc Centos container with "headless" VNC sessi... 18 [OK] million12/centos-supervisor Base CentOS-7 with supervisord launcher, h... 12 [OK]
通过命令查找时,返回信息包括:
- 仓库名(NAME)
- 镜像描述(DESCRIPTION)
- 用户评价(STARS)
- 是否官方式镜像(OFFICIAL)
- 是否自动构建(AUTOMATED)- 即由Docker Hub自动构建(Automated Build)流程创建
查找到指定镜像后,就可以git pull命令下载镜像。
如,下载名为jdeathe/centos-ssh的镜像:
$ sudo docker pull jdeathe/centos-ssh
镜像下载后,就可以通过下载的镜像创建或启动容器,也可以基于这些镜像构建自己的镜像。
2.4 镜像删除
当镜像不再需要时,可以将镜像从删除。删除镜像使用docker rmi命令。
如,删除jdeathe/centos-ssh的镜像:
$ sudo docker rmi jdeathe/centos-ssh Untagged: jdeathe/centos-ssh:latest Untagged: jdeathe/centos-ssh@sha256:7dbd9e7e37bac65bc6aff99472ea2919b38ede8da3a09c58bf56d4a3523d5abf Deleted: sha256:c3c34686b22ea2290d2c0316dde74ed4d2639b2f2ab27a7b72734dbc397ee2db Deleted: sha256:ef89b3ead0b29fdc9e02a040830df8e18186f65e92134e0ec8bbd6f3d2e0f77e Deleted: sha256:fe9df9eef47591a7afeba1a0747bf2b9b75dc31d9521df0dffd1cfa2677e82a7 …
删除和镜像时,我们会看到很多的Deleted行。这是因为,Docker镜像是一种以层(Layer)为单位的分层文件系统,每一行Deleted都表示一个镜像层被删除。
注意:docker rmi只能删除本地镜像,并不能删除镜像仓库。镜像仓库需要登录Docker Hub后,在后台删除对应的Repository。
删除镜像时,可以同时删除多个镜像:
$ sudo docker rmi image1 image2
删除镜像时,也可以指定版本号:
$ sudo docker rmi centos:centos6
3. 仓库(Repository)介绍
3.1 镜像从哪里来
docker pull命令会把镜像从Registry的镜像仓库中将镜像拉到本地,使用docker run、docker run命令创建、运行容器时,如果本地不存在创建容器的镜,首先也会从镜像仓库下载镜像。
镜像是从镜像仓库下载下来的。镜像保存在镜像仓库,而镜像仓库保存在Registry。Registry是由Docker运营的一个公共镜像服务,即:Docker Hub(类似于GitHub)。
Docker Registry是开源的,个人或组织也可以运行自己的Registry。市场上除了Docker官方的Registry外,还有很多第三方Registry服务。这些Registry服务大多基于Docker Registry或Docker Trusted Registry(Docker公司提供的商业版的Docker Hub)构建。
3.2 镜像仓库
镜像在保存Docker Hub的仓库(Repository)中的,镜像仓库类似于Git中仓库的概念。一个仓库中可以保存很多镜像,或者说很多版本的镜像。也和Git一样,Docker Hub也通过标签(tag)来标签镜像的不同版本。如:ubuntu镜像的仓库中就包含了12.04、14.04、16.10、trusty、latest等不同的镜像版本。
在使用docker pull等命令下载镜像时,如果不指定镜像版本,默认将下载latest版本。如果需要下载指定版本的镜像,可以通过仓库名:标签名的形式下载。
如,下载14.04版本的ubuntu镜像:
$ sudo docker pull ubuntu:14.04 14.04: Pulling from library/ubuntu c60055a51d74: Pull complete 755da0cdb7d2: Pull complete 969d017f67e6: Pull complete 37c9a9113595: Pull complete a3d9f8479786: Pull complete Digest: sha256:8f5f12335124c1b78e4cf2f8860d395f75ba279bae70a3c18dd470e910e38ec5 Status: Downloaded newer image for ubuntu:14.04
下载完成后,可以通过docker images查看当前已下载的镜像:
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest f49eec89601e 12 days ago 129 MB ubuntu 14.04 b969ab9f929b 12 days ago 188 MB
可以看到,本机除latest版的镜像外,又多出了一个14.04版本的镜像。
需要注意的是,我们可以看到相比完整的Ubuntu系统来说,镜像要小的。这是因为,镜像并不是一个完整的系统,而是一个裁剪版的系统,只包含了支持系统运行的有限组件。
除了在docker pull命令中可以指定镜像标签(版本)外,使用镜像的docker run和docker run命令同样可以指定。
如,使用16.04版本的ubuntu镜像运行一个容器:
$ sudo docker run -t -i --name ubuntu_16.04 ubuntu:16.04 /bin/bash Unable to find image 'ubuntu:16.04' locally 16.04: Pulling from library/ubuntu Digest: sha256:71cd81252a3563a03ad8daee81047b62ab5d892ebbfbf71cf53415f29c130950 Status: Downloaded newer image for ubuntu:16.04 root@a75027d832e4:/#
docker images查看,同样会下载指定版本的镜像到本地:
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 16.04 f49eec89601e 12 days ago 129 MB ubuntu latest f49eec89601e 12 days ago 129 MB ubuntu 14.04 b969ab9f929b 12 days ago 188 MB
3.3 镜像标签(tag)
为区分一个仓库中的不同镜像(不同镜像版本),Docker Hub引入标签(tagGit中标签的作用基本,都是为了文件进行标识。
我们在前面介绍,镜像由文件系统叠加构成。而镜像又是由多层构成,每一层包含了文件和配置两部分,我们一般会把层(Layer)做为一个独立的单元。而标签就是对这些镜像层的标记。
通过镜像层和标签,我们可以轻松实现镜像和容器的模块化管理。通过一定的提交、构建机制,还可以很轻松的在现在镜像的基础上构建新镜像。
为了方便镜像的查找,同一个镜像可以存在不同的标签。如,上面的ubuntu:latest与ubuntu:16.04具有相同的镜像ID,镜像ID才是镜像的唯一标识。
3.4 仓库类型
在Docker Hub有类型的仓库:用户仓库(User Repository)和顶层仓库(Top-level Repository)。其中,用户仓库是由用户创建的仓库;而顶层仓库由Doker官方创建和维护。
登录Docker Hub后,可以通过Create-Create Repository链接创建用户创建:

用户仓库由用户名和仓库名两部分组成,如,itbilu/myrepository:
- 用户名:
itbilu - 仓库名:
myrepository
用可以基于顶层仓库构建自己的仓库。下载用户仓库中的镜像与项层仓库下载规则相同:
$ sudo docker pull itbilu/myrepository:latest
顶层仓库只有仓库名一级,如:ubuntu。顶层仓库一般由Docker公司,及Docker公司指定的基础镜像厂商管理。
