Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。它们简化了从头到尾的流程并极
大的简化了 部署工作。Dockerfile从FROM命令开始,紧接着是各种方法、命令和参数。其产出为一个新的可以用于创建容器的镜像
使用Dockerfiles的优点
-干净,生成的镜像不会有日志文件、临时文件等东西
-灵活,可以挑选更合适的父镜像来编译
-可追溯,使用明确的步骤执行操作,通过history命令可以明确查看镜像的生成过程
1 查找 Docker Hub 上的 Dockerfile
Docker Hub 网站是容器镜像的常用搜索网站,在搜索镜像后,文档页中可能会提供其 Dockerfile 的链接
例如:打开 搜索mysql,在结果界面中,点开搜索结果中的mysql,就能看到这个镜像的具体信息,点开版本,里面
就有Dockerfiles
2 使用 OpenShift Source-to-Image 工具
Source-to-Image (S2I)提供了使用 Dockerfile 创建新容器镜像的替代选择,可以作为 OpenShift 的一项功能或单独的 s2i 实用程序来使用S2I 允许开发人员利用其常用的工具来操作,不需要学习 Dockerfile 语法和利用 yum 等操作系统命令,并且通常能创建层数较少的精简型镜像
S2I 利用下列流程为应用构建自定义容器镜像
从基础容器镜像(称为 构建器镜像)启动容器;基础容器镜像中包含编程语言运行时和基本的开发工具,如编译器和软件包管
理器
通常从 Git 服务器获取应用源代码,并将它发送到容器
在容器内构建应用二进制文件
在进行一些清理后,将容器保存为新的容器镜像,后者同时包含应编程语言运行时和应用二进制文件
怎么在 OpenShift 外的仅 Docker 环境中运行 S2I 流程?
安装 source-to-image RPM 软件包安装到 RHEL 系统上,也可通过在 GitHub 上的 S2I 项目中提供的安装程序安装到其他平台上,如 Windows 和 MacOS,可以获得s2i命令来执行s2i流程
3 使用Dockerfile构建自定义容器镜像
从 Dockerfile 构建镜像涉及三个步骤
1. 创建工作目录
docker 命令可 使用工作目录中的文件构建镜像
应创建空的工作目录以防将不必要的文件纳入镜像
出于安全原因,根目录 / 不应用作镜像构建的工作目录
2. 编写 Dockerfile 规格
Dockerfile 是应在工作目录中存在的文本文件
Dockerfile文件的基本语法
Docker文件中采用“键 值”方式定义
Docker文件中使用#作为注释,且#必须放在行首,放在行中不是注释
Dockerfile 中的指令按照其出现的顺序执行
第一条非注释指令必须是 FROM 指令,用于指定构建时要基于的基础镜像
每条 Dockerfile 指令均独立运行
Dockerfiles常用指令
FROM 指定base镜像
LABEL 添加元数据
MAINTAINER 设置镜像的作者
COPY 将文件从build context 复制到镜像,COPY src dest
ADD 与COPY类似,将文件从build context 复制到镜像,不同而是,ADD的src如果是归档文件(tar,zip,tgz,xz等),文
件会自动解压到dest
ENV 设置环境变量
EXPOSE 指定容器中的进程会监听某个端口,Docker可以将该端口开放出来
VOLUME 将文件或目录申明为volume
WORKDIR 为ADD、COPY、RUN、CMD、ENTRYPOINT指令设置镜像中的工作目录
RUN 在容器中运行指令,一般用来装包
CMD 容器启动后运行执行的命令
如果docker命令中指定了容器启动后运行的命令,这个指定会失效
Dockerfiles中可以设定多个CMD指令,但只有最后一个生效
ENTRYPOINT 设置容器启动时运行的命令
可以设定多个,但只有最后一个生效
CMD、docker run之后的参数都会被当做参数传递给ENTRYPOINT
示例1:构建一个Dockerfile 文件以用于生成Apache Web 服务器容器
#This is a comment line
FROM rhel7.5
LABEL description="This is a custom httpd image"
MAINTAINER Jingyan
RUN yum install -y httpd
EXPOSE 80
ENV Log "info"
ADD http://jingyan.com/img.pdf /var/www/html
COPY ./src/ var/www/html
USER apache
ENTRYPOINT ["/usr/sbin/httpd"]
CMD ["-D","FOREGROUND"]
总结一下通过Dockerfile构建镜像的过程:
(1)从base镜像运行一个容器。
(2)执行一条指令,对容器做修改。
(3)执行类似docker commit的操作,生成一个新的镜像层。
(4)Docker再基于刚刚提交的镜像运行一个新容器。
(5)重复2~4步,直到Dockerfile中的所有指令执行完毕。
从这个过程可以看出,如果Dockerfile由于某种原因执行到某个指令失败了,我们也将能够得到前一个指令成功执行构建出的镜像,这对调试Dockerfile非常有帮助。我们可以运行最新的这个镜像定位指令失败的原因。
1 井号 (#) 开头的行是注释
2 新容器镜像将在 rhel7.3 容器镜像基础上构建
可以将任何其他容器镜像用作基础镜像,而不仅限于来自操作系统分发的镜像
3 LABEL 负责添加通用元数据到镜像中
4 MAINTAINER 负责设置所生成的容器镜像的 Author 字段。您可以使用 docker inspect 命令查看镜像元数据
5 RUN 在当前镜像顶部的新层中执行命令,然后提交结果
所提交的结果将用于 Dockerfile 中的下一步
用于执行命令的 shell 是 /bin/sh
6 EXPOSE 指示容器在运行时侦听指定的网络端口
Docker 容器化环境使用此信息,通过链接的容器功能进行容器互连
EXPOSE 指令仅仅是元数据;不会使端口可从主机进行访问。docker run 命令的 -p 选项可以开放主机上的端口
7 ENV 负责定义可供容器使用的环境变量
可以在 Dockerfile 内声明多个 ENV 指令
可以在容器内使用 env 命令来查看各个环境变量
8 ADD 复制新文件、目录或远程 URL,并将它们添加到容器文件系统中
9 COPY 也复制新文件和目录,并将它们添加到容器文件系统中
COPY无法使用 URL
10 USER 指定运行容器镜像时要使用的用户名或 UID,用于 Dockerfile 中的 RUN、CMD 和ENTRYPOINT 指令
出于安全原因,最好定义 root 之外的其他用户名
11 ENTRYPOINT 指定在创建容器时要执行的默认命令
默认情况下,执行的命令是 /bin/sh -c,除非指定了 ENTRYPOINT
12 CMD 提供 ENTRYPOINT 指令的默认参数