优化Dockerfile最佳实践

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xyz_dream/article/details/89741751
1.原文参考

地址: https://blog.fundebug.com/2017/05/15/write-excellent-dockerfile/

2.总结

原文总结如下:
在这里插入图片描述
对于其中"编写.dockerignore文件","合理调整COPY与RUN的顺序"不太好理解,其他的都还挺好理解。 该条本质上是对dockerfile在build时利用缓存的原因。

  1. 实验: 执行相同的docker build 一个是存在无效的大文件, 一个是不存在无效大文件时, 两者耗时巨大差距。 可以通过删除文件或者添加.dockerignore文件声明忽略文件,将那些不相干的文件排除,加速构建时间。在这里插入图片描述
    可以参考官方文档地址:

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#understand-build-context

  1. “合理调整COPY与RUN的顺序”’

其实是巧妙的利用docker build的缓存机制来实现。官方文档是这么描述构建缓存的:

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#understand-build-context

总结几句话: 1.每条指令只要前面的指令缓存失效, 则随后指令构建的镜像都不再使用缓存。 2.对应COPY和ADD文件会检验文件的校验和, 改变则缓存失效。

那么 我们可以总结一个规律, 对于 类似 COPY WORKDIR ENV LABEL 等命令,可以往后放,进行把变化频率小的往前放, 经常可能变化的命令往后放。 因为假设把经常变化的指令放在前面, 根据规定1, 缓存没有命中,则后面都要重新打镜像。

实验截图:
v1 Dockerfile (v1第一次构建应该时间最长 有下载wget.)

FROM alpine

RUN apk update  && apk add wget

CMD ["/bin/sh","-c","echo hello"]

在这里插入图片描述
V2 Dockerfile (v2把label放到run后面 run缓存命中。应该很快 )
在这里插入图片描述

FROM alpine

RUN apk update  && apk add wget

LABEL  name=v2     # 将label命令放在  run之后    此时前面的run 会命中缓存 节约时间,从这里这一行指令往下
#都不会使用缓存cache

CMD ["/bin/sh","-c","echo hello"]

v3 Dockerfile (v3把label放到run前面, label缓存没命中,所以根据规定, 从此往下所有命令的缓存无效。 会比v2慢)

FROM alpine

LABEL  name=v3   #  从这里开始 往后  所有缓存无效。  

RUN apk update  && apk add wget

CMD ["/bin/sh","-c","echo hello"]

实验截图:

在这里插入图片描述

由此可以知道了构建Dockerfile的优化过程还是很重要的。 docker入门的时候要求是,学会使用以及 编辑dockerfile即可。 但是进阶之后,重点要学会优化!!!! 上面只是很简单的demo,构建时间都能差几十倍。 如果是正式项目, 那可能就因为一个简单的label位置, build时间浪费很多。

3.Dockerfile多阶段构建

docker版本在17.04以后提出了称为"多阶段构建"模式。 直接白话进入重点:
1.dockerfile中可以使用多个FROM语句。 FROM语句 还可以加一个自己的别名,用来标明阶段工程。 例如 FROM ubuntu:16.04 as base-container
2.后阶段的镜像构建,可以使用COPY拷贝前面一个阶段镜像内生成的产物。 如文件, 可执行程序等等。
下面是demo演示:
假设场景, 对于一个Java 项目,你想使用一个"编译容器"去编译你的代码变成.class字节码文件,然后把代码从容器拷贝出来,然后再把这个字节码文件放到"生产环境"的一个容器中去运行."编译容器"镜像很大,而且没必要生成,因为你最终想要的产物只是.class文件罢了。最终产物是"生成环境"容器以及.class文件。

1.最原始以及还没出现"多阶段构建"的解决方案(编写一个shell脚本以及2个Dockerfile)
shell脚本大致工作内容如下:

1.  编写编译容器Dockerfile,  把源Java代码拷贝进容器,然后编译,生成在一个目录中。
假设目录路径 /home/java/code.class
2. docker build -t java:build .
3. 运行编译容器
4. docker cp  容器:/home/java/code.class  ./  #把编译好的产物从容器拷贝出来到宿主机上
5. 编写生产环境Dockerfile
6. 将code.class拷贝到生产环境Dockerfile中
7. docker build java:production .  #最终生成  目标镜像
8. rm  code.class #删除宿主机的文件
9. docker rmi java:build  #删除无用(中间状态的构建容器)
10.docker rm -f build容器 

2.Docker多阶段构建解决方案

FROM  java  as build  #1.构建阶段别名
COPY code.java /home/java
WORKDDIR  /home/java
RUN java -c code.java

FROM java as production #2.构建阶段别名
COPY --form=build /home/java/code.class /home/java/code.class  #重点!!! 直接从第一阶段拷贝产物文件
WORKDIR  /home/java
CMD ["java","code"]

#  相对1解决方案  清晰明了   不用bash脚本了

docker build -t java:production .   #直接指挥生成最后一个阶段构建的容器   

#假设想单独生成某个阶段容器
docker build -t java:build  --target=build(构建阶段名称)  .   

展开阅读全文

Dockerfile 最佳实践

07-25

<p>n Docker 是 PaaS 供应商 DotCloud 开源的一个基于 LXC 的高级容器引擎,基于 Go 语言开发并遵从Apache 2.0  协议,通过内核虚拟化技术(namespaces及cgroups等,这里的内核技术指的是Linux内核)来提供容器的资源隔离与安全保证等。由于docker通过操作系统层的虚拟化实现隔离,所以在运行时,不需要额外的虚拟化管理程序(VMM(Virtual Machine Monitor),以及Hyperisor)支持,它属于内核级虚拟化,可以实现更高的性能,同时对资源的额需求更低。它和KVM 虚拟化的区别在于:docker是通过隔离来进行创建容器,而KVM虚拟化通过模拟方式创建虚拟机。n</p>n<p>n  n</p>n<p>n 本课程学习需具有一定的 Linux 基础知识,属于基础类型课程,为后面的 Devops 学习打下根基,主要讲解了以下几个方面:n</p>n<p>n  n</p>n<p>n 1.<span style="font-size:9px;">     </span>容器架构以及术语的介绍n</p>n<p>n 2.<span style="font-size:9px;">     </span>镜像知识的讲解与运用n</p>n<p>n 3.<span style="font-size:9px;">     </span>容器常见操作以及资源限制n</p>n<p>n 4.<span style="font-size:9px;">     </span>Docker 公共仓库和私有仓库创建以及使用n</p>n<p>n 5.<span style="font-size:9px;">     </span>Docker 数据卷和网络的知识介绍n</p>n<p>n <br /></p>n<p>n 课程使用的软件版本:n</p>n<p>n <img src="https://img-bss.csdn.net/201907250618331643.png" alt="" /></p>n<p>n <br /></p>n<p>n 课件插图:n</p>n<p>n <img src="https://img-bss.csdn.net/201907250619009469.png" alt="" /></p>n<p>n <img src="https://img-bss.csdn.net/201907250619175916.png" alt="" /></p>n<p>n <br /></p>

虚拟化技术 - DockerFile - 2 -DockerFIle展示

05-08

<p>n <span style="color:#404040;">虚拟化诞生的重要原因就是提升资源利用率,从而起到节约成本的主要目的,这也是高级运维工程师必须掌握的技能之一。</span>n</p>n<p>n <span style="color:#404040;"><span style="color:#404040;">本套视频完整的讲解了虚拟化在不同阶段出现的关键性技术。</span><br /><br /><span style="color:#404040;">Vcent是 VMware 公司出品的企业级虚拟化产品,也是公认最优秀的虚拟化产品之一,在世界百强企业的利用率居高不下。Vcent 是一种基础架构虚拟化,或者我更愿意称它为“传统虚拟化”,基于裸金属结构模式开发而来,大大提升了稳定性以及运行效率。在视频中讲解了虚拟化的常见分类、安装 、网络配置、资源分割等常用技术,让你在生产化境配置中游刃有余!</span><br /><br /><span style="color:#404040;">Docker为 DockerCloud公司出品,现已成为了容器级虚拟化的标准方案。Docker的优点非常众多,但是最让人印象深刻的莫过于“秒”级启动了,这是很多平台常用的一种描述方式。其实,这种说法不太友好,应该说为容器的启动时间等于容器内部进程的启动时间,这就可以让我们做到很多事情了。比如,不再去关注进程的失败原因从而找到解决方案,只需关心当前是否存在即可,失败 〉删除容器 〉重新启动容器,成了我们常见的操作。视频中对Docker技术的讲解非常细致,Docker常用命令、网络、存储、驱动、仓库一应俱全,是你走入容器世界的必备资料</span><br /><br /><span style="color:#404040;">OpenStack,也就是常说的云计算平台,它在云计算市场的使用率达到了自然垄断的地位。比如:阿里云、百度云、红帽云平台等都是使用OpenStack作为底层平台为构建基础。如果你处于云计算行业,那么OpenStack是你的必备技能。视频中对OpenStack框架进行分离讲解,对不同的组件进行解析安装到最终的实例部署构建,带你走入云计算的大门!</span><br /><span style="color:#404040;">关于虚拟化的技术,这里应有尽有,快来学习吧!</span><br /><br /><span style="color:#404040;">本视频中:</span><br /><span style="color:#404040;">01-02为虚拟化概述</span><br /><span style="color:#404040;">03-06为Vcent</span><br /><span style="color:#404040;">07-29为Docker</span><br /><span style="color:#404040;">30-53为云计算OpenStack</span><br /></span>n</p>

没有更多推荐了,返回首页