Dockerfile使用的整理

最近使用Dockerfile构建docker镜像,总结了一下一些指令规范,整理如下:

Dockerfile 书写原则

(1)Dockerfile 的指令是忽略大小写的,建议使用大写

(2)提供注释信息

Dockerfile 也是一种代码,我们应该保持良好的代码编写习惯,晦涩难懂的代码尽量添加注释,让协作者可以一目了然地知道每一行代码的作用,并且方便扩展和使用。

 

(3)保持容器最小化

 应该避免安装无用的软件包。


(4)合理选择基础镜像


(5)使用 .dockerigonre 文件

使用 .dockerignore 文件,允许我们在构建时,忽略一些不需要参与构建的文件,避免将不必要的文件, 拷贝到镜像中, 比如 .git,.java等,如此,构建镜像的过程通常会更快, 生成的镜像通常会更小, 整个部署过程耗时更少, 也避免k8s work nodes磁盘被大量镜像文件占用。

因此,需要在项目中,在 Dockerfile 工作的根目录下添加 .dockerignore 文件,文件里面包含内容如下:

**/*.git


**/*.java


其中,**/*.java 仅后端项目需要。

注:请严格按照上述格式编写,可以保证任意层级存在 .git 或 .java 文件均被排除在打包镜像之外。

其他使用方式可参加官方文档:.dockerfile file

在无法优化构建流程时, 可使用镜像压缩工具docker-squash


(6)尽量使用构建缓存

Docker 构建过程中,每一条 Dockerfile 指令都会提交为一个镜像层,下一条指令都是基于上一条指令构建的。如果构建时发现要构建的镜像层的父镜像层已经存在,并且下一条命令使用了相同的指令,即可命中构建缓存。

因此,基于 Docker 构建时的缓存特性,我们可以把不轻易改变的指令放到 Dockerfile 前面(例如安装软件包),而可能经常发生改变的指令放在 Dockerfile 末尾(例如编译应用程序)。




(7)最小化镜像层数

在构建镜像时尽可能地减少 Dockerfile 指令行数,尽量在一个 RUN 指令中运行更多的命令,以此提高性能,减少 IO 损耗。



Dockerfile 指令书写建议

(1)RUN

RUN 指令在构建时将会生成一个新的镜像层并且执行 RUN 指令后面的内容。

使用 RUN 指令时,应尽量遵循以下原则:

1. 指令后面的内容比较复杂时,建议使用反斜杠(\)结尾并换行;

2. 使用 ‘yum install …’ 时, 建议在同一个 RUN 命令中, 使用 ‘yum clean all && rm -rf /var/cache/yum’ 来清理多余文件.


(2)CMD 和 ENTRYPOINT

这两个指令都是容器的入口,这两个指令的相同之处在于:

1.  使用格式基本分为两种:

第一种称为 exec 模式(推荐使用),书写格式为:


CMD / ENTRYPOINT  [“command”,  “param”]


指令后面跟 json 数组,是 Docker 推荐的使用格式,也是我们项目建议使用的格式。


第二种称为 shell 模式,当时使用 shell 模式时,Docker 会以 /bin/sh -c command 的方式执行命令。


CMD 和 ENTRYPOINT 区别在于:

1.  Dockerfile 中如果使用了 ENTRYPOINT 指令,启动 Docker 容器时,只有使用 --entrypoint 参数才能覆盖 Dockerfile 中的 ENTRYPOINT 指令;而使用 CMD 设置的命令,则可以被 docker run 后面的参数直接覆盖。

CMD 和 ENTRYPOINT 指令可以单独使用,也可以组合使用。


综上,如果在构建 Docker 容器时,需要执行单一的具体程序,不希望用户在执行 docker run 时覆盖默认程序,建议使用 ENTRYPOINT;如果需要镜像足够灵活,建议使用 CMD 指令。


(3)ADD 和 COPY

两个指令功能类似,都是从外部向容器中添加文件。但是 COPY 命令只支持基本的文件和目录的拷贝, ADD 支持更多的文件类型,所以若需要将外部的压缩文件解压到镜像中, 请使用 ADD 指令, 而不是 COPY +  RUN untar … 组合指令, 因为 ADD 指令可自动解压 + 复制。


(4)WORKDIR

用来指定容器的工作路径。


(5)ENV

用于设置环境变量,书写格式推荐写为:


ENV <key>=<value>


当有多组环境变量,书写多行 ENV 即可。

若 build 镜像时, 需要通过代理访问网络, 可尝试使用 ENV http_proxy … 和 ENV https_proxy … 指令, 并在使用后销毁。


日常可使用 docker image prune 和 docker container prune 来清理无用空间。


Docker 容器内的配置

1.除配置性质的文件外, 请不要在容器自身的文件系统中写数据, 转而使用外接volume; 

2.stdout仅输出重要提示信息, 请勿当做常规日志数据通道.


参考文档

官方 Dockerfile 最佳实践

https://stackoverflow.com/questions/45142528/what-is-a-dangling-image-and-what-is-an-unused-image

https://docs.docker.com/engine/reference/commandline/image_prune/

https://docs.docker.com/engine/reference/commandline/container_prune/

posted on 2020-11-18 11:01  101欢欢鱼  阅读(274)  评论(0编辑  收藏  举报

导航