打包OCI镜像
该插件可以使用 Cloud Native Buildpacks (CNB) 从jar或war文件创建 OCI image。
可以通过 bootBuildImage
任务构建镜像。
出于安全考虑,镜像的构建和运行均以非root用户身份进行。 详见 CNB规范。 |
当应用了 java
或 war
插件时,该任务会被自动创建,并且是 BootBuildImage
的一个实例。
Docker Daemon
bootBuildImage
任务需要访问Docker守护进程。
该任务会检查本地Docker CLI的 配置文件,以确定当前的 context,并使用该context的连接信息与Docker守护进程通信。
如果无法确定当前context,或context没有连接信息,则该任务会使用默认的本地连接。
这在所有受支持平台上的 Docker Engine下无需配置即可工作。
可以通过设置环境变量来配置 bootBuildImage
任务使用本地或远程连接。
下表展示了可用的环境变量及其含义:
Environment variable | Description |
---|---|
DOCKER_CONFIG |
用于确定当前context的Docker CLI 配置文件位置(默认为 |
DOCKER_CONTEXT |
应用于从Docker CLI配置文件获取主机信息的 context名称(会覆盖 |
DOCKER_HOST |
Docker守护进程的主机和端口URL,例如 |
DOCKER_TLS_VERIFY |
设置为`1`时启用安全HTTPS协议(可选) |
DOCKER_CERT_PATH |
HTTPS所需的证书和密钥文件路径(若`DOCKER_TLS_VERIFY=1`时必需,否则忽略) |
也可以通过插件配置中的 docker
属性提供Docker守护进程连接信息。
下表总结了可用的属性:
Property | Description |
---|---|
|
|
|
Docker守护进程的主机和端口URL,例如 |
|
设置为 |
|
HTTPS所需的证书和密钥文件路径(若 |
|
若为 |
更多详情参见 示例。
Docker Registry
如果 builder
或 runImage
属性指定的Docker镜像存储在需要认证的私有Docker镜像仓库中,则可通过 docker.builderRegistry
属性提供认证凭据。
如果生成的Docker镜像需要发布到Docker镜像仓库,则可通过 docker.publishRegistry
属性提供认证凭据。
属性支持用户认证或身份令牌认证。 请查阅所用Docker仓库的文档,了解支持的认证方式。
下表总结了 docker.builderRegistry
和 docker.publishRegistry
可用的属性:
Property | Description |
---|---|
|
Docker镜像仓库用户的用户名。用户认证时必需。 |
|
Docker镜像仓库用户的密码。用户认证时必需。 |
|
Docker镜像仓库地址。用户认证时可选。 |
|
Docker镜像仓库用户的电子邮件地址。用户认证时可选。 |
|
Docker镜像仓库用户的身份令牌。令牌认证时必需。 |
更多详情参见 示例。
如果未提供凭据,插件会读取用户现有的Docker配置文件(通常位于 插件支持以下认证方式:
|
镜像自定义
插件会调用 builder来编排镜像的生成。 builder包含多个 buildpacks,可检查应用以影响生成的镜像。 默认情况下,插件会选择一个builder镜像。 生成镜像的名称由项目属性推断得出。
可通过任务属性配置builder在项目上的操作方式。 下表总结了可用属性及其默认值:
Property | Command-line option | Description | Default value |
---|---|---|---|
|
|
要使用的builder镜像名称。 |
|
|
|
是否将builder视为 受信任。 |
若builder为 |
|
|
拉取的builder、run和buildpack镜像的平台(操作系统和架构)。
格式为 |
无默认值,表示使用主机平台。 |
|
|
要使用的run镜像名称。 |
无默认值,表示使用Builder元数据中指定的run镜像。 |
|
|
|
|
|
|
用于决定何时从仓库拉取builder和run镜像的策略。
可选值为 |
|
|
传递给builder的环境变量。 |
空。 |
|
|
构建镜像时builder应使用的buildpacks。 仅会使用指定的buildpacks,覆盖builder中包含的默认buildpacks。 buildpack引用必须为以下形式之一:
|
无,表示使用builder自带的buildpacks。 |
|
|
卷绑定挂载,在构建镜像时应挂载到builder容器。 绑定信息会在创建builder容器时原样传递给Docker,不做解析和校验。 绑定必须为以下形式之一:
其中`<选项>`可包含:
|
||
|
|
builder容器将配置使用的 网络驱动。 提供的值会在创建builder容器时原样传递给Docker,不做校验。 |
|
|
|
构建前是否清理缓存。 |
|
|
启用builder操作的详细日志。 |
|
|
|
|
是否将生成的镜像发布到Docker仓库。 |
|
|
要为生成镜像附加的一个或多个额外标签。
|
||
|
builder和buildpacks在构建镜像时用于存储文件的临时工作区。 该值可以是命名卷或绑定挂载位置。 |
Docker守护进程中的命名卷,名称由镜像名派生。 |
|
|
构建过程中buildpacks创建的层缓存。 该值可以是命名卷或绑定挂载位置。 |
Docker守护进程中的命名卷,名称由镜像名派生。 |
|
|
镜像启动过程中buildpacks创建的层缓存。 该值可以是命名卷或绑定挂载位置。 |
Docker守护进程中的命名卷,名称由镜像名派生。 |
|
|
|
用于设置生成镜像元数据中 |
固定日期以实现 构建可重现性。 |
|
|
应用内容将上传到builder镜像中的目录路径。 生成的镜像中应用内容也位于该位置。 |
|
|
|
将应用于builder容器的 安全选项,以字符串数组形式提供 |
Linux和macOS下为 |
插件会通过JavaPlugin的 targetCompatibility 属性检测项目的目标Java兼容性。
使用默认Paketo builder和buildpacks时,插件会指示buildpacks安装相同的Java版本。
你可以按 builder配置示例所示覆盖此行为。
|
默认builder paketobuildpacks/builder-noble-java-tiny:latest 包含的系统库较少且不包含shell。
需要shell来运行启动脚本的应用(如应用了 application`插件 生成分发zip包的情况),或依赖于未包含的系统库的应用,应通过 `runImage 配置项指定包含shell和更丰富系统库的镜像,如 paketobuildpacks/ubuntu-noble-run-base:latest 。
|
标签格式
传递给 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
会直接按原样使用
示例
自定义镜像构建器与运行镜像
如果你需要自定义用于创建镜像的 builder 或用于启动已构建镜像的 run image,可按如下示例配置任务:
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
builder = "mine/java-cnb-builder"
runImage = "mine/java-cnb-run"
}
tasks.named<BootBuildImage>("bootBuildImage") {
builder.set("mine/java-cnb-builder")
runImage.set("mine/java-cnb-run")
}
该配置将使用名为 mine/java-cnb-builder
且标签为 latest
的 builder 镜像,以及名为 mine/java-cnb-run
且标签为 latest
的 run image。
builder 和 run image 也可以通过命令行指定,如下所示:
$ gradle bootBuildImage --builder=mine/java-cnb-builder --runImage=mine/java-cnb-run
Builder 配置
如果 builder 暴露了配置选项,可以通过 environment
属性进行设置。
以下是 配置 Paketo Java buildpacks 构建时 JVM 版本 的示例:
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
environment["BP_JVM_VERSION"] = "17"
}
tasks.named<BootBuildImage>("bootBuildImage") {
environment.put("BP_JVM_VERSION", "17")
}
如果 Docker daemon 所在的 builder 与 buildpacks 下载构件的网络位置之间存在代理,则需要配置 builder 使用代理。
使用 Paketo builder 时,可以通过设置 HTTPS_PROXY
和/或 HTTP_PROXY
环境变量实现,如下例所示:
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
environment["HTTP_PROXY"] = "http://proxy.example.com"
environment["HTTPS_PROXY"] = "https://proxy.example.com"
}
tasks.named<BootBuildImage>("bootBuildImage") {
environment.putAll(mapOf("HTTP_PROXY" to "http://proxy.example.com",
"HTTPS_PROXY" to "https://proxy.example.com"))
}
运行时 JVM 配置
Paketo Java buildpacks 通过设置 JAVA_TOOL_OPTIONS
环境变量 配置 JVM 运行时环境。
buildpack 提供的 JAVA_TOOL_OPTIONS
值可以被修改,以便在容器中启动应用镜像时自定义 JVM 运行时行为。
需要存储在镜像中并应用于每次部署的环境变量修改,可参考 Paketo 文档 并如下例所示:
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
environment["BPE_DELIM_JAVA_TOOL_OPTIONS"] = " "
environment["BPE_APPEND_JAVA_TOOL_OPTIONS"] = "-XX:+HeapDumpOnOutOfMemoryError"
}
tasks.named<BootBuildImage>("bootBuildImage") {
environment.putAll(mapOf(
"BPE_DELIM_JAVA_TOOL_OPTIONS" to " ",
"BPE_APPEND_JAVA_TOOL_OPTIONS" to "-XX:+HeapDumpOnOutOfMemoryError"
))
}
自定义镜像名称
默认情况下,镜像名称由项目的 name
和 version
推断而来,形如 docker.io/library/${project.name}:${project.version}
。
你可以通过设置任务属性来控制镜像名称,如下例所示:
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
imageName = "example.com/library/${project.name}"
}
tasks.named<BootBuildImage>("bootBuildImage") {
imageName.set("example.com/library/${project.name}")
}
注意,该配置未显式指定标签,因此会使用 latest
。
也可以指定标签,无论是使用 ${project.version}
、构建中可用的任何属性,还是硬编码版本。
镜像名称也可通过命令行指定,如下所示:
$ gradle bootBuildImage --imageName=example.com/library/my-app:v1
Buildpacks
默认情况下,builder 会使用 builder 镜像中包含的 buildpacks,并按预定义顺序应用。 也可以提供一组自定义 buildpacks,用于应用 builder 未包含的 buildpacks,或更改已包含 buildpacks 的顺序。 当指定了一个或多个 buildpacks 时,仅会应用这些指定的 buildpacks。
以下示例指示 builder 先使用一个打包为 .tgz
文件的自定义 buildpack,然后再使用 builder 中包含的 buildpack。
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
buildpacks = ["file:///path/to/example-buildpack.tgz", "urn:cnb:builder:paketo-buildpacks/java"]
}
tasks.named<BootBuildImage>("bootBuildImage") {
buildpacks.set(listOf("file:///path/to/example-buildpack.tgz", "urn:cnb:builder:paketo-buildpacks/java"))
}
buildpacks 可按以下任意形式指定。
位于 CNB Builder 中的 buildpack(如果 builder 中仅有一个与 buildpack-id
匹配的 buildpack,则版本可省略):
-
urn:cnb:builder:buildpack-id
-
urn:cnb:builder:buildpack-id@0.0.1
-
buildpack-id
-
buildpack-id@0.0.1
指向包含 buildpack 内容的目录路径(Windows 不支持):
-
/path/to/buildpack/
指向包含 buildpack 内容的 gzip 压缩 tar 文件路径:
-
/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 仓库。
如果 Docker 仓库需要认证,可通过 docker.publishRegistry
属性配置凭据。
如果 Docker 仓库不需要认证,则可以省略 docker.publishRegistry
配置。
镜像将被发布到的仓库由镜像名称中的 registry 部分决定(如这些示例中的 docker.example.com )。
如果配置了 docker.publishRegistry 凭据并包含 url 属性,该值会传递给仓库,但不会用于决定发布仓库的位置。
|
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
imageName.set("docker.example.com/library/${project.name}")
publish = true
docker {
publishRegistry {
username = "user"
password = "secret"
}
}
}
tasks.named<BootBuildImage>("bootBuildImage") {
imageName.set("docker.example.com/library/${project.name}")
publish.set(true)
docker {
publishRegistry {
username.set("user")
password.set("secret")
}
}
}
发布选项也可以通过命令行指定,如下所示:
$ gradle bootBuildImage --imageName=docker.example.com/library/my-app:v1 --publishImage
Builder 缓存与工作区配置
CNB builder 会缓存构建和启动镜像时使用的层。 默认情况下,这些缓存作为命名卷存储在 Docker daemon 中,卷名由目标镜像的完整名称派生。 如果镜像名称经常变化(例如项目版本作为镜像标签),则缓存也可能会频繁失效。
可以通过如下示例配置缓存卷使用自定义名称,以便更好地控制缓存生命周期:
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
buildCache {
volume {
name = "cache-${rootProject.name}.build"
}
}
launchCache {
volume {
name = "cache-${rootProject.name}.launch"
}
}
}
tasks.named<BootBuildImage>("bootBuildImage") {
buildCache {
volume {
name.set("cache-${rootProject.name}.build")
}
}
launchCache {
volume {
name.set("cache-${rootProject.name}.launch")
}
}
}
builder 和 buildpacks 需要一个位置在构建镜像期间存储临时文件。 默认情况下,该临时构建工作区存储在命名卷中。
缓存和构建工作区也可以配置为使用绑定挂载(bind mount)而非命名卷,如下例所示:
-
Groovy
-
Kotlin
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"
}
}
}
tasks.named<BootBuildImage>("bootBuildImage") {
buildWorkspace {
bind {
source.set("/tmp/cache-${rootProject.name}.work")
}
}
buildCache {
bind {
source.set("/tmp/cache-${rootProject.name}.build")
}
}
launchCache {
bind {
source.set("/tmp/cache-${rootProject.name}.launch")
}
}
}
Docker 配置
minikube 的 Docker 配置
插件可以与 minikube 提供的 Docker daemon 通信,而不是默认的本地连接。
在 Linux 和 macOS 上,minikube 启动后可通过命令 eval $(minikube docker-env)
设置环境变量。
插件也可以通过如下示例所示的连接信息配置为使用 minikube daemon:
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
docker {
host = "tcp://192.168.99.100:2376"
tlsVerify = true
certPath = "/home/user/.minikube/certs"
}
}
tasks.named<BootBuildImage>("bootBuildImage") {
docker {
host.set("tcp://192.168.99.100:2376")
tlsVerify.set(true)
certPath.set("/home/user/.minikube/certs")
}
}
podman 的 Docker 配置
插件可以与 podman 容器引擎 通信。
插件可通过如下示例所示的连接信息配置为使用 podman 本地连接:
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
docker {
host = "unix:///run/user/1000/podman/podman.sock"
bindHostToBuilder = true
}
}
tasks.named<BootBuildImage>("bootBuildImage") {
docker {
host.set("unix:///run/user/1000/podman/podman.sock")
bindHostToBuilder.set(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 daemon:
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
docker {
host = "unix://${System.properties['user.home']}/.colima/docker.sock"
}
}
tasks.named<BootBuildImage>("bootBuildImage") {
docker {
host.set("unix://${System.getProperty("user.home")}/.colima/docker.sock")
}
}
Docker 认证配置
如果 builder 或 run image 存储在支持用户认证的私有 Docker 仓库中,可通过如下示例所示的 docker.builderRegistry
属性提供认证信息:
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
docker {
builderRegistry {
username = "user"
password = "secret"
url = "https://docker.example.com/v1/"
email = "user@example.com"
}
}
}
tasks.named<BootBuildImage>("bootBuildImage") {
docker {
builderRegistry {
username.set("user")
password.set("secret")
url.set("https://docker.example.com/v1/")
email.set("user@example.com")
}
}
}
如果 builder 或 run image 存储在支持 token 认证的私有 Docker 仓库中,可通过如下示例所示的 docker.builderRegistry
提供 token 值:
-
Groovy
-
Kotlin
tasks.named("bootBuildImage") {
docker {
builderRegistry {
token = "9cbaf023786cd7..."
}
}
}
tasks.named<BootBuildImage>("bootBuildImage") {
docker {
builderRegistry {
token.set("9cbaf023786cd7...")
}
}
}