微信公众号:Aditya Bhuyan K8S中文社区

1、Docker关键概念

Docker有四个关键概念:images, layers, Dockerfile 和 Docker cache 。简而言之,Dockerfile描述了如何构建Docker镜像。镜像由许多层组成。Dockerfile从基础镜像开始,并添加了其他层。当新内容添加到镜像时,将生成一个新层。所构建的每个层都被缓存,因此可以在后续构建中重复使用。当Docker构建运行时,它可以从缓存中获取重复使用任何已有层。这就减少了每次构建所需的时间和空间。任何已更改或以前尚未构建的内容都将根据需要进行构建。

2、镜像层内容很重要

镜像各层的重要性。Docker缓存中的现有层,只有当改镜像层内容没有变更时,才能被使用。在Docker构建期间更改的层越多,Docker需要执行更多的工作来重建镜像。镜像层顺序也很重要。如果某个图层的所有父图层均未更改,则该图层就能被重用。因此,最好把比较频繁更改的图层放在上面,以便对其更改会影响较少的子图层。

镜像层的顺序和内容很重要。当你把应用程序打包为Docker镜像时,最简单的方法是将整个应用程序放置到一个单独的镜像层中。但是,如果该应用程序包含大量静态库依赖,那么即使更改很少的代码,也需要重新构建整个镜像层。这就需要在Docker缓存中,花费大量构建时间和空间。

3、镜像层影响部署

部署Docker镜像时,镜像层也很重要。在部署Docker镜像之前,它们会被推送到Docker远程仓库。该仓库是所有部署镜像的源头,并且经常包含同一镜像的许多版本。Docker非常高效,每个层仅存储一次。但是,对于频繁部署且具有不断重建的大体积层的镜像,这就不行了。大体积层的镜像,即使内部只有很少的更改,也必须单独存储在仓库中并在网络中推送。因为需要移动并存储不变的内容,这就会增加部署时间。

4、Docker中的Spring Boot应用

使用uber-jar方法的Spring Boot应用程序本身就是独立的部署单元。该模型非常适合在虚拟机或构建包上进行部署,因为该应用程序可带来所需的一切。但是,这对Docker部署是一个缺点:Docker已经提供了打包依赖项的方法。将整个Spring Boot JAR放入Docker镜像是很常见的,但是,这会导致Docker镜像的应用程序层中的不变内容太多。

5、单层方法

Docker的Spring Boot指南 列出了单层Dockerfile来构建你的Docker镜像:

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

它的最终结果是一个正常运行的Docker镜像,其运行方式与你期望Spring Boot应用程序运行的方式完全相同。但是,由于它基于整个应用程序JAR,因此存在分层效率问题。随着应用程序源的更改,整个Spring Boot JAR都会被重建。下次构建Docker镜像时,将重新构建整个应用程序层,包括所有不变的依赖库。

5.1 深入地研究单层方法

单层方法使用Open Boot JDK基础镜像之上的Spring Boot JAR作为Docker层构建Docker镜像:

$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
springio/spring-petclinic latest 94b0366d5ba2 16 seconds ago 140MB

生成的Docker镜像为140 MB。你可以使用docker history 命令检查图层 。你可以看到Spring Boot应用程序JAR已复制到镜像中,大小为38.3 MB。

docker history springio/spring-petclinic

下次构建Docker镜像时,将重新创建整个38 MB的层,因为重新打包了JAR文件。

在此示例中,应用程序的大小相对较小(因为仅基于spring-boot-starter-web和其他依赖项,例如spring-actuator)。在实际开发中,这些大小通常要大得多,因为它们不仅包括Spring Boot库,还包括其他第三方库。根据我的经验,实际的Spring Boot应用程序的大小范围可能在50 MB到250 MB之间(如果不是更大的话)。

仔细观察该应用程序,应用程序JAR中只有372 KB是应用程序代码。其余38 MB是依赖库。这意味着实际上只有0.1%的层在变化。其余99.9%不变。

5.2 镜像层生命周期

这是基于镜像层的基本考虑:内容的生命周期。镜像层的内容应具有相同的生命周期。Spring Boot应用程序的内容有两个不同的生命周期:不经常更改的依赖库和经常更改的应用程序类。

每次由于应用程序代码更改而重建该层时,也会包含不变的二进制文件。在快速的应用程序开发环境中,不断更改和重新部署应用程序代码,这种附加成本可能变得非常昂贵。

想象一个应用团队在Pet Clinic上进行迭代。团队每天更改和重新部署应用程序10次。这10个新层的成本为每天383 MB。如果使用更多实际大小,则每天最多可以达到2.5 GB或更多。最终将浪费大量的构建时间,部署时间和Docker仓库空间。

快速迭代的开发和交付是决定我们是继续使用简单的单层方法,还是采用更有效的替代方法。

一:优化Docker中的Spring Boot应用:单层镜像方法的更多相关文章

  1. 在Docker中部署Spring Boot项目

    想要获取更多文章可以访问我的博客 - 代码无止境. 微服务现在在互联网公司可谓非常流行了,之前找工作的的时候很多HR电话约面试的时候都会问对微服务是否有过接触.而微服务和Docker可以非常完美的结合 ...

  2. 【原创】Docker容器及Spring Boot微服务应用

    Docker容器及Spring Boot微服务应用 1 什么是Docker 1.1 Docker的出现 问题一:项目实施环境复杂问题 传统项目实施过程中经常会出现“程序在我这跑得好好的,在你那怎么就不 ...

  3. docker+jenkins实现spring boot项目持续集成自动化部署

    一.首先jenkins与docker的安装参考下面链接   安装jenkins:  https://www.cnblogs.com/jescs/p/7644635.html   安装docker:ht ...

  4. step6----->往工程中添加spring boot项目------->修改pom.xml使得我的project是基于spring boot的,而非直接基于spring framework

    文章内容概述: spring项目组其实有多个projects,如spring IO platform用于管理external dependencies的版本,通过定义BOM(bill of mater ...

  5. 第64节:Java中的Spring Boot 2.0简介笔记

    Java中的Spring Boot 2.0简介笔记 spring boot简介 依赖java8的运行环境 多模块项目 打包和运行 spring boot是由spring framework构建的,sp ...

  6. 使用Maven插件构建Spring Boot应用程序镜像

    使用Maven插件构建Spring Boot应用程序的Docker镜像. 环境准备 1.Linux系统 2.安装JDK,Maven 3.安装Docker 应用实践 1.在应用程序根目录下添加Docke ...

  7. 使用Spring Boot和AspectJ实现方法跟踪基础结构

    了解如何使用Spring Boot和AspectJ实现方法跟踪基础结构!最近在优锐课学习收获颇多,记录下来大家一起进步! 在我们的应用程序中,获取方法的堆栈跟踪信息可能会节省很多时间.具有输入输出参数 ...

  8. 在CentOS下的docker容器中部署spring boot应用的两种方式

    我们通常在 windows 环境下开发 Java,而通常是部署在Linux的服务器中,而CentOS通常是大多数企业的首选,基于Docker的虚拟化容器技术,多数Java应用选择这种方式部署服务.本文 ...

  9. 在Docker容器中运行Spring Boot的jar包 jar外的配置文件无法生效

    Spring Boot加载配置文件,默认会从几个固定位置搜索一下看看有没有配置文件 ——application.properties或者bootstrap.properties(如果你使用了sprin ...

随机推荐

  1. ServletContext的作用

    一个项目只有一个ServletContext对象,一个tomcat有多个项目 作用:在多核Servlet中来获取这个唯一的对象,使用ta给多个Servlet传递数据. 在Tomcat启动时创建,在To ...

  2. JavaDailyReports10_20

    1 package varycode; 2 class Grandparent 3 { 4 public Grandparent() 5 { 6 7 System.out.println(" ...

  3. 每日一个linux命令5 -- rm

    rm命令.rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所有文件及子目录均删除.对于链接文件,只是删除了链接,原有文件均保持不变. rm是一个危险的命 ...

  4. elasticsearch基本概念和基本语法

    Elasticsearch是基于Json的分布式搜索和分析引擎,是利用倒排索引实现的全文索引. 优势: 横向可扩展性:增加服务器可直接配置在集群中 分片机制提供更好的分布性:分而治之的方式来提升处理效 ...

  5. 第12章 DOM操作

    目录 *1. 向DOM中注入HTML 1.1 将HTNL字符串转换成DOM 预处理HTML源字符串 包装HTML 1.2 将DOM元素插入到文档中 2. DOM的特性和属性 通过DOM方法和属性访问特 ...

  6. 使用javafx开发一款桌面个性化软件

    本来笔者只是打算开发一个显示在桌面的cpu和内存监控工具,没想到迭代了几次版本之后变成了桌面个性化工具了. 目前实现功能: cpu和内存的实时监控 开机自动启动 自定义logo 自定义主题颜色 鼠标拖 ...

  7. mac配置Android SDK

    下载地址:http://tools.android-studio.org/index.php/sdk 2.找到tools文件夹 选中android-sdk-macosx包下的tools文件夹,按com ...

  8. (十二)random模块

    大致有以下几个函数: print(random.random()) #0到1的浮点型 print(random.randint(1,6)) #1到6的整型 print(random.randrange ...

  9. 【Vue】Vue开发环境搭建

    Vue前置学习环境 文章目录 Vue前置学习环境 IDE Node.js 调试环境 工程环境 小结 IDE WebStorm 官网下载:https://www.jetbrains.com/websto ...

  10. 【Linux】实现端口转发的rinetd

    Linux下端口转发一般都使用iptables来实现,使用iptables可以很容易将TCP和UDP端口从防火墙转发到内部主机上.但是如果需要将流量从专用地址转发到不在您当前网络上的机器上,可尝试另一 ...