打包 OCI 镜像
该插件可以使用 OCI 镜像 规范和 云原生构建包 (CNB) 从 jar 或 war 文件创建 OCI 镜像。可以使用 build-image
目标在命令行上构建镜像。这确保了在创建镜像之前已运行包生命周期。
出于安全原因,镜像构建和运行为非 root 用户。有关更多详细信息,请参阅 CNB 规范。 |
最简单的入门方法是在项目上调用 mvn spring-boot:build-image
。可以自动化在每次调用 package
阶段时创建镜像,如下例所示。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-image-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
将目标绑定到包生命周期时,请使用 build-image-no-fork 。此目标类似于 build-image ,但不会分叉生命周期以确保 package 已运行。在本节的其余部分,build-image 用于指代 build-image 或 build-image-no-fork 目标。 |
虽然构建包从 可执行归档文件 运行,但无需首先执行 repackage 目标,因为如果需要,可执行归档文件会自动创建。当 build-image 重新打包应用程序时,它会应用与 repackage 目标相同的设置,即可以使用其中一个排除选项排除依赖项。默认情况下会自动排除 spring-boot-devtools 和 spring-boot-docker-compose 模块(可以使用 excludeDevtools 和 excludeDockerCompose 属性控制此行为)。 |
Docker 守护进程
build-image
目标需要访问 Docker 守护进程。该目标将检查本地 Docker CLI 配置文件 以确定当前 上下文,并使用上下文连接信息与 Docker 守护进程通信。如果无法确定当前上下文或上下文没有连接信息,则目标将使用默认本地连接。这在所有受支持的平台上都可以与 Docker Engine 一起使用,无需配置。
可以通过设置环境变量来配置build-image
目标,以使用替代的本地或远程连接。下表显示了环境变量及其值。
环境变量 | 描述 |
---|---|
DOCKER_CONFIG |
Docker CLI 配置文件的位置,用于确定当前上下文(默认为 |
DOCKER_CONTEXT |
应使用哪个上下文从Docker CLI配置文件中检索主机信息(覆盖 |
DOCKER_HOST |
包含Docker守护进程的主机和端口的URL - 例如 |
DOCKER_TLS_VERIFY |
设置为 |
DOCKER_CERT_PATH |
HTTPS证书和密钥文件路径(如果 |
Docker守护进程连接信息也可以使用插件配置中的docker
参数提供。下表总结了可用的参数。
参数 | 描述 |
---|---|
|
|
|
包含Docker守护进程的主机和端口的URL - 例如 |
|
设置为 |
|
HTTPS证书和密钥文件路径(如果 |
|
当设置为 |
更多详细信息,请参阅示例。
Docker注册表
如果builder
或runImage
参数指定的Docker镜像存储在需要身份验证的私有Docker镜像注册表中,则可以使用docker.builderRegistry
参数提供身份验证凭据。
如果要将生成的Docker镜像发布到Docker镜像注册表,则可以使用docker.publishRegistry
参数提供身份验证凭据。
提供了用于用户身份验证或身份令牌身份验证的参数。请参阅用于存储镜像的Docker注册表的文档,以获取有关支持的身份验证方法的更多信息。
下表总结了docker.builderRegistry
和docker.publishRegistry
可用的参数。
参数 | 描述 |
---|---|
|
Docker镜像注册表用户的用户名。用户身份验证需要。 |
|
Docker镜像注册表用户的密码。用户身份验证需要。 |
|
Docker镜像注册表的地址。用户身份验证可选。 |
|
Docker镜像注册表用户的电子邮件地址。用户身份验证可选。 |
|
Docker镜像注册表用户的身份令牌。令牌身份验证需要。 |
更多详细信息,请参阅示例。
镜像自定义
image
参数允许配置构建器以及它应该如何操作项目。下表总结了可用的参数及其默认值。
参数 / (用户属性) | 描述 | 默认值 |
---|---|---|
|
要使用的构建器镜像的名称。 |
|
|
要使用的运行镜像的名称。 |
没有默认值,表示应使用构建器元数据中指定的运行镜像。 |
|
生成的镜像的镜像名称。 |
|
|
用于确定何时从注册表中拉取构建器和运行镜像的策略。可接受的值为 |
|
|
应传递给构建器的环境变量。 |
|
|
构建器在构建镜像时应使用的构建包。仅使用指定的构建包,覆盖构建器中包含的默认构建包。构建包引用必须采用以下格式之一
|
无,表示构建器应使用其中包含的构建包。 |
|
在构建镜像时应挂载到构建器容器的卷挂载。在创建构建器容器时,这些绑定将被未解析且未验证地传递给Docker。绑定必须采用以下格式之一
其中
|
|
|
构建器容器将配置为使用的网络驱动程序。提供的值将在创建构建器容器时未经验证地传递给Docker。 |
|
|
是否在构建前清除缓存。 |
|
|
启用构建器操作的详细日志记录。 |
|
|
是否将生成的镜像发布到Docker注册表。 |
|
|
要应用于生成的镜像的一个或多个其他标签。提供给 |
|
|
构建器和构建包将在镜像构建期间用于存储文件的临时工作区。该值可以是命名卷或绑定挂载位置。 |
Docker守护进程中的命名卷,其名称派生自镜像名称。 |
|
包含构建包创建并由镜像构建过程使用的层的缓存。该值可以是命名卷或绑定挂载位置。 |
Docker守护进程中的命名卷,其名称派生自镜像名称。 |
|
包含构建包创建并由镜像启动过程使用的层的缓存。该值可以是命名卷或绑定挂载位置。 |
Docker守护进程中的命名卷,其名称派生自镜像名称。 |
|
将用于设置生成的镜像元数据中 |
一个固定日期,用于启用构建可重复性。 |
|
应用程序内容将上传到构建器镜像中的目录的路径。应用程序内容也将位于生成的镜像中的此位置。 |
|
|
将应用于构建器容器的安全选项,以字符串值数组的形式提供 |
在Linux和macOS上为 |
插件使用编译器的插件配置或maven.compiler.target 属性检测项目的目标Java兼容性。当使用默认的Paketo构建器和构建包时,插件会指示构建包安装相同的Java版本。您可以覆盖此行为,如构建器配置示例所示。 |
更多详细信息,请参阅示例。
标签格式
提供给tags
选项的值应为**完整**的镜像引用。接受的格式为[domainHost:port/][path/]name[:tag][@digest]
。
如果缺少域名,则默认为docker.io
。如果缺少路径,则默认为library
。如果缺少标签,则默认为latest
。
一些示例
-
my-image
将导致镜像引用docker.io/library/my-image:latest
-
my-repository/my-image
将导致docker.io/my-repository/my-image:latest
-
example.com/my-repository/my-image:1.0.0
将按原样使用
spring-boot:build-image
org.springframework.boot:spring-boot-maven-plugin:3.3.5
使用构建包将应用程序打包到OCI镜像中,分叉生命周期以确保package
已运行。此目标适用于命令行调用。如果您需要在构建中配置目标execution
,请改用build-image-no-fork
。
参数详细信息
excludeDevtools
从重新打包的归档文件中排除 Spring Boot devtools。
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
excludeDockerCompose
从重新打包的归档文件中排除 Spring Boot 开发服务。
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
excludeGroupIds
要排除的 groupId 名称的逗号分隔列表(完全匹配)。
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
excludes
要排除的构件定义集合。Exclude
元素定义了必需的 groupId
和 artifactId
组件以及可选的 classifier
组件。当配置为属性时,值应以逗号分隔,并使用冒号分隔组件:groupId:artifactId,groupId:artifactId:classifier
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
image
镜像配置,包含 builder
、runImage
、name
、env
、cleanCache
、verboseLogging
、pullPolicy
和 publish
选项。
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
includes
要包含的构件定义集合。Include
元素定义了必需的 groupId
和 artifactId
组件以及可选的 classifier
组件。当配置为属性时,值应以逗号分隔,并使用冒号分隔组件:groupId:artifactId,groupId:artifactId:classifier
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
layout
归档文件的类型(对应于依赖项在其中如何布局)。可能的值为 JAR
、WAR
、ZIP
、DIR
、NONE
。默认为根据归档文件类型猜测的值。
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
spring-boot:build-image-no-fork
org.springframework.boot:spring-boot-maven-plugin:3.3.5
使用构建包将应用程序打包到 OCI 镜像中,但不分叉生命周期。在构建中配置目标 execution
时,应使用此目标。要在命令行上调用该目标,请使用 build-image
。
参数详细信息
excludeDevtools
从重新打包的归档文件中排除 Spring Boot devtools。
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
excludeDockerCompose
从重新打包的归档文件中排除 Spring Boot 开发服务。
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
excludeGroupIds
要排除的 groupId 名称的逗号分隔列表(完全匹配)。
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
excludes
要排除的构件定义集合。Exclude
元素定义了必需的 groupId
和 artifactId
组件以及可选的 classifier
组件。当配置为属性时,值应以逗号分隔,并使用冒号分隔组件:groupId:artifactId,groupId:artifactId:classifier
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
image
镜像配置,包含 builder
、runImage
、name
、env
、cleanCache
、verboseLogging
、pullPolicy
和 publish
选项。
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
includes
要包含的构件定义集合。Include
元素定义了必需的 groupId
和 artifactId
组件以及可选的 classifier
组件。当配置为属性时,值应以逗号分隔,并使用冒号分隔组件:groupId:artifactId,groupId:artifactId:classifier
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
layout
归档文件的类型(对应于依赖项在其中如何布局)。可能的值为 JAR
、WAR
、ZIP
、DIR
、NONE
。默认为根据归档文件类型猜测的值。
名称 |
|
---|---|
类型 |
|
默认值 |
|
用户属性 |
|
自 |
|
示例
自定义镜像构建器
如果您需要自定义用于创建镜像的构建器或用于启动已构建镜像的运行镜像,请按以下示例所示配置插件。
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>mine/java-cnb-builder</builder>
<runImage>mine/java-cnb-run</runImage>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
此配置将使用名称为 mine/java-cnb-builder
和标签为 latest
的构建器镜像,以及名称为 mine/java-cnb-run
和标签为 latest
的运行镜像。
构建器和运行镜像也可以在命令行上指定,如以下示例所示。
$ mvn spring-boot:build-image -Dspring-boot.build-image.builder=mine/java-cnb-builder -Dspring-boot.build-image.runImage=mine/java-cnb-run
构建器配置
如果构建器使用环境变量公开配置选项,则可以使用 env
属性设置这些选项。
以下是如何配置 Paketo Java 构建包在构建时使用的 JVM 版本的示例。
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<env>
<BP_JVM_VERSION>17</BP_JVM_VERSION>
</env>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
如果 Docker 守护程序与构建包从中下载构件的网络位置之间存在网络代理,则需要配置构建器以使用该代理。在使用 Paketo 构建器时,可以通过设置 HTTPS_PROXY
和/或 HTTP_PROXY
环境变量来实现,如下例所示。
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<env>
<HTTP_PROXY>http://proxy.example.com</HTTP_PROXY>
<HTTPS_PROXY>https://proxy.example.com</HTTPS_PROXY>
</env>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
运行时 JVM 配置
Paketo Java 构建包通过设置 JAVA_TOOL_OPTIONS
环境变量来配置 JVM 运行时环境。可以修改构建包提供的 JAVA_TOOL_OPTIONS
值以自定义应用程序镜像在容器中启动时的 JVM 运行时行为。
应存储在镜像中并应用于每次部署的环境变量修改,可以按照Paketo 文档中所述并如下例所示进行设置。
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<env>
<BPE_DELIM_JAVA_TOOL_OPTIONS xml:space="preserve"> </BPE_DELIM_JAVA_TOOL_OPTIONS>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-XX:+HeapDumpOnOutOfMemoryError</BPE_APPEND_JAVA_TOOL_OPTIONS>
</env>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
自定义镜像名称
默认情况下,镜像名称是从项目的 artifactId
和 version
推断出来的,类似于 docker.io/library/${project.artifactId}:${project.version}
。您可以控制名称,如以下示例所示。
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>example.com/library/${project.artifactId}</name>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
此配置未提供显式标签,因此使用 latest 。也可以指定标签,使用 ${project.version} 、构建中可用的任何属性或硬编码版本。 |
镜像名称也可以在命令行上指定,如以下示例所示。
$ mvn spring-boot:build-image -Dspring-boot.build-image.imageName=example.com/library/my-app:v1
构建包
默认情况下,构建器将使用构建器镜像中包含的构建包,并按预定义的顺序应用它们。可以提供一组替代的构建包,以应用构建器中未包含的构建包,或更改包含的构建包的顺序。当提供一个或多个构建包时,只会应用指定的构建包。
以下示例指示构建器使用打包在 .tgz
文件中的自定义构建包,然后是构建器中包含的构建包。
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<buildpacks>
<buildpack>file:///path/to/example-buildpack.tgz</buildpack>
<buildpack>urn:cnb:builder:paketo-buildpacks/java</buildpack>
</buildpacks>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
构建包可以以以下所示的任何形式指定。
位于 CNB 构建器中的构建包(如果构建器中只有一个与 buildpack-id
匹配的构建包,则可以省略版本)。
-
urn:cnb:builder:buildpack-id
-
urn:cnb:builder:[email protected]
-
buildpack-id
包含构建包内容的目录的路径(在 Windows 上不支持)。
-
file:///path/to/buildpack/
-
/path/to/buildpack/
包含构建包内容的 gzip 压缩 tar 文件的路径。
-
file:///path/to/buildpack.tgz
-
/path/to/buildpack.tgz
包含打包的构建包的 OCI 镜像。
-
docker://example/buildpack
-
docker:///example/buildpack:latest
-
docker:///example/buildpack@sha256:45b23dee08…
-
example/buildpack
-
example/buildpack:latest
-
example/buildpack@sha256:45b23dee08…
镜像发布
可以通过启用 publish
选项将生成的镜像发布到 Docker 注册表。
如果 Docker 注册表需要身份验证,则可以使用 docker.publishRegistry
参数配置凭据。如果 Docker 注册表不需要身份验证,则可以省略 docker.publishRegistry
配置。
镜像将发布到的注册表由镜像名称的注册表部分确定(在这些示例中为 docker.example.com )。如果配置了 docker.publishRegistry 凭据并且包含 url 参数,则此值将传递到注册表,但不用于确定发布注册表的位置。 |
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>docker.example.com/library/${project.artifactId}</name>
<publish>true</publish>
</image>
<docker>
<publishRegistry>
<username>user</username>
<password>secret</password>
</publishRegistry>
</docker>
</configuration>
</plugin>
</plugins>
</build>
</project>
publish
选项也可以在命令行上指定,如以下示例所示。
$ mvn spring-boot:build-image -Dspring-boot.build-image.imageName=docker.example.com/library/my-app:v1 -Dspring-boot.build-image.publish=true
在命令行上使用 publish
选项进行身份验证时,您可以使用属性提供凭据,如以下示例所示。
$ mvn spring-boot:build-image \
-Ddocker.publishRegistry.username=user \
-Ddocker.publishRegistry.password=secret \
-Ddocker.publishRegistry.url=docker.example.com \
-Dspring-boot.build-image.publish=true \
-Dspring-boot.build-image.imageName=docker.example.com/library/my-app:v1
并在 XML 配置中引用这些属性。
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<docker>
<publishRegistry>
<url>${docker.publishRegistry.url}</url>
<username>${docker.publishRegistry.username}</username>
<password>${docker.publishRegistry.password}</password>
</publishRegistry>
</docker>
</configuration>
</plugin>
</plugins>
</build>
</project>
构建器缓存和工作区配置
CNB 构建器缓存构建和启动镜像时使用的层。默认情况下,这些缓存作为命名卷存储在 Docker 守护程序中,其名称派生自目标镜像的全名。如果镜像名称经常更改,例如当项目版本用作镜像名称中的标签时,则缓存可能会经常失效。
可以将缓存卷配置为使用替代名称,以便更好地控制缓存生命周期,如下例所示。
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<buildCache>
<volume>
<name>cache-${project.artifactId}.build</name>
</volume>
</buildCache>
<launchCache>
<volume>
<name>cache-${project.artifactId}.launch</name>
</volume>
</launchCache>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
构建器和构建包需要一个位置来在镜像构建期间存储临时文件。默认情况下,此临时构建工作区存储在命名卷中。
可以将缓存和构建工作区配置为使用绑定挂载而不是命名卷,如下例所示
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<buildWorkspace>
<bind>
<source>/tmp/cache-${project.artifactId}.work</source>
</bind>
</buildWorkspace>
<buildCache>
<bind>
<source>/tmp/cache-${project.artifactId}.build</source>
</bind>
</buildCache>
<launchCache>
<bind>
<source>/tmp/cache-${project.artifactId}.launch</source>
</bind>
</launchCache>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
Docker 配置
minikube 的 Docker 配置
插件可以与minikube 提供的 Docker 守护进程通信,而不是默认的本地连接。
在 Linux 和 macOS 上,可以在启动 minikube 后使用命令 eval $(minikube docker-env)
设置环境变量。
还可以将插件配置为使用 minikube 守护进程,方法是提供类似于以下示例中所示的连接详细信息
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<docker>
<host>tcp://192.168.99.100:2376</host>
<tlsVerify>true</tlsVerify>
<certPath>/home/user/.minikube/certs</certPath>
</docker>
</configuration>
</plugin>
</plugins>
</build>
</project>
Podman 的 Docker 配置
插件可以与Podman 容器引擎通信。
可以通过提供类似于以下示例中所示的连接详细信息,将插件配置为使用 Podman 本地连接
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<docker>
<host>unix:///run/user/1000/podman/podman.sock</host>
<bindHostToBuilder>true</bindHostToBuilder>
</docker>
</configuration>
</plugin>
</plugins>
</build>
</project>
安装了 colima CLI 后,可以使用命令 podman info --format='{{.Host.RemoteSocket.Path}}' 获取此示例中显示的 docker.host 配置属性的值。 |
Colima 的 Docker 配置
插件可以与Colima提供的 Docker 守护进程通信。可以使用以下命令设置 DOCKER_HOST
环境变量
$ export DOCKER_HOST=$(docker context inspect colima -f '{{.Endpoints.docker.Host}}')
还可以将插件配置为使用 Colima 守护进程,方法是提供类似于以下示例中所示的连接详细信息
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<docker>
<host>unix:///${user.home}/.colima/docker.sock</host>
</docker>
</configuration>
</plugin>
</plugins>
</build>
</project>
Docker 身份验证配置
如果构建器或运行镜像存储在支持用户身份验证的私有 Docker 注册表中,则可以使用 docker.builderRegistry
参数提供身份验证详细信息,如下例所示
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<docker>
<builderRegistry>
<username>user</username>
<password>secret</password>
<url>https://docker.example.com/v1/</url>
<email>[email protected]</email>
</builderRegistry>
</docker>
</configuration>
</plugin>
</plugins>
</build>
</project>
如果构建器或运行镜像存储在支持令牌身份验证的私有 Docker 注册表中,则可以使用 docker.builderRegistry
参数提供令牌值,如下例所示
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<docker>
<builderRegistry>
<token>9cbaf023786cd7...</token>
</builderRegistry>
</docker>
</configuration>
</plugin>
</plugins>
</build>
</project>