一、前言
Spring Boot 2.3.0的版本已经发布了。这个版本带来了很多重要更新,比如增加了对Docker的支持,包括使用buildpacks构建镜像,优雅停机(graceful shutdown)的支持,活动性(liveness)和就绪性(readiness)探针,另一个值得注意的更新是对Java 14支持并保持对Java 8和11的LTS版本的支持。
Buildpacks是Dockerfile的替代方案。Buildpacks自动检测在Docker容器中运行应用程序所需的软件。例如,它检测到应用程序中使用的Java版本。基于该版本,buildpacks将选择在buildpack中指定的JRE并构建一个Docker镜像。
二、如何构建镜像
当基于Spring Boot 2.3.0及以上版本创建项目后,同样可以使用Maven或Gradle构建工具创建Docker镜像,进入项目的根目录下执行
#maven$ mvn spring-boot:build-image#gradle$ gradle bootBuildImage
注意:构建时又涉及到外网翻墙的问题了,因为需要从https://gcr.io/v2/下载几个对应的镜像。
下面构建结果就是通过上述命令构建的docker镜像,默认名称为:docker.io/libray/${project.artifactId}:${project.version}
三、如何修改镜像名称
修改镜像名称根据不同的构建工具不同,Maven构建工具可以通过配置文件完成,gradle可以通过命令行参数完成。
Maven构建:
通过在构建插件中添加镜像名称的配置参数修改镜像名称。
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <image> <name>devops.com/${project.artifactId}:${project.version}</name> </image> </configuration></plugin>
Gradle构建:
通过在构建命令行里添加--imageName参数修改镜像名称。
$gradle bootBuildImage --imageName=devops.com/myspring-app-docker:v1.0
四、镜像大小的优化
我们都知道,Docker镜像是分层的,镜像内容改变的频繁度会影响镜像的大小。一般情况下,都是将经常改变的应用制品包添加的最顶层来减少镜像的大小。使用Spring Boot开发的应用程序一般都会达成Jar文件,这个jar文件里包含里经常改变的内容,比如代码。但是这个Jar文件也包含了一些变更少的文件,比如依赖包。因为Docker镜像每个版本之间的差异都是以diffs进行存储的,所有当这个Jar文件经常改变时,这个diffs会变得越来越大。Buildpacks通过根据更频繁的变更将应用程序划分为多个层来减少镜像的大小。
将镜像拆分为多个层的功能在Dockerfile也能实现。虽然Buildpacks提供了一些配置项,但Dockerfile可以完成控制生成的镜像。因此,开发人员有时会更倾向于使用Dockerfile而不是buildpack。选择使用Dockerfile时,最好也将镜像划分成多个层。相比Buildpacks,使用Dockerfile需要更多的工作量,但这个是一次性的。
首先配置spring-boot-maven-plugin以支持产生分层的Jar:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <layers> <enabled>true</enabled> </layers> </configuration> </plugin> </plugins></build>
这个配置可以确保将应用程序分为四个部分:dependencies、spring-boot-loader、snapshot-dependencies和application。
下面这个片段显示了一个多阶段的Dockerfile。第一步,使用特定的jarmode参数运行应用程序。这个就会将四个部分分别存储在其自己的目录中。在下一步中,将这四个目录分别复制到Docker镜像中,并制定启动入口。
FROM adoptopenjdk:14-jre-hotspot as builderWORKDIR applicationARG JAR_FILE=target/*.jarCOPY ${JAR_FILE} application.jarRUN java -Djarmode=layertools -jar application.jar extract FROM adoptopenjdk:14-jre-hotspotWORKDIR applicationCOPY --from=builder application/dependencies/ ./COPY --from=builder application/spring-boot-loader/ ./COPY --from=builder application/snapshot-dependencies/ ./COPY --from=builder application/application/ ./ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
开发人员可以使用Dockerfile构建Docker镜像:
$ docker build . --tag v1.0
五、总结
随着Docker、Kubernetes等容器技术的不断成熟,企业中越来越多的应用程序运行在云上。因此Spring Boot开发框架也在向云端发展,通过提供一些基础能力,比如内置构建docker镜像,来提高应用程序快速上云的速度,这个功能还是非常给力的。
本文分享自微信公众号 - DevOps探索者(devopsagile)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。