Initialization tasks

通常,Quarkus 扩展会执行一些初始化任务,这些任务旨在运行一次。例如,Flyway 或 Liquibase 初始化属于该类。但是,当需要更多的应用程序实例来运行应用程序的可伸缩性时,会发生什么情况?或者当应用程序重新启动时会发生什么情况?

There are often initialization tasks performed by Quarkus extensions that are meant to be run once. For example, Flyway or Liquibase initialization falls into that category. But what happens when the scaling needs of an application requires more instances of the application to run? Or what happens when the application restarts ?

这两个用例都很常见的一个常见环境就是 Kubernetes。为了解决这些挑战,Quarkus 允许将这些任务外部化为 Kubernetes Jobs,并使用 init containers 以确保只有在初始化作业完成后,应用程序实例才会启动。使用此方法,即使应用程序有多个副本,初始化逻辑也只会运行一次。

A common environment where both of these cases are pretty common is Kubernetes. To address these challenges, Quarkus allows externalization of such tasks as Kubernetes Jobs and uses init containers to ensure that an application instance only starts once the initialization jobs have finished. With this approach even if an application has multiple replicas, the initialization logic will only run once.

这种方法反映在 Kubernetes extension 生成的清单中。

This approach is reflected in the manifests generated by Kubernetes extension.

Disabling the feature

可以显式地禁用每个任务中的特性(默认情况下启用)。可以通过将以下属性设置为 false 来更改默认行为:

The feature can be explictily disabled per task (enabled by default). The default behavior can change by setting the following property to false:

quarkus.kubernetes.init-task-defaults.enabled=false

或在 OpenShift 上:

or on OpenShift:

quarkus.openshift.init-task-defaults.enabled=false

Note:本指南中的所有配置选项都适用于 OpenShift 和 Kubernetes。本指南的其余部分将使用 Kubernetes(quarkus.kubernetes 前缀)配置前缀,但所有配置选项也可用于 OpenShift(quarkus.openshift 前缀)。

Note: All the configuration options in this guide are available on both OpenShift and Kubernetes. The rest of the guide will use Kubernetes(quarkus.kubernetes prefix) configuration prefix, but all the configuration options are also available for OpenShift(quarkus.openshift prefix) too.

如果需要禁用特定任务,我们可以使用以下属性:

In the case where we need to disable a particular task, we can use the following property:

quarkus.kubernetes.init-tasks."<task name>".enabled=false

任务名称是执行初始化的扩展的名称。示例:

The task name is the name of the extension that performs the initialization. Examples:

对于 Flyway:

For Flyway:

quarkus.kubernetes.init-tasks.flyway.enabled=false

对于 Liquibase:

For Liquibase:

quarkus.kubernetes.init-tasks.liquibase.enabled=false

对于 Liquibase Mongodb:

For Liquibase Mongodb:

quarkus.kubernetes.init-tasks.liquibase-mongodb.enabled=false

Controlling the generated job

作业容器与应用程序容器非常相似,唯一改变的是配置的环境变量。更具体地说,添加以下环境变量,以在初始化后立即指示作业退出。

The job container is pretty similar to the application container, and the only thing that changes is the configured environment variables. More specifically, the following environment variable is added, to tell the job to exit right after initialization.

QUARKUS_INIT_AND_EXIT=true

图像、图像提取政策、服务帐户、卷、挂载和附加环境变量从部署资源继承/复制。对原始部署资源的任何自定义(通过配置或扩展)也会反映在作业中。

The image, image pull policy, service account, volumes, mounts and additional environment variables are inherited/copied from the deployment resource. Any customization to the original deployment resource (via configuration or extension) will also be reflected in the job.

Controlling the generated init container

生成的初始化容器的名称默认`wait-for-${task name}`。鉴于初始化容器是与实际应用程序相同的 Pod 的一部分,它将获取与应用程序相同的服务帐户(因此权限)和卷。可以使用初始化容器的配置选项(请参见 quarkus.kubernetes.init-containersquarkus.openshift.init-containers)进一步自定义容器。

The name of the generated init container is wait-for-${task name} by default. Given that the init container is part of the same pod as the actual application it will get the same service account (and therefore permissions) and volumes as the application. Further customization to the container can be done using using the configuration options for init containers (see quarkus.kubernetes.init-containers or quarkus.openshift.init-containers).

示例:

Examples:

若要将图像提取政策设置为 IfNotPresent 在等待 flyway 作业的初始化容器上:

To set the imagePullPolicy to IfNotPresent on the init container that waits for the flyway job:

quarkus.kubernetes.init-containers.wait-for-flyway.image-pull-policy=IfNotPresent

若要设置自定义命令(例如 custom-wait-for)在等待 flyway 作业的初始化容器上:

To set custom command (say custom-wait-for) on the init container that waits for the flyway job:

quarkus.kubernetes.init-containers.wait-for-flyway.command=custom-wait-for

Orchestration of the initialization tasks

在作业完成之前,部署资源不应该启动。Kubernetes 用户中使用的典型模式是使用初始化容器实现此目的。一个`wait for`作业完成的初始化容器足以实现该要求。

The deployment resource should not start until the job has been completed. The typical pattern that is used among Kubernetes users is the use of init containers to achieve this. An init container that wait for the job to complete is enough to enforce that requirement.

Using a custom wait-for container image

若要更改默认`groundnuty/k8s-wait-for:no-root-v1.7` 的 wait-for 图像,可以使用:

To change the wait-for image which by default is groundnuty/k8s-wait-for:no-root-v1.7 you can use:

quarkus.kubernetes.init-task-defaults.wait-for-container.image=my/wait-for-image:1.0

若要更改特定初始化容器(例如 wait-for-flway)的 wait-for 图像,可以使用:

To change the wait-for image for a particular init container (e.g. wait-for-flway) you can use:

quarkus.kubernetes.init-containers.wait-for-flyway=my/wait-for-image:1.0

Configuring permissions

为了让一个初始化容器能够执行 wait for job,它需要能够对作业资源执行 get 操作。这是自动完成的,生成的清单包括所需的 RoleRoleBinding 资源。

For an init container to be able to perform the wait for job it needs to be able to perform get operations on the job resource. This is done automatically and the generated manifests include the required Role and RoleBinding resources.

如果出于任何原因,初始化容器或作业需要其他权限,它们可以通过 Kubernetes RBAC configuration 进行配置。

If for any reason additional permissions are required either by the init container or the job, they can be configured with through the Kubernetes RBAC configuration.

Note:应用程序、初始化容器和作业使用相同的 ServiceAccount,因此共享相同的权限。

Note: The application, the init container and the job use the same ServiceAccount and therefore, share the same permissions.

Extension providing Initialization Tasks

当前,此功能由以下扩展使用:- Flyway- Liquibase- Liquibase MongoDB

Currently, this feature is used by the following extensions: - Flyway - Liquibase - Liquibase MongoDB