网站备案找回密码,wordpress+app+打包,指定网站长期建设 运营计划,网页制作工具的英文名一、导读
本文主要介绍在编写 docker 镜像的时候一些需要注意的事项和推荐的做法。
虽然 Dockerfile 简化了镜像构建的过程#xff0c;并且把这个过程可以进行版本控制#xff0c;但是不正当的
Dockerfile 使用也会导致很多问题。 docker 镜像太大。如果你经常使用镜像或者…一、导读
本文主要介绍在编写 docker 镜像的时候一些需要注意的事项和推荐的做法。
虽然 Dockerfile 简化了镜像构建的过程并且把这个过程可以进行版本控制但是不正当的
Dockerfile 使用也会导致很多问题。 docker 镜像太大。如果你经常使用镜像或者构建镜像一定会遇到那种很大的镜像甚至有些能达到 2G 以上docker 镜像的构建时间过长。每个 build 都会耗费很长时间对于需要经常构建镜像比如单元测试的地方这可能是个大问题重复劳动。多次镜像构建之间大部分内容都是完全一样而且重复的但是每次都要做一遍浪费时间和资源 希望读者能够对 docker 镜像有一定的了解阅读这篇文章至少需要一下前提知识 了解 docker 的基础概念运行过容器熟悉 docker 镜像的基础知识知道镜像的分层结构最好是负责过某个 docker 镜像的构建使用 docker build 命令创建过自己的镜像Dockerfile 和镜像构建 Dockerfile 是由一个个指令组成的每个指令都对应着最终镜像的一层。每行的第一个单词就是命令后面所有的字符串是这个命令的参数关于 Dockerfile 支持的命令以及它们的用法可以参考官方文档这里不再赘述。
当运行 docker build 命令的时候整个的构建过程是这样的
a. 读取 Dockerfile 文件发送到 docker daemon
b. 读取当前目录的所有文件context发送到 docker daemon
c. 对 Dockerfile 进行解析处理成命令加上对应参数的结构
d. 按照顺序循环遍历所有的命令对每个命令调用对应的处理函数进行处理
e. 每个命令除了 FROM都会在一个容器执行执行的结果会生成一个新的镜像,为最后生成的镜像打上标签
二、编写 Dockerfile 的一些最佳实践
1.使用统一的 base 镜像
有些文章讲优化镜像会提倡使用尽量小的基础镜像目前集团操作系统一级提供统一的基础镜像一些BU也根据自己的技术规范定义了BU级的基础镜像一般的应用只需要FROM自己BU提供的基础镜像即可因为基础镜像只需要下载一次可以共享并不会造成太多的存储空间浪费。它的好处是这些镜像的生态比较完整方便我们安装软件除了问题方便调试。
2.动静分离
经常变化的内容和基本不会变化的内容要分开把不怎么变化的内容放在下层创建出来不同基础镜像供上层使用。比如可以创建各种语言的基础镜像这些镜像包含了最基本的语言库每个组可以在上面继续构建应用级别的镜像。
3.最小原则只安装必需的东西
很多人构建镜像的时候都有一种冲动——把可能用到的东西都打包到镜像中。要遏制这种想法镜像中应该只包含必需的东西任何可以有也可以没有的东西都不要放到里面。因为镜像的扩展很容易而且运行容器的时候也很方便地对其进行修改。这样可以保证镜像尽可能小构建的时候尽可能快也保证未来的更快传输、更省网络资源。
4.一个原则每个镜像只有一个功能
不要在容器里运行多个不同功能的进程每个镜像中只安装一个应用的软件包和文件需要交互的程序通过 容器之间的网络进行交流。这样可以保证模块化不同的应用可以分开维护和升级也能减小单个镜像的大小。
5.使用更少的层
虽然看起来把不同的命令尽量分开来写在多个命令中容易阅读和理解。但是这样会导致出现太多的镜像层而不好管理和分析镜像而且镜像的层是有限的。尽量把相关的内容放到同一个层使用换行符进行分割这样可以进一步减小镜像大小并且方便查看镜像历史。
6.减少每层的内容
尽管只安装必须的内容在这个过程中也可能会产生额外的内容或者临时文件我们要尽量让每层安装的东西保持最小。
比如使用 --no-install-recommends 参数告诉 apt-get 不要安装推荐的软件包
7.不要在 Dockerfile 中单独修改文件的权限
因为 docker 镜像是分层的任何修改都会新增一个层修改文件或者目录权限也是如此。如果有一个命令单独修改大文件或者目录的权限会把这些文件复制一份这样很容易导致镜像很大。
解决方案也很简单要么在添加到 Dockerfile 之前就把文件的权限和用户设置好要么在容器启动脚本entrypoint做这些修改或者拷贝文件和修改权限放在一起做这样最终也只是增加一层。
8.利用 cache 来加快构建速度
如果 Docker 发现某个层已经存在了它会直接使用已经存在的层而不会重新运行一次。如果你连续运行 docker build 多次会发现第二次运行很快就结束了。
不过从 1.10 版本开始Content Addressable Storage 的引入导致缓存功能的实效目前引入了 --cache-from 参数可以手动指定一个镜像来使用它的缓存。
反之如果想要缓存失效禁用此层及后面层的缓存可以在对应层前加LABEL语句
LABEL keyvalue 每次修改value的值使得缓存失效。
9.版本控制和自动构建
最好把 Dockerfile 和对应的应用代码一起放到版本控制中然后能够自动构建镜像。这样的好处是可以追踪各个版本镜像的内容方便了解不同镜像有什么区别对于调试和回滚都有好处。
另外如果运行镜像的参数或者环境变量很多也要有对应的文档给予说明并且文档要随着 Dockerfile 变化而更新这样任何人都能参考着文档很容易地使用镜像而不是下载了镜像不知道怎么用。
10.使用一个.dockerignore文件
在大部分情况下最好的做法是将每一个Dockerfile文件放到一个空的文件夹里。接着把构建Dockerfile所需的文件添加到这个文件下。为了提高构建的效率你可以在这个文夹下添加一个.dockerignore 文件来排除那些没用的文件和文件夹。这个文件支持类似 .gitignore 文件那样的排除模式。关于如何创建它可以移步到dockerignore 文件。