目录
1、介绍
在 Docker 的术语里,一个只读层被称为镜像,一个镜像是永久不会变的。
镜像可以用来创建 Docker 容器。
Docker 镜像包含了运行应用程序的所有程序:代码、运行时环境、系统资源、依赖、配置
例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。
Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
由于 Docker 使用一个统一文件系统,Docker 进程认为整个文件系统是以读写方式挂载的。 但是所有的变更都发生顶层的可写层,而下层的原始的只读镜像文件并未变化。由于镜像不可写,所以镜像是无状态的。由镜像新建容器时,是在镜像层之上加了一层读写层。
父镜像
每一个镜像都可能依赖于由一个或多个下层的组成的另一个镜像。我们有时说,下层那个镜像是上层镜像的父镜像。
基础镜像
一个没有任何父镜像的镜像,谓之基础镜像。
镜像ID
所有镜像都是通过一个 64 位十六进制字符串 (内部是一个 256 bit 的值)来标识的。 为简化使用,前 12 个字符可以组成一个短ID,可以在命令行中使用。短ID还是有一定的碰撞机率,所以服务器总是返回长ID。
2、获取镜像
可以使用 docker pull 命令来从仓库获取所需要的镜像。
下面的例子将从 Docker Hub 仓库下载一个 Ubuntu 12.04 操作系统的镜像。
$ sudo docker pull ubuntu:12.04
Pulling repository ubuntu
ab8e2728644c: Pulling dependent layers
511136ea3c5a: Download complete
5f0ffaa9455e: Download complete
a300658979be: Download complete
904483ae0c30: Download complete
ffdaafd1ca50: Download complete
d047ae21eeaf: Download complete
下载过程中,会输出获取镜像的每一层信息。
该命令实际上相当于 $ sudo docker pull registry.hub.docker.com/ubuntu:12.04
命令,即从注册服务器registry.hub.docker.com 中的 ubuntu 仓库来下载标记为 12.04 的镜像。
有时候官方仓库注册服务器下载较慢,可以从其他仓库下载。 从其它仓库下载时需要指定完整的仓库注册服务器地址。例如
$ sudo docker pull dl.dockerpool.com:5000/ubuntu:12.04
Pulling dl.dockerpool.com:5000/ubuntu
ab8e2728644c: Pulling dependent layers
511136ea3c5a: Download complete
5f0ffaa9455e: Download complete
a300658979be: Download complete
904483ae0c30: Download complete
ffdaafd1ca50: Download complete
d047ae21eeaf: Download complete
完成后,即可随时使用该镜像了,例如创建一个容器,让其中运行 bash 应用。
$ sudo docker run -t -i ubuntu:12.04 /bin/bash root@fe7fc4bd8fc9:/#
3、列出本地镜像
使用 docker images 显示本地已有的镜像。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 12.04 74fe38d11401 4 weeks ago 209.6 MB
ubuntu precise 74fe38d11401 4 weeks ago 209.6 MB
ubuntu 14.04 99ec81b80c55 4 weeks ago 266 MB
ubuntu latest 99ec81b80c55 4 weeks ago 266 MB
ubuntu trusty 99ec81b80c55 4 weeks ago 266 MB
在列出信息中,可以看到几个字段信息
-
来自于哪个仓库,比如 ubuntu
-
镜像的标记,比如 14.04
-
它的 ID 号(唯一)
-
创建时间
-
镜像大小
其中镜像的 ID 唯一标识了镜像,注意到 ubuntu:14.04 和 ubuntu:trusty 具有相同的镜像 ID,说明它们实际上是同一镜像。
TAG 信息用来标记来自同一个仓库的不同镜像。例如 ubuntu 仓库中有多个镜像,通过 TAG 信息来区分发行版本,例如 10.04、12.04、12.10、13.04、14.04 等。例如下面的命令指定使用镜像 ubuntu:14.04 来启动一个容器。
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
如果不指定具体的标记,则默认使用 latest 标记信息。
4、创建镜像
创建镜像有很多方法,用户可以从 Docker Hub 获取已有镜像并更新,也可以利用本地文件系统创建一个。
4.1 修改已有镜像
请参照[10 Docker实战案例第2个]
。
4.2 利用 Dockerfile 来创建镜像
生成一个SpringBoot应用,并通过DockerFile生成镜像文件运行。
请参照[10 Docker实战案例第1个]
。
4.3 从本地文件系统导入
要从本地文件系统导入一个镜像,可以使用 openvz(容器虚拟化的先锋技术)的模板来创建: openvz 的模板下载地址为 templates 。
比如,先下载了一个 ubuntu-14.04 的镜像,之后使用以下命令导入:
sudo cat ubuntu-14.04-x86_64-minimal.tar.gz |docker import - ubuntu:14.04
然后查看新导入的镜像。
docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 14.04 05ac7c0b9383 17 seconds ago 215.5 MB
4.4 上传镜像
用户可以通过 docker push 命令,把自己创建的镜像上传到仓库中来共享。例如,用户在 Docker Hub 上完成注册后,可以推送自己的镜像到仓库中。
我们把刚才生成的tomcat.lucas:1.0 push上去试试看。
[root@iZ2zef4zu0mvk0hhwa0il1Z ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: james821
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@iZ2zef4zu0mvk0hhwa0il1Z ~]# docker tag tomcat.lucas:1.0 james821/tomcat.lucas:1.0
[root@iZ2zef4zu0mvk0hhwa0il1Z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat.lucas 1.0 aba402c4a427 2 hours ago 791MB
james821/tomcat.lucas 1.0 aba402c4a427 2 hours ago 791MB
[root@iZ2zef4zu0mvk0hhwa0il1Z ~]# docker push james821/tomcat.lucas:1.0
The push refers to repository [docker.io/james821/tomcat.lucas]
985204d9ffd2: Pushing [=====> ] 14.77MB/143.5MB
123a7175f991: Pushed
68b9387df273: Pushing [==========> ] 4.207MB/19.95MB
...家里网络太差,就没有继续上传了,这个文件打包出来挺大的...
8803ef42039d: Waiting
5、导出和载入镜像
5.1 导出镜像
如果要导出镜像到本地文件,可以使用 docker save 命令。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 14.04 c4ff7513909d 5 weeks ago 225.4 MB
...
$sudo docker save -o ubuntu_14.04.tar ubuntu:14.04
5.2 载入镜像
可以使用 docker load 从导出的本地文件中再导入到本地镜像库,例如
$ sudo docker load --input ubuntu_14.04.tar
$ sudo docker load < ubuntu_14.04.tar
这将导入镜像以及其相关的元数据信息(包括标签等)。
6、移除本地镜像
如果要移除本地的镜像,可以使用 docker rmi 命令。注意 docker rm 命令是移除容器。
$ sudo docker rmi training/sinatra
Untagged: training/sinatra:latest
Deleted: 5bc342fa0b91cabf65246837015197eecfa24b2213ed6a51a8974ae250fedd8d
Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f
Deleted: 5c58979d73ae448df5af1d8142436d81116187a7633082650549c52c3a2418f0
*注意:在删除镜像之前要先用 docker rm 删掉依赖于这个镜像的所有容器。
7、镜像的实现原理
Docker 镜像是怎么实现增量的修改和维护的? 每个镜像都由很多层次构成,Docker 使用 Union FS 将这些不同的层结合到一个镜像中去。
通常 Union FS 有两个用途, 一方面可以实现不借助 LVM、RAID 将多个 disk 挂到同一个目录下,另一个更常用的就是将一个只读的分支和一个可写的分支联合在一起,Live CD 正是基于此方法可以允许在镜像不变的基础上允许用户在其上进行一些写操作。
Docker 在 AUFS 上构建的容器也是利用了类似的原理。