简介很久以前我们是如何创建SpringBootdocker镜像的?最常见的方式是将Springboot应用打包成一个fatjar,然后写一个docker文件,将fatjar打成docker镜像运行。今天我们就来体验一下SpringBoot2.3.3带来的快速创建docker镜像的功能。传统方法及其缺点现在我们创建一个非常简单的SpringBoot程序:@SpringBootApplication@RestControllerpublicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.run(Application.class,args);}@GetMapping("/getInfo")publicStringgetInfo(){return"www.flydean.com";}}复制代码默认情况下,我们构建的是一个fatjar:springboot-with-docker-0.0.1-SNAPSHOT.jar我们解压看看里面的内容:fatSpringBoot的jar分为三个部分。第一部分是BOOT-INF。里面的class目录就是我们自己写的class文件。lib目录存放项目依赖的其他jar包。第二部分是META-INF,定义了jar包的属性信息。第三部分是SpringBoot的类加载器。fatjar包的启动是通过SpringBoot的jarLauncher创建LaunchedURLClassLoader,通过它加载lib下的jar包,最后以新的线程启动应用程序的Main函数。关于SpringBoot的启动这里就不多说了。来看看,如果要用这个fatjar创建docker镜像怎么写:FROMopenjdk:8-jdk-alpineEXPOSE8080ARGJAR_FILE=target/springboot-with-docker-0.0.1-SNAPSHOT.jarADD${JAR_FILE}app.jarENTRYPOINT["java","-jar","/app.jar"]这样复制代码有两个问题。第一个问题:我们使用的是farjar,在使用farjar的过程中会存在一定的性能问题,肯定比解压后的性能要低,尤其是运行在容器环境下,可能会比较突出。第二个问题:我们知道docker的镜像是分层构建的。逐层构建的好处是可以减少镜像构建的时间,可以复用上一层。但是如果使用fatjar包,即使我们只修改自己的代码,也会导致整个fatjar重新更新,影响docker镜像的构建速度。除了以上两个问题,传统的使用Buildpacks的方法是需要自己构建docker文件。有没有办法一键构建docker镜像?答案是肯定的。SpringBoot在2.3.0之后引入了CloudNativebuildpacks。通过这个工具,我们可以非常非常方便的创建docker镜像。在Maven和Gradle中,SpringBoot引入了一个新的阶段:spring-boot:build-image我们可以直接运行:mvnspring-boot:build-image让代码运行起来,不幸的是,你可能会遇到如下错误:[ERROR]Failed执行goalorg.springframework.boot:spring-boot-maven-plugin:2.3.3.RELEASE:build-image(default-cli)onprojectspringboot-with-docker:Executiondefault-cliofgoalorg.springframework.boot:spring-boot-maven-plugin:2.3.3.RELEASE:build-imagefailed:DockerAPI调用'localhost/v1.24/images/create?fromImage=gcr.io%2Fpaketo-buildpacks%2Fbuilder%3Abase-platform-api-0.3'failedwithstatuscode500"InternalServerError"和消息"Gethttps://gcr.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)"->[Help1]复制代码这是因为我们无法从gcr.io中提取图像!没关系,如果你知道如何正确上网,那我估计你找到了代理。将您的代理配置到Docker的代理项中。我使用Docker桌面。以下是我的配置:重新运行mvnspring-boot:build-image等待执行结果:[INFO]---spring-boot-maven-plugin:2.3.3.RELEASE:build-image(default-cli)@springboot-with-docker---[INFO]Buildingimage'docker.io/library/springboot-with-docker:0.0.1-SNAPSHOT'[INFO][INFO]>Pullingbuilderimage'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3'0%[INFO]>Pullingbuilderimage'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3'0%[INFO]>Pullingbuilderimage'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3'0%[INFO]>Pullingbuilderimage'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3'0%[INFO]>Pullingbuilderimage'gcr。io/paketo-buildpacks/builder:base-platform-api-0.3'0%[INFO]>Pullingbuilderimage'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3'0%复制代码即可看到我们真的需要从gcr.io中提取图像。分层Jars如果您不想使用CloudNativeBuildpacks,您仍然想使用传统的Dockerfile。没关系,SpringBoot为我们提供了独特的分层jar包体系。如何打开它?我们需要在POM文件中添加如下配置:
