0%

DockerFile

Docker File 解析:

构建简史

编写一个 dockerfile 的文件,符合 dockerfile 的规范 docker build 执行,获得一个自定义的镜像 docker 运行 Docker 执行 docker file 文件的大致流程

docker 从基础镜像运行一个容器 执行一条指令并对容器作出修改 执行类似 docker commit 的操作提交一个新的镜像层 docker 在基于刚提交的镜像运行一个新容器 执行 docker 中的下一条指令知道所有指令都执行完成

Docker File 基础知识:

每条保留字指令必须为大写字母且后面要跟随至少一个参数 指令从上到下、从左至右执行 ‘#’ :表示注释 每条指令都会创建一个新的镜像层,并对镜像进行提交

Docker File 体系结构:

保留字指令:

FROM:基础镜像,当前这个新的镜像是基于哪个镜像(scratch) MAINTAINER:镜像作者+邮箱 RUN:容器构建时所需要运行的命令 EXPOSE:当前容器对外暴露的端口号 WORKDIR:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点 ENV:用于构建镜像过程中设置环境变量 ADD: 拷贝加解压缩:将宿主机目录下的文件拷贝进镜像且 add 命令会自动处理 rul 和解压 tar 压缩包 COPY:将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置

  • COPY src dest
  • COPY [“src”,”dest”]

VOLUME:容器数据卷,用于数据保存和持久化工作 CMD:

  • 指定一个容器启动时要运行的命令
  • DockerFile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换!!!

ENTRYPOINT:

  • 指定一个容器启动时要运行的命令
  • 目的与 CMD 一样,都是在指定容器启动程序及参数
  • 不会被替换,被追加

ONBUILD:触发器 当构建一个被继承 Docker File 时运行的命令,父镜像在被子继承后父镜像的 onbuild 被触发

关键字详解

Dockerfile 分为四部分:

基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

基础镜像信息

FROM

1
2
# 格式
FROM <image> or FROM <image>:<tag>

如果在同一个 Dockerfile 中创建多个镜像时,可以使用多个 FROM 指令(每个镜像一次)

注意: Dockerfile 每个保留字都会在 docker 容器中新建一层镜像层, 合理的减少镜像层以达节省资源的目的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# base
FROM python:3.7
RUN pip3 install requests
RUN pip3 install bs4
RUN pip3 install scrapy
RUN ...

# other
FROM python:3.7
RUN pip3 install requests bs64 scrapy # Python通过空格分隔,达到安装多个包的效果

# batter
# 外部建立所安装包
pip3 freeze >> requirements.txt
# 在Dockerfile 中
FROM python:3.7
RUN pip3 install -r requirements.txt

分析: 达到的效果虽相同,但所用资源却不同, base 所使用的资源约为 other,batter 的 3/5

  • base 三层
  • other 一层
  • batter 一层
  1. 若所需要使用到的第三方库较少,建议使用 other
  2. 在实际工程中用到的第三方库大多情况下都大于三个,方法二虽好.但所需导入的包一多,很可能出现单词拼写错误, 格式不符

维护者信息(非必须)

MAINTAINER

1
2
# 格式
MAINTAINR <name>

镜像操作指令(按需择选)

COPY

作用: 复制文件指令,从上下文 目录中复制或目录, 到容器中的指定路径 同等需求下建议使用 COPY

1
2
3
4
5
6
# 格式
COPY <src> <dest>
COPY [--chown=<user>:<group>] <源路径1>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
# [--chown=<user>:<group>]:可选参数,用户改变复制到容器内文件的拥有者和属组。
# 复制本地主机的 `<src>`(为 Dockerfile 所在目录的相对路径)到容器中的 `<dest>`

<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。

1
2
COPY hom* dir/
COPY hom?.txt dir/

<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

ADD

作用: 复制文件指令,从上下文 目录中复制或目录, 到容器中的指定路径 同等需求下建议使用 COPY

1
2
3
4
5
# 格式
ADD <src> <dest>`

# 该命令将复制指定的 `<src>` 到容器中的 `<dest>`。
# 其中 `<src>` 可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
  • ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
  • ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定

小结:

  • ADD 与 COPY 功能无明显差异, 但针对性不同
  • 当使用本地文件为源目录时,建议使用 Copy
  • 当需使用压缩包中文件时构建时,建议使用 Copy

RUN

作用: 用于在容器内执行命令

1
2
3
# 格式
RUN <command> [option] # 相当于shell格式
RUN ["command", "option1", 'option2'] # 相当于 exec 格式

WORKDIR

作用:指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作(主)目录,必须是提前创建好)。 docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。

1
2
# 格式
WORKDIR <dir>

USE

作用:用于指定将使用命令的用户和用户组 此处只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。 由于 docker 无设置,默认需在 root 权限下运行 正所谓权限越大能力越大,若被入侵则造成损失较于其他权限为最大 安全与灵活性 二者相对斟酌

1
2
# 格式
USER <username>[:<usergroup>]

EXPOSE

作用:仅声明端口

  • 方便配置映射
  • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
1
2
# 格式
EXPORT <port1> [<prot2> <prot3> ...]

执行指令

CMD

作用: 类似于 RUN 命令,但运行处不同

  • RUN 在 Docker build 前运行
  • CMD 在 docker run 后运行

注意:

  • 当 Dockerfile 中存在多个 CMD 指令,仅最后一个生效。
  • CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

当使用自定制镜像时,大致流程为

  • 编写业务代码
  • 构建定制镜像(docker build)
  • docker 中运行业务 (Docker run)
1
2
3
4
5
# 格式
CMD <ShellCommand1 [option]> [&&ShellCommand2[option] ]
CMD ["<可执行命令或文件>", "<option1>", "<option2>", ... ]
# 此写法为保留字 ENTRYPOINT 指令指定的程序提供默认参数
CMD ["<command1>", "<command2>", "<command3>", ...]

ENTRYPOINT

作用: 功能与 CMD 相似,但不会被 docker run 后的指定参数所覆盖, 命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。 但是当 docker run 使用了 —entrypoint 选项此选项的参数,可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。 ENTRYPOINT CMD 对比 同: 多个 指令,仅最后一个生效。 异: ENTRYPOINT 选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。

1
2
# 格式
ENTRYPOINT ["<可执行命令或文件>","option1", "option2"]

ENV

作用:配置容器内的环境变量,且保存,可以被后续 指令使用

1
2
3
# 格式
ENV <Key> <Values>
ENV <Key1>=<Values1>, <Key2>=<Values2> ...

ARG

作用:配置容器内的环境变量,且保存,可以被后续 指令使用(与 ENV 功能相似) 不同:作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效 也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

1
构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。
1
2
3
# 格式
ARG <key>[=默认值], <Value>
# 若不写Value 则Build时为自己写的默认值

VOLUME

作用:定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

  • 避免重要的数据,因容器重启而丢失
  • 避免容器不断变大
1
2
3
# 格式:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。

HEALTHCHECK

作用: 用于指定某个程序或者指令来监控 docker 容器服务的运行状态。

格式:

1
2
3
HEALTHCHECK [option] CMD <command> #设置检查容器健康状况的命令
HEALTHCHECK NONE # 如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK [option] CMD <command> # CMD 后面跟随的命令使用

ONBUILD

作用: 用于延迟构建命令的执行。 先构建一个父类镜像(ONBUILD 在父类中,但不立即执行),后子类继承此父类镜像(执行父类的 ONBUILD 命令) 本次并不执行,当镜像调用它时,将执行父类中 ONBUILD 命令

1
2
# 格式
ONBUILD <其它指令>