SpringBoot-2-3-x分层构建Docker镜像实践 下

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: SpringBoot-2-3-x分层构建Docker镜像实践

三、创建测试的 SpringBoot 应用

创建测试的 SpringBoot 项目,并且在 pom.xml 中开启镜像分层。

1、Maven 中引入相关依赖和插件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.6.RELEASE</version>
    </parent>
    <artifactId>springboot-dockerfile-layer</artifactId>
    <packaging>jar</packaging>
    <name>springboot-dockerfile-layer</name>
    <description>springboot build layer example</description>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <layers>
                        <enabled>true</enabled>
                    </layers>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2、创建测试的 Controller 类

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
    @GetMapping("/hello")
    public String hello() {
        return "hello world!";
    }
}

3、创建 SpringBoot 启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

四、创建两种构建镜像的 Dockerfile 脚本

为了方便体现出 SpringBoot 2.3.x 支持的分层构建 Dockerfile 的优点,这里在 Java 源码文件夹下,创建普通与分层两种构建镜像的 Dockerfile 脚本,后续会使用这两种脚本构建 Docker 镜像进行构建速度、推送速度、拉取速度的对比。

1、普通镜像构建脚本文件 dockerfile-number

FROM openjdk:8u275
VOLUME /tmp
ADD target/*.jar app.jar
RUN sh -c 'touch /app.jar'
ENV TZ="Asia/Shanghai"
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV JVM_OPTS="-XX:MaxRAMPercentage=80.0"
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS" ]

说明:

  • TZ: 时区设置,而 Asia/Shanghai 表示使用中国上海时区。
  • JVM_OPTS: 指定 JVM 启动时候的参数,-XX:MaxRAMPercentage 参数和 -Xmx 类似,都是限制堆内存大小,只不过 -Xmx 需要手动指定限制大小,而 -XX:MaxRAMPercentage 则是根据虚拟机可用内存百分比限制。
  • JAVA_OPTS: 在镜像启动时指定的自定义 Java 参数,例如 -Dspring.application.name=xxx。

2、分层镜像构建脚本文件 dockerfile-layer

FROM openjdk:8u275 as builder
WORKDIR application
COPY target/*.jar application.jar
RUN java -Djarmode=layertools -jar application.jar extract
FROM openjdk:8u275
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/application/ ./
ENV TZ="Asia/Shanghai"
ENV JVM_OPTS="-XX:MaxRAMPercentage=80.0"
ENV JAVA_OPTS=""
ENTRYPOINT ["sh","-c","java $JVM_OPTS $JAVA_OPTS org.springframework.boot.loader.JarLauncher"]

说明:

  • TZ: 时区设置,而 Asia/Shanghai 表示使用中国上海时区。
  • -Djarmode=layertools: 指定构建 Jar 的模式。
  • extract: 从 Jar 包中提取构建镜像所需的内容。
  • -from=builder 多级镜像构建中,从上一级镜像复制文件到当前镜像中。

五、使用两种 Dockerfile 构建项目镜像

1、在服务器一构建普通 Docker 镜像

(1)、第一次构建

## 执行 Maven 命令,将源代码构建 Jar 包
$ mvn clean install
## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-normal:0.0.1 .

Docker 镜像构建总共花费 24.98s 时间。

(2)、第二次构建(修改依赖 pom.xml 文件)

## 修改 pom.xml 里面的依赖,随意添加一个新的依赖包,然后再次将源代码构建 Jar 包
$ mvn clean install
## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-normal:0.0.2 .

Docker 镜像构建总共花费 1.27s 时间。

(3)、第三次构建(修改代码内容)

## 修改源代码任意内容后,然后再次将源代码构建 Jar 包
$ mvn clean install
## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-normal:0.0.3 .

Docker 镜像构建总共花费 1.32s 时间。

2、在服务器二构建分层 Docker 镜像

(1)、第一次构建

## 执行 Maven 命令,将源代码构建 Jar 包
$ mvn clean install
## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-layer:0.0.1 .

Docker 镜像构建总共花费 26.12s 时间。

(2)、第二次构建(修改依赖 pom.xml 文件)

## 修改 pom.xml 里面的依赖,随意添加一个新的依赖包,然后再次将源代码构建 Jar 包
$ mvn clean install
## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-layer:0.0.2 .

Docker 镜像构建总共花费 3.44s 时间。

(3)、第三次构建(修改代码内容)

## 修改源代码任意内容后,然后再次将源代码构建 Jar 包
$ mvn clean install
## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-layer:0.0.3 .

Docker 镜像构建总共花费 2.82s 时间。

六、镜像推送到镜像仓库测试

1、推送镜像到镜像仓库测试

服务器一推送普通镜像到镜像仓库1:

## 第一次推送镜像
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.1
real    0m35.215s
## 第二次推送镜像
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.2
real    0m14.051s
## 第三次推送镜像
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.3
real    0m14.183s

服务器二推送分层镜像到镜像仓库2:

## 第一次推送镜像
$ time docker push hub.mydlq.club/library/springboot-layer:0.0.1
real    0m34.121s
## 第二次推送镜像
$ time docker push hub.mydlq.club/library/springboot-layer:0.0.2
real    0m13.605s
## 第三次推送镜像
$ time docker push hub.mydlq.club/library/springboot-layer:0.0.3
real    0m4.805s

2、镜像仓库拉取镜像测试

服务器一推送从镜像仓库1拉取镜像:

## 清理全部镜像
$ docker rm --force $(docker images -qa)
## 拉取镜像 springboot-normal:0.0.1
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.1
real    0m35.395s
## 拉取镜像 springboot-normal:0.0.2
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.2
real    0m6.501s
## 拉取镜像 springboot-normal:0.0.3
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.3
real    0m6.993s

服务器二推送从镜像仓库2拉取镜像:

## 清理全部镜像
$ docker rm --force $(docker images -qa)
## 拉取镜像 springboot-layer:0.0.1
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.1
real    0m30.615s
## 拉取镜像 springboot-layer:0.0.2
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.2
real    0m4.811s
## 拉取镜像 springboot-layer:0.0.3
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.3
real    0m1.293s

七、镜像构建、推送、拉取时间汇总

1、不使用分层构建镜像

如下图:

2、使用分层构建镜像

如下图:

3、总结

上面进行了使用 SpringBoot2.3.x 分层的方式构建镜像与普通的方式构建镜像,在镜像的构建、推送、拉取方面进行了执行速度对比,总结出如下结论:

  • 镜像构建: 在构建上,使用分层 Jar 构建镜像可能比普通方式构建镜像更繁琐,所以也更耗时,故而在构建上分层 Jar 构建镜像没有太多优势。
  • 镜像推送: 在推送上,如果每次构建镜像都只是修改构建镜像项目的源码,使用分层 Jar 构建镜像,可以大大加快镜像推送速度。如果是修改构建镜像项目中的依赖包,则和普通构建一样速度很慢。
相关实践学习
通过ACR快速部署网站应用
本次实验任务是在云上基于ECS部署Docker环境,制作网站镜像并上传至ACR镜像仓库,通过容器镜像运行网站应用,网站运行在Docker容器中、网站业务数据存储在Mariadb数据库中、网站文件数据存储在服务器ECS云盘中,通过公网地址进行访问。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
1月前
|
Kubernetes Docker Python
Docker 与 Kubernetes 容器化部署核心技术及企业级应用实践全方案解析
本文详解Docker与Kubernetes容器化技术,涵盖概念原理、环境搭建、镜像构建、应用部署及监控扩展,助你掌握企业级容器化方案,提升应用开发与运维效率。
448 108
|
11天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1230 5
|
21天前
|
缓存 安全 Linux
优化Docker镜像大小的多阶段构建实践
优化Docker镜像大小的多阶段构建实践
186 99
|
5月前
|
Docker 容器 Perl
云效flow构建docker镜像更换apt源为阿里镜像源
在 Dockerfile 中添加命令以更换 Debian 源为阿里云镜像,加速容器内软件包下载。核心命令通过 `sed` 实现源地址替换,并更新 apt 软件源。其中 `cat` 命令用于验证替换是否成功,实际使用中可删除该行。
1193 32
|
4月前
|
缓存 Shell 网络安全
将应用程序打包成Docker镜像时可能遇到哪些问题?
将应用程序打包成Docker镜像时可能遇到哪些问题?
451 77
|
4月前
|
安全 Java API
Spring Boot 功能模块全解析:构建现代Java应用的技术图谱
Spring Boot不是一个单一的工具,而是一个由众多功能模块组成的生态系统。这些模块可以根据应用需求灵活组合,构建从简单的REST API到复杂的微服务系统,再到现代的AI驱动应用。
|
4月前
|
Shell 应用服务中间件 nginx
docker 镜像的部分常用命令
docker镜像常用命令
162 16
|
4月前
|
关系型数据库 MySQL Docker