Initialization tasks
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?
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.
This approach is reflected in the manifests generated by Kubernetes extension.
Disabling the feature
The feature can be explicitly 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
or on OpenShift:
quarkus.openshift.init-task-defaults.enabled=false
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:
For Flyway:
quarkus.kubernetes.init-tasks.flyway.enabled=false
For Liquibase:
quarkus.kubernetes.init-tasks.liquibase.enabled=false
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
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 the configuration options for init containers (see quarkus.kubernetes.init-containers
or quarkus.openshift.init-containers
).
Examples:
To set the imagePullPolicy
to IfNotPresent
on the init container that waits for the flyway
job:
quarkus.kubernetes.init-containers.flyway.image-pull-policy=if-not-present
To set custom command (say custom-wait-for
) on the init container that waits for the flyway
job:
quarkus.kubernetes.init-containers.flyway.command=custom-wait-for
Orchestration of the initialization tasks
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 waits for
the job to complete is enough to enforce that requirement.
Using a custom wait-for container image
By default, the wait-for
image is groundnuty/k8s-wait-for:no-root-v1.7
.
You can define another image:
quarkus.kubernetes.init-task-defaults.wait-for-container.image=my/wait-for-image:1.0
The imagePullPolicy
can also be configured:
quarkus.kubernetes.init-task-defaults.wait-for-container.image-pull-policy=if-not-present
To change the wait-for
image for a particular init container (e.g. one that waits for the flyway
job), you can use:
quarkus.kubernetes.init-tasks.flyway.wait-for-container.image=my/wait-for-image:1.0
You can define the imagePullPolicy
for this particular init container with:
quarkus.kubernetes.init-tasks.flyway.wait-for-container.image-pull-policy=if-not-present
Configuring permissions
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.
If, for any reason, additional permissions are required either by the init container or the job, they can be configured with the Kubernetes RBAC configuration.
The application, the init container and the job use the same |