Spring Boot 2.3.0 之后支持通过 buildpacks 插件构建 Docker 镜像,原理和执行过程与 Jib 类似,支持 Spring Boot 项目的分层构建,当代码改动后,只需更新代码部分,可以减少构建后 push 和 pull 镜像的时间,减少镜像存储的成本
底层是通过 Buildpacks 构建,Buildpacks是 Dockerfile 的一个替代方案。Buildpacks 能够自动探测运行 Docker 容器中的应用时所需要的软件,例如,它会探测应用中所使用的 Java 版本,基于该版本,buildpack 会选择所指定的 JRE 并构建 Docker 镜像
优点
- Spring Boot 编译插件集成,不需要额外的配置
- JVM 参数计算,支持通过线程数量,类数量等,动态的计算适合的 JVM 参数
- 会在构建过程中加入 OOM Killer,当 OOM 时自动杀死应用
弊端
- 在镜像中指定了内存参数,CPU数量等
- 不能灵活添加自定义文件,只能添加应用中的文件为单独的层
- 构建镜像、运行镜像与 Buildpacks 强绑定,需要 Buildpacks 的参数才可以成功构建,如果要自定义信息,同样需要在基础镜像中加入 Buildpacks 的配置
- 不支持直接使用历史版本镜像的分层,当tag改变时会完全重新构建
- builder 和 runImage 中的内容是动态下载的,访问 GitHub 可能失败,也不安全
使用
- 更新 SpringBoot 版本为 2.3.2.RELEASE
- 启用分层
bootJar {
layered()
}
- 执行构建
会根据应用名称构建出一个镜像
gradle buildImage
- 指定基础镜像、默认镜像以及镜像名称
bootBuildImage {
builder = "docker.io/hellowoodes/buildpacks-builer:base-platform-api-0.3"
runImage = "docker.io/hellowoodes/buildpacks-run:base-cnb"
imageName = "docker.io/hellowoodes/${artifactId}:${version}"
environment = [
"TZ" : "Asia/Shanghai",
"JAVA_OPTS": "-Djava.security.egd=file:/dev/./urandom"
]
}
自定义分层
目前只支持两种 layer,分别是 application 和 dependencies
- application 只支持将项目目录下的文件打包到镜像中,格式为文件目录
- dependencies 支持依赖,格式为
groupId:artifactId:version
共有4层,可以通过java -Djarmode=layertools -jar image-0.0.1-SNAPSHOT.jar list
查看:
- dependencies 正式版的依赖
- spring-boot-loader SpringBoot 启动文件
- snapshot-dependencies 快照版的依赖
- application 应用文件,即编译后的类,resource下面的文件
添加新的 layer
如需要将静态文件单独分为一个层,可以在 application 加入新的层的逻辑
需要注意的是,这个层的 layerOrder 得放到 application 层的前面,否则 application 层包含了所有的文件,这个层就找不到;因为文件的添加逻辑是先添加 include 中指定的,下一层如果没有指定则添加剩余的
暂时不支持将自定义的外部文件加入层中,需要自定义 buildpacks 才可以
bootJar {
layered {
application {
intoLayer("spring-boot-loader") {
include "org/springframework/boot/loader/**"
}
// 自定义 static 层,存放静态文件
intoLayer("static") {
include "static/**"
}
intoLayer("application")
}
dependencies {
intoLayer("snapshot-dependencies") {
include "*:*:*SNAPSHOT"
}
intoLayer("dependencies")
}
layerOrder = ["dependencies", "spring-boot-loader", "snapshot-dependencies", "static", "application"]
}
}
注意事项
- 默认的用户是 cnb
- 启动方式不同,是通过启动JarLauncher 来启动应用
- 自定义 Builder 镜像和 Stack 可以参考 buildpacks/samples
- 构建镜像和基础运行镜像默认从 gcr.io 下载