dockerfile
问题
- docker镜像太大
- docker镜像构建时间太长
- 重复劳动,多次构建镜像之间大部分内容都是完全一样而且重复的,但是每次都要做一边,浪费时间和资源
运行docker build 命令之后,构建过程
- 读取dockerfile文件发送到docker daemon
- 读取当前目录的所有文件(context),发送到docker daemon
- 对dockerfile解析,处理成命令加上对应参数的结构
- 按照顺序循环遍历所有命令,对每个命令调用对应的处理函数进行处理
- 每个命令(除了FROM)都会在一个容器执行,执行的结果会生成一个新的镜像文件
- 为最后生成的镜像打上标签
编写dockerfile最佳实践
- 使用统一的base镜像
- 小的基础镜像busybox, alpine
- 统一熟悉的基础镜像Ubuntu, CentOs,只需下载一次可以共享,有比较完整的生态,方便安装软件,调试
- 动静分离
- 经常变化的内容和基本不会变的内容要分开,把不怎么变化的内容放在下层,创建出不同基础镜像供上层使用。
- 最小原则:每个镜像只安装必需的东西
- 镜像中应该只包含必需的东西,任何可以有也可以没有的东西都不要放到里面
- 镜像的扩展很容易,而且运行容器的时候也很方便对其进行修改
- 保证镜像尽可能的小,构建的时候尽可能的快,保证更快的传输,更省网络资源
- 一个原则:每个镜像只有一个功能
- 不要在容器里运行多个不同功能的进程,每个镜像只安装一个应用的软件和文件,需要交互的程序通过pod(kubernetes)或容器之间的网络进行交互
- 保证模块化,不同的应用可以分开维护升级,也能减小单个镜像大小
- 使用更少的层
- 不同的命令尽量分开来, 写在多个命令中容易阅读和理解。但是这样会导致出现太多的镜像层,而不好管理和分析镜像,镜像的层是有限的。
- 尽量把相关的内容放到同一个层,使用换行符进行分割,这样可以进一步减小镜像大小,方便查看镜像历史
1 2 3 4 5 6 7 8
RUN apt-get update\ && apt-get install -y --no-install-recommends \ bzr \ csv \ git \ mercurial \ subversion \ && apt get clean
- 减少每层内容
- 尽管只安装必需的内容, 在这个过程中可能会产生额外的内容或者临时文件,尽量让每层安装的东西最小
- 使用
--no-install-recommends, 告诉apt-get 不要安装推荐的软件包 - 安装完软件包,清除
/var/lib/apt/list/缓存 - 删除中间文件,比如压缩包
- 删除临时文件,命令产生了临时文件也要及时删除
- 使用
- 尽管只安装必需的内容, 在这个过程中可能会产生额外的内容或者临时文件,尽量让每层安装的东西最小
- 不要在dockerfile中单独修改文件权限
- docker镜像是分层的,任何修改都会新增加一层,修改文件或目录权限也是如此,也会导致镜像很大
- 在添加dockerfile前把文件权限和用户设置好
- 在容器启动脚本做修改(entrypoint)
- 拷贝文件和修改权限放在一起做
- docker镜像是分层的,任何修改都会新增加一层,修改文件或目录权限也是如此,也会导致镜像很大
- 利用cache加快构建速度
- 如果docker发现某个层已经存在,它会直接使用已经存在的层,而不会重新运行一次。
- 引入
--cache-from参数可以手动指定一个镜像来使用缓存
- 版本控制和自动构建
- dockerfile和对应的代码放到一起在版本控制中,然后能够自动构建镜像。这样的好处是可以追踪各个版本镜像的内容,方便了解不同镜像的区别,方便调试和回滚。
- 有对应的文档说明并且跟着dockerfile更新,方便任何人使用镜像