Docker镜像优化打包速度思考

 更新时间:2023年05月08日 10:24:27   作者:在下uptown  
本文主要介绍了Docker镜像优化打包速度思考,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

image.png

当下主流的业务架构大部分会选择用容器进行部署,并结合一些容器编排技术k8s技术。由于公司业务调整,jenkins打包的工作交付到我这边来负责。

结果组长上来就给我一个当头一棒,打包速度太慢,尽量优化下。我寻思过年也没忘记给拜年啊,不行把送出去的特产要回来吧,没啥用啊,净给整这一出。

说归说闹归闹,别拿绩效开玩笑,毕竟这年终还没发呢,该忍还得忍。君让臣死,臣不得不死,硬着头皮上吧

压缩镜像大小

优化第一步,瘦身,docker images查看了下基础服务的镜像大小,好家伙没有小于300M的,一个普通的小服务都要300多,显然在镜像体积上可以做做文章。

在Docker官方的建议中有一个点,使用更小的基础镜像。而在小的基础镜像中全网的一致答案都是alpine了。

alpine是一个非常特别的Linux版本,大小才5M左右,最早适用于嵌入式系统,但随着容器的流行,这个才5M大小的Linux在Docker中流行起来了,因为太小了,非常节省空间。

这里就对比下同样属于Linux镜像centeros与alpine的大小

REPOSITORY TAG IMAGE ID CREATED SIZE
alpine 3.16.2 9c6f07244728 7 days ago 5.54MB
centeros latest df5de72bdb3b 2 weeks ago 77.8MB

解决完基础镜像再来研究下第三方包是不是有可优化的点,仔细分析Dockerfile发现在构建过程中去拉代码打包的,那么构建过程中就会存在大量运行时不需要的包。这部分清掉基本上就可以瘦身成功了。

构建过程中,通过apk安装软件包时,可以指定虚拟包.build-deps,这样git之类的工具归属到虚拟包下,由于仅是构建阶段用到的命令,如执行npm installpip install,当把项目构建完以后,通过apk del .build-deps清理掉所有临时命令即可。

这样就可以保证构建出的镜像最小了。

利用缓存加速打包速度

docker本身是有缓存机制的,也就是每次build的时候会检查Dockerfile是否发生了变更,这里要注意是Dockerfile发生了变更,并不是代码发生变更。

得到这个结论的时候其实我是很迷惑的,照这么来说的话,Dockefile基本不会变,每次走缓存为什么jenkins打包速度这么慢呢。

后来在build命令里发现了端倪,有人在docker build时加了--no-cache参数,因为代码是在镜像构建时拉取的,每次走了缓存那么代码就不会拉取了,每次都会走缓存。所以为了避免代码不对运维在命令里加了--no-cache

那怎么办呢,因为Dockefile执行从上到下依次执行。把代码放到最低端,通过定义随机数或时间戳的方式使拉代码的命令缓存失效而不影响上面的第三方包的安装。

42ce9b8428f6effa08aa41798c5e798.jpg

岂不美哉。

Multi-stage Build

Docker 提供了 Multi-stage Build(多阶段构建),可以实现镜像瘦身。

我们将镜像构建分成两个阶段:

在 ”build“ 阶段依然采用 JDK 作为基础镜像,并利用 Maven 进行应用构建; 在最终发布的镜像中,我们会采用 JRE 版本作为基础镜像,并从”build“ 镜像中直接拷贝出生成的 jar 文件。这意味着在最终发布的镜像中,只包含运行时所需必要内容,不包含任何编译时依赖,大大减少了镜像体积。

FROM adoptopenjdk/openjdk8 AS build
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/' /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y \
git \
maven
WORKDIR /tmp
RUN git clone https://github.com/spring-projects/spring-petclinic.git
WORKDIR /tmp/spring-petclinic
RUN mvn install
FROM adoptopenjdk/openjdk8:jre8u222-b10-alpine-jre
COPY --from=build /tmp/spring-petclinic/target/spring-petclinic-2.1.0.BUILD-SNAPSHOT.jar spring-petclinic-2.1.0.BUILD-SNAPSHOT.jar
CMD ["java","-jar","spring-petclinic-2.1.0.BUILD-SNAPSHOT.jar"]

Java打包测试

springboot背景下,在默认的maven打包插件加入分层打包配置

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <layers>
                        <enabled>true</enabled>
                    </layers>
                </configuration>
            </plugin>
        </plugins>
    </build>

再次进行打包分析操作mvn clean package,现在我们可以用下面命令来看分层打包编译的jar包结构 java -Djarmode=layertools -jar target/dockers-demo-0.0.1-SNAPSHOT.jar list

图片

可以看到layertools识别出jar包内将依赖打包到不同文件夹中,接下来我们改造下原有的dockerfile。

如果不分层打包的话,一次全量包会特别大。如果只更改部分代码的话。

FROM openjdk:8 as builder
RUN mvn clean package -DskipTests
# 声明端口并没有真正运行在这个端口
EXPOSE 8080
ADD ./target/*.jar ./app.jar
RUN java -Djarmode=layertools -jar app.jar extract
FROM openjdk:8-jre
MAINTAINER ttzommed@foxmail.com
WORKDIR application
# 复制第三方依赖、SpringBoot内部配置、快照依赖
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

依靠docker的分层特征,分次加入文件即可达到分层加速打包的效果

到此这篇关于Docker镜像优化打包速度思考的文章就介绍到这了,更多相关Docker镜像打包优化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 常用的Docker命令及示例汇总分析

    常用的Docker命令及示例汇总分析

    这篇文章主要介绍了常用的Docker命令及示例的汇总分析,附含源码示例分析,有需要的朋友可以借鉴参考下,希望可以对广大读者有所帮助
    2021-09-09
  • 深入理解docker的四种网络方式

    深入理解docker的四种网络方式

    本篇文章主要介绍了深入理解docker的四种网络方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • Vue.js中的watch属性详解

    Vue.js中的watch属性详解

    在Vue.js中,watch属性是一种非常重要的属性,它可以监听Vue实例中指定的数据变化,并在数据发生变化时执行相应的操作,本文将对 Vue.js中的watch属性进行详细的介绍,并附上相关的代码示例,需要的朋友可以参考下
    2023-06-06
  • docker中运行PostgreSQL容器的简单步骤

    docker中运行PostgreSQL容器的简单步骤

    这篇文章主要给大家介绍了关于docker中运行PostgreSQL容器的简单步骤,随着docker的广泛应用,为了提供便利的管理,PostgreSQL数据库也支持docker的安装方式,需要的朋友可以参考下
    2023-08-08
  • 在Docker中的ubuntu中安装Python3和Pip的问题

    在Docker中的ubuntu中安装Python3和Pip的问题

    这篇文章主要介绍了在Docker中的ubuntu中安装Python3和Pip的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • Docker创建Mysql容器的简单步骤

    Docker创建Mysql容器的简单步骤

    这篇文章主要给大家介绍了关于Docker创建Mysql容器的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Docker具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • Docker 配置容器固定IP的方法

    Docker 配置容器固定IP的方法

    这篇文章主要介绍了Docker 配置容器固定IP,下面使用docker自带的network实现固定ip分配,并且重启不会消失,通过绑定步骤给大家介绍的非常详细,需要的朋友参考下吧
    2022-04-04
  • docker 动态映射运行的container端口实例详解

    docker 动态映射运行的container端口实例详解

    这篇文章主要介绍了 docker 动态映射运行的container端口实例详解的相关资料,需要的朋友可以参考下
    2016-10-10
  • Docker核心原理之 Cgroup详解

    Docker核心原理之 Cgroup详解

    cgroup的内核通过hook钩子来实现管理进程资源,提供了一个统一的接口,从单个进程的资源控制到操作系统层面的虚拟卡的过渡,今天通过本文给大家介绍Docker核心原理之 Cgroup详解,需要的朋友参考下吧
    2021-07-07
  • Docker仓库常用命令详解

    Docker仓库常用命令详解

    这篇文章主要介绍了Docker仓库常用命令详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10

最新评论