我们知道镜像是 Docker 的三大组件之一。Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在本地, Docker 会从镜像仓库下载(默认是Docker Hub 公共注册服务器中的仓库)。
可以使用 docker pull 命令来从仓库获取所需要的镜像。下面的例子将从 Docker Hub 仓库下载一个 Ubuntu 12.04 操作系统的镜像。
下载过程中,会输出获取镜像的每一层信息。该命令实际上相当于 $ sudo docker pull registry.hub.docker.com/ubuntu:12.04 命令,即从注册服务器registry.hub.docker.com 中的 ubuntu 仓库来下载标记为 12.04 的镜像。有时候官方仓库注册服务器下载较慢,可以从其他仓库下载。 从其它仓库下载时需要指定完整的仓库注册服务器地址。如:
完成后,即可随时使用该镜像了,例如创建一个容器,在其中运行 bash 应用。
使用 docker images 显示本地已有的镜像。
在列出信息中,可以看到几个字段信息
其中镜像的 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
创建镜像有很多方法,用户可以从 Docker Hub 获取已有镜像并更新,也可以利用本地文件系统创建一个。
修改已有镜像
先使用下载的镜像启动容器。
注意:记住容器的 ID,稍后还会用到。在容器中添加 json 和 gem 两个应用。
当结束后,我们使用 exit 来退出,现在我们的容器已经被我们改变了,使用 docker commit 命令来提交更新后的副本。
其中, -m 来指定提交的说明信息,跟我们使用的版本控制工具一样; -a 可以指定更新的用户信息;之后是用来创建镜像的容器的 ID;最后挃定目标镜像的仏库名和 tag 信息。创建成功后会迒回返个镜像的 ID信息。
使用 docker images 来查看新创建的镜像。
之后,可以使用新的镜像来启动容器:
利用 Dockerfile 来创建镜像
使用 docker commit 来扩展一个镜像比较简单,但它很容易在一个团队中分享它。我们可以使用 docker build 来创建一个新的镜像。为此,首先需要创建一个 Dockerfile,包函一些如何创建镜像的指令。
Dockerfile 由一行行命令语句组成,幵头支持以 # 开头的注释行。一般的, Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。例如:
其中,一开始必须指明所基于的镜像名称,接下来推荐说明维护者信息。后面则是镜像操作指令,例如 RUN 指令, RUN 指令将对镜像执行跟随的命令。每运行一条 RUN 指令,镜像添加新的一层,并提交。最后是 CMD 指令,来指定运行容器时的操作命令。dockerfile中的指令系统如下:
FROM
格式为 FROM <image> 或 FROM <image>:<tag> 。第一条指令必须为 FROM 指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM指令(每个镜像一次)。
MAINTAINER
格式为 MAINTAINER <name> ,指定维护者信息。
RUN
格式为 RUN <command> 或 RUN ["executable", "param1", "param2"] 。前者将在 shell 终端中运行命令,即 /bin/sh -c ;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"] 。每条 RUN 指令将在当前镜像基础上执行挃定命令,幵提交为新的镜像。当命令较长时可以使用 \ 来换行。
CMD
支持三种格式CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;指定启动容器时执行的命令,每个 Dockerfile 叧能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。
EXPOSE
格式为 EXPOSE <port> [<port>...] 。指定 Docker 服务端容器暴露的端口号,供关联系统使用。在启动容器时需要通过 -P, Docker 主机会自动分配一个端口转发到指定的端口。
ENV
格式为 ENV <key> <value> 。指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。例如:
ADD
格式为 ADD <src> <dest> 。该命令将复制指定的 <src> 到容器中的 <dest> 。 其中 <src> 可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
COPY
格式为 COPY <src> <dest> 。复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径)到容器中的 <dest> 。当使用本地目录为源目录时,推荐使用 COPY 。
ENTRYPOINT
两种格式:
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。每个 Dockerfile 中叧能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效。
VOLUME
格式为 VOLUME ["/data"] 。创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
USER
格式为 USER daemon 。指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例
如: RUN groupadd -r postgres && useradd -r -g postgres postgres 。要临时获取管理员权限可以使用gosu ,而不推荐 sudo 。
WORKDIR
格式为 WORKDIR /path/to/workdir 。为后续的 RUN 、 CMD 、 ENTRYPOINT 指令配置工作目录。可以使用多个 WORKDIR 挃令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如
则最终路径为 /a/b/c 。
ONBUILD
格式为 ONBUILD [INSTRUCTION] 。配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。例如, Dockerfile 使用如下的内容创建了镜像 image-A 。
如果基于 image-A 创建新的镜像时,新的Dockerfile中使用 FROM image-A 指定基础镜像时,会自动执行ONBUILD 指令内容,等价亍在后面添加了两条指令。
使用 ONBUILD 指令的镜像,推荐在标签中注明,例如 ruby:1.9-onbuild 。
从本地文件系统导入
要从本地文件系统导入一个镜像,可以使用 openvz(容器虚拟化的先锋技术)的模板来创建。比如,先下载了一个 ubuntu-14.04 的镜像,之后使用以下命令导入:
然后查看新导入的镜像。
用户可以通过 docker push 命令,把自己创建的镜像上传到仓库中来共享。例如,用户在 Docker Hub 上完成注册后,可以推送自己的镜像到仓库中。