跳到主要内容
版本:3.5.10

打包 OCI 镜像

QWen Max 中英对照 Packaging OCI Images

打包 OCI 镜像

该插件可以使用 Cloud Native Buildpacks(CNB)从 jar 或 war 文件创建 OCI 镜像。可以使用 bootBuildImage 任务来构建镜像。

备注

出于安全原因,镜像以非 root 用户身份构建和运行。更多详情请参见 CNB 规范

当应用 javawar 插件时,该任务会自动创建,并且是 BootBuildImage 的一个实例。

Docker Daemon

bootBuildImage 任务需要访问 Docker daemon。该任务将检查本地 Docker CLI 的配置文件,以确定当前的上下文,并使用该上下文的连接信息与 Docker daemon 通信。如果无法确定当前上下文,或者该上下文不包含连接信息,则该任务将使用默认的本地连接。此方式在所有受支持的平台上无需额外配置即可与 Docker Engine 配合使用。

可以设置环境变量来配置 bootBuildImage 任务,以使用替代的本地或远程连接。下表列出了环境变量及其对应的值:

环境变量描述
DOCKER_CONFIGDocker CLI 配置文件 的位置,用于确定当前上下文(默认为 $HOME/.docker
DOCKER_CONTEXT应使用的 上下文 名称,用于从 Docker CLI 配置文件中获取主机信息(会覆盖 DOCKER_HOST
DOCKER_HOST包含 Docker 守护进程主机和端口的 URL,例如 tcp://192.168.99.100:2376
DOCKER_TLS_VERIFY当设置为 1 时,启用安全的 HTTPS 协议(可选)
DOCKER_CERT_PATHHTTPS 证书和密钥文件的路径(当 DOCKER_TLS_VERIFY=1 时必需,否则忽略)

Docker daemon 的连接信息也可以通过插件配置中的 docker 属性提供。下表汇总了可用的属性:

属性描述
context应用于从 Docker CLI 配置文件 中检索主机信息的 context 名称
host包含 Docker daemon 主机和端口的 URL,例如 tcp://192.168.99.100:2376
tlsVerify当设置为 true 时,启用安全的 HTTPS 协议(可选)
certPathHTTPS 证书和密钥文件的路径(当 tlsVerifytrue 时必需,否则忽略)
bindHostToBuilder当为 true 时,host 属性的值将提供给为 CNB builder 创建的容器(可选)

更多详情,请参见 示例

Docker Registry

如果 builderrunImage 属性指定的 Docker 镜像存储在需要身份验证的私有 Docker 镜像仓库中,则可以使用 docker.builderRegistry 属性提供身份验证凭据。

如果要将生成的 Docker 镜像发布到 Docker 镜像仓库,可以使用 docker.publishRegistry 属性提供身份验证凭据。

提供了用于用户认证或身份令牌(identity token)认证的属性。有关所支持的认证方法的更多信息,请参阅用于存储镜像的 Docker registry 的文档。

下表总结了 docker.builderRegistrydocker.publishRegistry 的可用属性:

属性描述
usernameDocker 镜像仓库用户的用户名。用户认证时必需。
passwordDocker 镜像仓库用户的密码。用户认证时必需。
urlDocker 镜像仓库的地址。用户认证时可选。
emailDocker 镜像仓库用户的电子邮件地址。用户认证时可选。
tokenDocker 镜像仓库用户的身份令牌。令牌认证时必需。

更多详情,请参见 示例

备注

如果未提供凭证,该插件会读取用户现有的 Docker 配置文件(通常位于 $HOME/.docker/config.json)以确定认证方法。插件将使用这些方法为请求的镜像提供认证凭证。

该插件支持以下认证方法:

  • Credential Helpers:在 Docker 配置文件中配置的外部工具,用于为特定的 registry 提供凭证。例如,osxkeychainecr-login 等工具可处理某些 registry 的认证。

  • Credential Store:一种默认的后备机制,用于安全地存储和检索凭证(例如,Docker Desktop 使用的 desktop)。

  • Static Credentials:直接存储在 Docker 配置文件 auths 部分中的凭证。

镜像定制

该插件调用一个 builder 来协调生成镜像。该 builder 包含多个 buildpacks,可以检查应用程序并影响所生成的镜像。默认情况下,插件会选择一个 builder 镜像。所生成镜像的名称由项目属性推断得出。

任务属性可用于配置构建器在项目上的操作方式。下表总结了可用的属性及其默认值:

Property命令行选项描述默认值
builder--builder要使用的构建器镜像的名称。paketobuildpacks/builder-noble-java-tiny:latest
trustBuilder--trustBuilder是否将该 builder 视为 trustedtrue if the builder is one of paketobuildpacks/builder-noble-java-tiny, paketobuildpacks/builder-jammy-java-tiny, paketobuildpacks/builder-jammy-tiny, paketobuildpacks/builder-jammy-base, paketobuildpacks/builder-jammy-full, paketobuildpacks/builder-jammy-buildpackless-tiny, paketobuildpacks/builder-jammy-buildpackless-base, paketobuildpacks/builder-jammy-buildpackless-full, gcr.io/buildpacks/builder, heroku/builder; false otherwise.
imagePlatform--imagePlatform所拉取的任何 builder 镜像、运行镜像和 buildpack 镜像的平台(操作系统和架构)。格式必须为 OS[/architecture[/variant]],例如 linux/amd64linux/arm64linux/arm/v5。请参考所用 builder 的文档,以确定可用的镜像操作系统和架构选项。无默认值,表示应使用主机机器的平台。
runImage--runImage要使用的运行镜像的名称。无默认值,表示应使用 Builder 元数据中指定的运行时镜像。
imageName--imageName生成的镜像的 Image namedocker.io/library/${project.name}:${project.version}
pullPolicy--pullPolicy用于确定何时从注册表拉取 builder 镜像和 run 镜像的 Policy。可接受的值为 ALWAYSNEVERIF_NOT_PRESENTALWAYS
environment应传递给构建器的环境变量。空。
buildpacks构建器在构建镜像时应使用的 Buildpacks。仅会使用指定的 Buildpacks,从而覆盖构建器中包含的默认 Buildpacks。Buildpack 引用必须采用以下形式之一:

- 构建器中的 Buildpack - [urn:cnb:builder:]<buildpack ID>[@<version>]

- 文件系统目录中的 Buildpack - [file://]<path>

- 文件系统中 gzipped tar(.tgz)文件内的 Buildpack - [file://]<path>/<file name>

- OCI 镜像中的 Buildpack - [docker://]<host>/<repo>[:<tag>][@<digest>]
None,表示构建器应使用其中包含的 buildpacks。
bindings卷绑定挂载(Volume bind mounts) 应在构建镜像时挂载到构建器容器中。这些绑定将在创建构建器容器时以未经解析和验证的形式直接传递给 Docker。绑定必须采用以下形式之一:

- <host source path>:<container destination path>[:<options>]

- <host volume name>:<container destination path>[:<options>]


其中 <options> 可包含以下内容:

- ro:将卷以只读方式挂载到容器中

- rw:将卷以可读写方式挂载到容器中

- volume-opt=key=value:指定由选项名称及其值组成的键值对
network--network构建器容器将配置为使用的 网络驱动。所提供的值在创建构建器容器时会未经验证地传递给 Docker。
cleanCache--cleanCache是否在构建前清理缓存。false
verboseLogging启用构建器操作的详细日志记录。false
publish--publishImage是否将生成的镜像发布到 Docker registry。false
tags一个或多个要应用于生成镜像的附加标签列表。提供给 tags 选项的值应为完整的镜像引用。更多详情请参见 标签部分
buildWorkspace一个临时工作区,将由 builder 和 buildpacks 在镜像构建过程中用于存储文件。该值可以是一个命名卷(named volume)或绑定挂载(bind mount)位置。Docker 守护进程中一个命名卷,其名称源自镜像名称。
buildCache一个包含由 buildpacks 创建的层并被镜像构建过程使用的缓存。该值可以是一个命名卷或绑定挂载位置。Docker 守护进程中一个命名卷,其名称源自镜像名称。
launchCache一个包含由 buildpacks 创建的层并被镜像启动过程使用的缓存。该值可以是一个命名卷或一个绑定挂载位置。Docker 守护进程中的一个命名卷,其名称源自镜像名称。
createdDate--createdDate一个用于设置生成镜像元数据中 Created 字段的日期。该值必须是 ISO 8601 瞬时格式的字符串,或者使用 now 表示当前日期和时间。一个固定日期,用于实现 构建可重现性
applicationDirectory--applicationDirectory应用程序内容将被上传到构建器镜像中的目录路径。在生成的镜像中,应用程序内容也将位于此位置。/workspace
securityOptions--securityOptions安全选项,将应用于构建器容器,以字符串值数组的形式提供["label=disable"] on Linux and macOS, [] on Windows
备注

该插件使用 JavaPlugin 的 targetCompatibility 属性来检测项目的 Java 目标兼容性。当使用默认的 Paketo builder 和 buildpacks 时,该插件会指示 buildpacks 安装相同版本的 Java。你可以按照 builder 配置 示例中所示的方式覆盖此行为。

备注

默认的构建器 paketobuildpacks/builder-noble-java-tiny:latest 包含一组精简的系统库,且不包含 shell。如果应用程序需要 shell 来运行启动脚本(例如,当应用了 application plugin 以生成分发 zip 归档文件时),或者依赖于某些未包含在该构建器中的系统库,则应覆盖 runImage 配置,改用包含 shell 和更完整系统库的镜像,例如 paketobuildpacks/ubuntu-noble-run:latest

标签格式

提供给 tags 选项的值应为完整的镜像引用。可接受的格式为 [domainHost:port/][path/]name[:tag][@digest]

如果域(domain)缺失,则默认为 docker.io。如果路径(path)缺失,则默认为 library。如果标签(tag)缺失,则默认为 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 将按原样使用

示例

自定义 Image Builder 和 Run Image

如果你需要自定义用于创建镜像的 builder,或用于启动构建后镜像的 run 镜像,可按照以下示例配置该任务:

tasks.named("bootBuildImage") {
builder = "mine/java-cnb-builder"
runImage = "mine/java-cnb-run"
}

此配置将使用名为 mine/java-cnb-builder、标签为 latest 的构建器镜像,以及名为 mine/java-cnb-run、标签为 latest 的运行镜像。

构建镜像和运行镜像也可以在命令行中指定,如下例所示:

$ gradle bootBuildImage --builder=mine/java-cnb-builder --runImage=mine/java-cnb-run

Builder 配置

如果构建器(builder)暴露了配置选项,可以使用 environment 属性进行设置。

以下是在构建时 配置 Paketo Java buildpack 所使用的 JVM 版本 的示例:

tasks.named("bootBuildImage") {
environment["BP_JVM_VERSION"] = "17"
}

如果在 Docker daemon(builder 运行于其中)与 buildpacks 下载制品的网络位置之间存在网络代理,则需要配置 builder 以使用该代理。当使用 Paketo builder 时,可以通过设置 HTTPS_PROXY 和/或 HTTP_PROXY 环境变量来实现,如下例所示:

tasks.named("bootBuildImage") {
environment["HTTP_PROXY"] = "http://proxy.example.com"
environment["HTTPS_PROXY"] = "https://proxy.example.com"
}

运行时 JVM 配置

Paketo Java buildpack 通过设置 JAVA_TOOL_OPTIONS 环境变量来配置 JVM 运行时环境。当应用程序镜像在容器中启动时,可以修改 buildpack 提供的 JAVA_TOOL_OPTIONS 值,以自定义 JVM 运行时行为。

应存储在镜像中并应用于每次部署的环境变量修改,可按照 Paketo 文档 中所述进行设置,如下例所示:

tasks.named("bootBuildImage") {
environment["BPE_DELIM_JAVA_TOOL_OPTIONS"] = " "
environment["BPE_APPEND_JAVA_TOOL_OPTIONS"] = "-XX:+HeapDumpOnOutOfMemoryError"
}

自定义镜像名称

默认情况下,镜像名称会根据项目的 nameversion 推断得出,类似于 docker.io/library/${project.name}:${project.version}。你可以通过设置任务属性来控制镜像名称,如下例所示:

tasks.named("bootBuildImage") {
imageName = "example.com/library/${project.name}"
}

请注意,此配置未提供显式的 tag,因此使用 latest。也可以指定一个 tag,可以使用 ${project.version}、构建中可用的任意属性,或硬编码的版本。

镜像名称也可以在命令行中指定,如以下示例所示:

$ gradle bootBuildImage --imageName=example.com/library/my-app:v1

Buildpacks

默认情况下,builder 将使用 builder 镜像中包含的 buildpack,并按照预定义的顺序应用它们。也可以提供一组替代的 buildpack,以应用未包含在 builder 中的 buildpack,或更改已包含 buildpack 的顺序。当提供一个或多个 buildpack 时,将仅应用所指定的 buildpack。

以下示例指示 builder 使用一个打包在 .tgz 文件中的自定义 buildpack,然后使用 builder 中包含的 buildpack。

tasks.named("bootBuildImage") {
buildpacks = ["file:///path/to/example-buildpack.tgz", "urn:cnb:builder:paketo-buildpacks/java"]
}

Buildpacks 可以以如下任意一种形式指定。

位于 CNB Builder 中的 buildpack(如果该 builder 中只有一个 buildpack 与 buildpack-id 匹配,则版本号可以省略):

  • urn:cnb:builder:buildpack-id

  • urn:cnb:builder:buildpack-id@0.0.1

  • buildpack-id

  • buildpack-id@0.0.1

指向包含 buildpack 内容的目录的路径(在 Windows 上不支持):

  • file:///path/to/buildpack/

  • /path/to/buildpack/

指向包含 buildpack 内容的 gzipped tar 文件的路径:

  • file:///path/to/buildpack.tgz

  • /path/to/buildpack.tgz

一个包含 打包的 buildpack 的 OCI 镜像:

  • docker://example/buildpack

  • docker:///example/buildpack:latest

  • docker:///example/buildpack@sha256:45b23dee08…​

  • example/buildpack

  • example/buildpack:latest

  • example/buildpack@sha256:45b23dee08…​

镜像发布

通过启用 publish 选项,可以将生成的镜像发布到 Docker registry。

如果 Docker registry 需要身份验证,可以使用 docker.publishRegistry 属性配置凭据。如果 Docker registry 不需要身份验证,则可以省略 docker.publishRegistry 配置。

备注

镜像将被发布到的 registry 由镜像名称中的 registry 部分(在这些示例中为 docker.example.com)决定。如果配置了 docker.publishRegistry 凭据并包含 url 属性,则该值会传递给 registry,但不会用于确定发布 registry 的位置。

tasks.named("bootBuildImage") {
imageName.set("docker.example.com/library/${project.name}")
publish = true
docker {
publishRegistry {
username = "user"
password = "secret"
}
}
}

发布选项也可以在命令行中指定,如下例所示:

$ gradle bootBuildImage --imageName=docker.example.com/library/my-app:v1 --publishImage

构建器缓存和工作区配置

CNB 构建器会缓存构建和启动镜像时使用的层。默认情况下,这些缓存以命名卷的形式存储在 Docker 守护进程中,其名称由目标镜像的完整名称派生而来。如果镜像名称频繁更改(例如,当项目版本被用作镜像名称中的标签时),则缓存可能会频繁失效。

缓存卷可以配置为使用替代名称,以提供对缓存生命周期的更多控制,如下例所示:

tasks.named("bootBuildImage") {
buildCache {
volume {
name = "cache-${rootProject.name}.build"
}
}
launchCache {
volume {
name = "cache-${rootProject.name}.launch"
}
}
}

构建器(Builders)和 buildpacks 在构建镜像时需要一个位置来存储临时文件。默认情况下,这个临时构建工作区存储在一个命名卷(named volume)中。

缓存和构建工作区可以配置为使用绑定挂载(bind mounts)而非命名卷(named volumes),如下例所示:

tasks.named("bootBuildImage") {
buildWorkspace {
bind {
source = "/tmp/cache-${rootProject.name}.work"
}
}
buildCache {
bind {
source = "/tmp/cache-${rootProject.name}.build"
}
}
launchCache {
bind {
source = "/tmp/cache-${rootProject.name}.launch"
}
}
}

Docker 配置

minikube 的 Docker 配置

该插件可以与 minikube 提供的 Docker daemon 通信,而不是使用默认的本地连接。

在 Linux 和 macOS 上,可以在启动 minikube 后使用命令 eval $(minikube docker-env) 来设置环境变量。

该插件也可以通过提供类似于以下示例所示的连接详细信息,配置为使用 minikube 守护进程:

tasks.named("bootBuildImage") {
docker {
host = "tcp://192.168.99.100:2376"
tlsVerify = true
certPath = "/home/user/.minikube/certs"
}
}

Podman 的 Docker 配置

该插件可以与 podman 容器引擎 通信。

该插件可以通过提供类似以下示例所示的连接详细信息,配置为使用 podman 本地连接:

tasks.named("bootBuildImage") {
docker {
host = "unix:///run/user/1000/podman/podman.sock"
bindHostToBuilder = true
}
}
提示

安装了 podman CLI 后,可以使用命令 podman info --format='{{.Host.RemoteSocket.Path}}' 来获取本例中 docker.host 配置属性的值。

Colima 的 Docker 配置

该插件可以与 Colima 提供的 Docker daemon 进行通信。可以通过以下命令设置 DOCKER_HOST 环境变量:

$ export DOCKER_HOST=$(docker context inspect colima -f '{{.Endpoints.docker.Host}}')

该插件也可以通过提供类似以下示例所示的连接详细信息,配置为使用 Colima 守护进程:

tasks.named("bootBuildImage") {
docker {
host = "unix://${System.properties['user.home']}/.colima/docker.sock"
}
}

用于认证的 Docker 配置

如果 builder 镜像或 run 镜像存储在支持用户认证的私有 Docker registry 中,可以使用 docker.builderRegistry 属性提供认证信息,如下例所示:

tasks.named("bootBuildImage") {
docker {
builderRegistry {
username = "user"
password = "secret"
url = "https://docker.example.com/v1/"
email = "user@example.com"
}
}
}

如果 builder 镜像或 run 镜像存储在支持令牌认证的私有 Docker registry 中,则可以使用 docker.builderRegistry 提供令牌值,如下例所示:

tasks.named("bootBuildImage") {
docker {
builderRegistry {
token = "9cbaf023786cd7..."
}
}
}