Spring Boot无需Dockerfile创建Docker镜像三种方法    

     随着技术的发展,服务于终端用户请求的应用程序的部署方式也发生了变化。传统上,你需要用一台机器来部署应用程序,然后决定机器的配置,以保证应用程序的运行。容器的引入,即把整个软件堆栈打包成一个单一的实体并进行运输,解决了开发人员面临的最大问题之一。"它能在我的机器上运行":) 因此,今天我们将探讨为 Spring Boot 应用程序构建 docker 镜像的三种机制:

  • Spring Boot (spring-boot-maven-plugin) 插件
  • Fabric8 Maven 插件
  • Google JIB maven 插件

创建应用程序 让我们访问 https://start.spring.io,创建一个仅依赖于 Spring-web 的应用程序。

让我们添加一个简单的控制器来接受一些请求:

@RestController
@SpringBootApplication
public class ServiceDockerImageBuildApplication {

   public static void main(String[] args) {
       SpringApplication.run(ServiceDockerImageBuildApplication.class, args);
    }

   @GetMapping("/")
    public ResponseEntity get(){
       return ResponseEntity.ok("All Ok");
    }
}

当我们运行它并打开 "http://localhost:8080 "时,会得到 "一切正常 "的回应。

这样,我们就可以使用开箱即用的构建插件来构建我们的 docker 镜像了。

一. 使用 Spring Boot 构建插件构建 Docker 镜像

image

Spring Boot 的构建插件提供了一种使用 BuildPacks 概念创建 docker 镜像的方法。Build Packs 提供了一种定义应用程序构建方式的方法。它会检测应用程序的类型并构建它,以便你能在特定平台上运行或独立于平台运行。现在,Spring Boot 的构建插件使用 BuildPack 构建镜像,它会自动检测到这是一个 Spring Boot 应用程序,并为你构建相关镜像。你唯一需要做的就是使用 maven 在 Spring Boot 应用程序上调用 image-build goal

mvn spring-boot:build-image

是一个 Maven 命令,用于使用 spring-boot-maven-plugin 插件将 Spring Boot 应用程序打包成可执行的镜像文件。这个命令的作用是自动生成跨全平台的镜像服务,无需再自己手动编写 Dockerfile 文件。这个插件基于 buildpacks 这个规范,有一系列的生命周期,和 Maven 差不多。正常来说,如果是在互联网环境下,它会自动检测项目的语言、运行时环境(如 Python、Node.js、JVM)等,并自动从网络下载对应的依赖,一键即可生成镜像,非常方便。

image

Buildpacks 是一个程序,可以将源代码转换成容器镜像,并在任意云环境中运行。通常,buildpack 封装了单一语言的生态工具链,适用于 Java、Ruby、Go、NodeJs、Python 等。相比 Maven,Buildpacks 有以下优势:

1. 语言和框架支持:Buildpacks 支持多种语言和框架,可以根据应用程序的需要自动选择适当的构建工具和运行时环境。而 Maven 主要针对 Java 应用程序,对于其他语言和框架的支持有限。
2. 自动化构建:Buildpacks 可以自动检测应用程序的语言、框架和依赖,并根据需要提供所需的运行时环境和依赖项。这使得我们可以专注于应用程序的开发,而不必手动配置和管理构建过程中的各种环境和依赖。相比之下,Maven 需要手动配置和管理依赖和构建过程。
3. 集成开发环境支持:Buildpacks 能够与集成开发环境无缝集成,提供一致的构建体验。一些 IDE(如 VS Code 和 IntelliJ IDEA)已经支持使用 Buildpacks 来构建和调试应用程序,简化了本地开发和测试的过程。这使得开发人员可以在熟悉的开发环境中轻松地使用 Buildpacks 进行应用程序开发和调试。
4. 自动化构建和持续集成/持续交付:Buildpacks 可以与自动化构建和持续集成/持续交付(CI/CD)流程集成,实现自动化的应用程序构建和部署。当代码发生变化或触发 CI/CD 流水线时,Buildpacks 可以自动重新构建应用程序,并生成新的可部署的镜像,简化了部署流程,并确保应用程序的构建和部署过程始终与代码同步。相比之下,Maven 主要用于手动构建应用程序,而不是自动化构建和持续集成/持续交付。

这将从 BuildPacks 提取基础生成器镜像,以检测应用程序的类型并为应用程序选择构建包。这个过程会连接GitHub与hub.docker.com下载依赖 然后,它会使用选定的构建包构建最终镜像。

下面的日志显示了构建应用程序所需的构建包:

===> DETECTING
[INFO]     [creator]     6 of 24 buildpacks participating
[INFO]     [creator]     paketo-buildpacks/ca-certificates   3.2.4
[INFO]     [creator]     paketo-buildpacks/bellsoft-liberica 9.3.7
[INFO]     [creator]     paketo-buildpacks/syft              1.12.0
[INFO]     [creator]     paketo-buildpacks/executable-jar    6.2.4
[INFO]     [creator]     paketo-buildpacks/dist-zip          5.2.4
[INFO]     [creator]     paketo-buildpacks/spring-boot       5.12.0
...
...
[INFO] Successfully built image 'docker.io/library/service-docker-image-build:0.0.1-SNAPSHOT'

您可以使用参数指定最终图像的名称,如下所示

mvn spring-boot:build-image \
-Dspring-boot.build-image.imageName=my-spring-boot-image

或者在配置中指定,如下所示

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
       <imageName>my-spring-boot-image</imageName>
    </configuration>
</plugin>

现在,我看到这里有几个自定义级别。如果你想真正自定义图像的构建过程,你必须创建自己的构建器图像来定义你的构建过程。让我们看看另一种构建镜像的方法:

二. 使用 Fabric8 Maven 插件构建 Docker 镜像

image

Fabric8 是容器化世界中最受欢迎的 API 提供商之一。

Fabric8 Maven 插件是一个用于简化在 Java 应用程序中部署和管理 Kubernetes 和 OpenShift 资源的 Maven 插件。它的主要功能包括:

1. 构建 Docker 镜像:Fabric8 Maven 插件可以自动构建应用程序的 Docker 镜像,并将其推送到 Docker 注册表中。
2. 创建 Kubernetes 和 OpenShift 资源:通过使用 Maven 的项目对象模型(POM),Fabric8 Maven 插件可以自动创建和管理 Kubernetes 和 OpenShift 资源,例如部署、服务、配置文件等。
3. 集成测试:插件支持集成测试,可以在构建过程中运行测试用例,并在部署到 Kubernetes 或 OpenShift 时进行验证。
4. 配置管理:通过使用 POM 文件,用户可以轻松地管理和修改应用程序的配置信息,以便在部署到生产环境时进行微调。

Fabric8 Maven 插件的优势包括:

1. 简化部署过程:通过自动化 Docker 镜像构建、Kubernetes 和 OpenShift 资源创建以及集成测试,该插件简化了 Java 应用程序的部署过程。
2. 提高开发效率:通过将部署和管理资源的过程集成到 Maven 构建过程中,开发人员可以更快速地迭代应用程序并部署到生产环境中。
3. 可扩展性:插件支持各种 Kubernetes 和 OpenShift 的版本和配置,可以根据项目需求进行定制和扩展。
4. 集成测试:该插件提供了集成测试功能,可以在部署前验证应用程序的功能和性能。
5. 简化配置管理:通过使用 POM 文件进行配置管理,可以轻松地修改应用程序的配置信息,并确保在部署时的一致性。

他们有与 Kubernetes 集群通信的客户端 API,今天我们将使用他们的 maven 插件来构建 docker 镜像。

<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.40.1</version>
<configuration>
    <images>
       <image>
          <name>${project.name}:${project.version}</name>
          <build>
             <from>openjdk:17</from>
             <assembly>
                <name>build</name>
                <descriptorRef>artifact</descriptorRef>
             </assembly>
             <ports>
                <port>8080</port>
             </ports>
             <cmd>java -jar build/${project.name}-${project.version}.jar</cmd>
          </build>
       </image>
    </images>
</configuration>
    <executions>
    <execution>
       <id>build-image</id>
       <phase>verify</phase>
       <goals>
          <goal>build</goal>
       </goals>
    </execution>
    </executions>
</plugin>

配置部分非常简单。让我们看看 <build> 部分的一些重要配置。在这里,我们使用 <from> 标记指定基本镜像,然后在 <assembly> 部分指定镜像的组装方式。在装配部分,我们指定了 <descriptorRef>,其值为 artifact,以表示我们只想复制已构建的构件,而 <name> 标记则指定了目标图像中将其复制到的位置。desciptorRef 有多种选项,比如是否要将依赖项与 artifact 一并复制或仅复制依赖项等,你可以在这里找到。由于我们构建的是一个单一的胖 jar,因此只需复制工件即可。

最后,我们指定 <cmd> 来运行已复制的 jar 文件。运行 maven build 命令后,镜像就构建完成了。

我检查了镜像层,发现工件作为最后一层被复制,如下图所示。

image-layer-fabric8

你总是可以创建一个分层的 docker 镜像,方法是在程序集标签中指定你想创建的层以及需要复制到这些层中的内容。你可以在这个链接中找到更多自定义选项。现在,我们只需使用 docker run -p 8080:8080 service-docker-image-build:0.0.1-SNAPSHOT 运行 docker 文件即可。

三. 使用谷歌的 JIB 插件构建 Docker image

image

让我们来看看谷歌的 JIB 插件。它是由谷歌提供和维护的工具之一,提供了相当详细的自定义级别

Jib Maven 插件的优势主要体现在以下几个方面:

1. **无需 Dockerfile**:传统的 Dockerfile 构建方式需要编写和维护 Dockerfile,而 Jib Maven 插件则无需编写 Dockerfile,简化了构建过程。
2. **快速构建**:Jib Maven 插件可以在本地构建镜像,无需在 Docker 守护进程中运行,这大大加快了构建速度。
3. **灵活性**:Jib Maven 插件支持多种镜像仓库,包括 Docker Hub、Google Container Registry 等,同时也支持不同的镜像标签和镜像名称。
4. **安全性**:Jib Maven 插件支持自动签名和验证镜像,确保镜像的安全性。
5. **集成测试**:Jib Maven 插件可以集成测试,在构建过程中运行测试用例,并在部署到 Kubernetes 或 OpenShift 时进行验证。
6. **简化配置管理**:通过使用 POM 文件进行配置管理,可以轻松地修改应用程序的配置信息,并确保在部署时的一致性。


<build>
    <plugins>
       <plugin>
          <groupId>com.google.cloud.tools</groupId>
          <artifactId>jib-maven-plugin</artifactId>
          <version>3.2.1</version>
          <configuration>
             <from>
                <image>openjdk:17</image>
             </from>
             <to>
                <image>jib-build-${project.name}:${project.version}</image>
             </to>
          </configuration>
          <executions>
             <execution>
                <phase>verify</phase>
                <goals>
                   <goal>dockerBuild</goal>
                </goals>
             </execution>
          </executions>
       </plugin>
    </plugins>
</build>

在这里,我们在 <from> 标签中指定了我们想要的基本镜像,并在 <to> 标签中指定了我们想要的最终镜像名称。现在,我在 <execution> 部分使用了 dockerBuild 目标,这样,docker 镜像就会被构建到本地的 docker 守护进程中。如果使用了构建目标,JIB 插件就会构建 docker 镜像,并将其推送到相应的版本库。它支持所有主要的版本库,如 docker.io、AWS ECR、Google GCR、Azure ACR 等。为此,你可以设置推送镜像的验证机制。你可以在此阅读相关内容。

让我们来看看创建的镜像层:

35b87957340d28888713fd695fecce2306fd3c4ed2f4210e2a7379895522bee1

35b87957340d28888713fd695fecce2306fd3c4ed2f4210e2a7379895522bee1

如上图所示,层的创建过程如下:

第 1 层:包含所有依赖关系。

第 2 层:包含应用程序资源。

第 3 层:包含应用程序类。

第 4 层:包含 jib-classpath-file 文件(其中包含类路径信息)和 jib-main-class-file 文件(其中包含将执行的完全合格的主类名称)。 您可以通过此链接中的选项自定义镜像的创建方式。

四. 总结

     今天我们看到了如何构建 docker 镜像,而无需手动编写 docker 文件。我们只需要在你的 maven 构建配置文件中加入一个插件,然后构建镜像并推送到它的仓库。Jib Maven、spring-boot-maven-plugin和Fabric8 Maven都是Maven插件,用于简化和自动化Java应用程序的构建、部署和管理过程。它们各自具有一些优势,但具体哪个更有优势取决于具体的需求和使用场景。

     Jib Maven插件主要用于构建Docker镜像,它无需编写Dockerfile,可以直接将Java应用程序打包成Docker镜像,并推送到容器仓库中。Jib Maven插件的优势在于简化了Docker镜像的构建过程,提高了构建效率,并提供了对多种镜像仓库的支持。

     Spring-boot-maven-plugin是Spring Boot官方提供的Maven插件,用于支持Spring Boot应用程序的构建和运行。它提供了丰富的功能,包括将Spring Boot应用程序打包为可执行的jar或war文件,并在Maven的生命周期中提供了各种目标(goals),如运行、重新打包、启动和停止应用程序等。spring-boot-maven-plugin的优势在于与Spring Boot框架紧密集成,提供了全面的支持和丰富的功能。

     Fabric8 Maven插件主要用于Java应用程序在Kubernetes和OpenShift上的部署和管理。它提供了构建Docker镜像、创建Kubernetes和OpenShift资源、集成测试以及配置管理等功能。Fabric8 Maven插件的优势在于简化了Java应用程序在云原生环境中的部署和管理过程,提供了与Kubernetes和OpenShift的紧密集成,并支持各种配置和定制。

Jib Maven、spring-boot-maven-plugin和Fabric8 Maven都具有各自的优势,具体选择哪个插件取决于具体的需求和使用场景。如果主要关注Docker镜像的构建和推送,可以考虑使用Jib Maven;如果需要全面的Spring Boot应用程序支持,可以选择spring-boot-maven-plugin;如果需要在Kubernetes或OpenShift上部署和管理Java应用程序,可以考虑使用Fabric8 Maven插件。我个人比较喜欢的是 jib 插件,因为它可以定制,而且开箱即可使用 docker 镜像层。



今天先到这儿,希望对云原生,技术领导力, 企业管理,系统架构设计与评估,团队管理, 项目管理, 产品管管,团队建设 有参考作用 , 您可能感兴趣的文章:
领导人怎样带领好团队
构建创业公司突击小团队
国际化环境下系统架构演化
微服务架构设计
视频直播平台的系统架构演化
微服务与Docker介绍
Docker与CI持续集成/CD
互联网电商购物车架构演变案例
互联网业务场景下消息队列架构
互联网高效研发团队管理演进之一
消息系统架构设计演进
互联网电商搜索架构演化之一
企业信息化与软件工程的迷思
企业项目化管理介绍
软件项目成功之要素
人际沟通风格介绍一
精益IT组织与分享式领导
学习型组织与企业
企业创新文化与等级观念
组织目标与个人目标
初创公司人才招聘与管理
人才公司环境与企业文化
企业文化、团队文化与知识共享
高效能的团队建设
项目管理沟通计划
构建高效的研发与自动化运维
某大型电商云平台实践
互联网数据库架构设计思路
IT基础架构规划方案一(网络系统规划)
餐饮行业解决方案之客户分析流程
餐饮行业解决方案之采购战略制定与实施流程
餐饮行业解决方案之业务设计流程
供应链需求调研CheckList
企业应用之性能实时度量系统演变

如有想了解更多软件设计与架构, 系统IT,企业信息化, 团队管理 资讯,请关注我的微信订阅号:

MegadotnetMicroMsg_thumb1_thumb1_thu[2]

作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 该文章也同时发布在我的独立博客中-Petter Liu Blog。

posted on 2024-02-03 16:47  PetterLiu  阅读(110)  评论(0编辑  收藏  举报