Skip to content

Commit

Permalink
doc: apply feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
iocanel committed Sep 22, 2023
1 parent 8498d2c commit 06dc7e4
Showing 1 changed file with 83 additions and 21 deletions.
104 changes: 83 additions & 21 deletions docs/src/main/asciidoc/init-tasks.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
= Initialization tasks
:categories: initialization
:summary: This guide explains how to configure initialization tasks
:summary: This reference guide explains how to configure initialization tasks

There are often initialization tasks performed by Quarkus extensions that are meant to be run once.
For example Flyway or Liquibase initialization fall into that category. But what happens when the scaling
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
Quarkus allows externalization of such tasks as Kubernetes https://kubernetes.io/docs/concepts/workloads/controllers/job/[Jobs] and uses https://kubernetes.io/docs/concepts/workloads/pods/init-containers/[init containers] to ensure that an

Check warning on line 16 in docs/src/main/asciidoc/init-tasks.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'.", "location": {"path": "docs/src/main/asciidoc/init-tasks.adoc", "range": {"start": {"line": 16, "column": 46}}}, "severity": "INFO"}
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.

Expand All @@ -22,62 +22,124 @@ This approach is reflected in the manifests generated by xref:kubernetes.adoc[Ku
== Disabling the feature

The feature can be explictily disabled per task (enabled by default).

Check warning on line 24 in docs/src/main/asciidoc/init-tasks.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Spelling] Use correct American English spelling. Did you really mean 'explictily'? Raw Output: {"message": "[Quarkus.Spelling] Use correct American English spelling. Did you really mean 'explictily'?", "location": {"path": "docs/src/main/asciidoc/init-tasks.adoc", "range": {"start": {"line": 24, "column": 20}}}, "severity": "WARNING"}
The default behavior can change setting the following property to `false`:
The default behavior can change by setting the following property to `false`:

[source,properties]
----
quarkus.kubernetes.init-task-defaults.enabled=false
----

or on Openshift:

Check warning on line 32 in docs/src/main/asciidoc/init-tasks.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Spelling] Use correct American English spelling. Did you really mean 'Openshift'? Raw Output: {"message": "[Quarkus.Spelling] Use correct American English spelling. Did you really mean 'Openshift'?", "location": {"path": "docs/src/main/asciidoc/init-tasks.adoc", "range": {"start": {"line": 32, "column": 7}}}, "severity": "WARNING"}

Check warning on line 32 in docs/src/main/asciidoc/init-tasks.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'OpenShift' rather than 'Openshift' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'OpenShift' rather than 'Openshift' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/init-tasks.adoc", "range": {"start": {"line": 32, "column": 7}}}, "severity": "WARNING"}

[source,properties]
----
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:

Check warning on line 42 in docs/src/main/asciidoc/init-tasks.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'.", "location": {"path": "docs/src/main/asciidoc/init-tasks.adoc", "range": {"start": {"line": 42, "column": 22}}}, "severity": "INFO"}

[source,properties]
----
quarkus.openshift.init-tasks."<task name>".enabled=false
quarkus.kubernetes.init-tasks."<task name>".enabled=false
----

The task name is the name of the Kubernetes Job resource that follows the convention `${quarkus.appliction.name}-${extension}-init`.
If the convention is hard to remember you can always peek at the generated manifests.
The task name is the name of the extension that performs the initialization.
Examples:

== Controlling the generated Job
For Flyway:

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.
[source,properties]
----
quarkus.kubernetes.init-tasks.flyway.enabled=false
----

For Liquibase:

[source,properties]
----
quarkus.kubernets.init-tasks.liquibase.enabled=false
----

For Liquibase Mongodb:

Check warning on line 66 in docs/src/main/asciidoc/init-tasks.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.CaseSensitiveTerms] Use 'MongoDB' rather than 'Mongodb'. Raw Output: {"message": "[Quarkus.CaseSensitiveTerms] Use 'MongoDB' rather than 'Mongodb'.", "location": {"path": "docs/src/main/asciidoc/init-tasks.adoc", "range": {"start": {"line": 66, "column": 15}}}, "severity": "INFO"}

[source,properties]
----
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.

[source,properties]
----
QUARKUS_INIT_AND_EXIT=true
----

The image, image pull policy, service account, volumes, mounts and additional environment variables are inherited from the deployment resource.
Any customization that happens to the original deployment resource (via configuration or extension) will be reflected in the Job too.
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 too.

Check warning on line 85 in docs/src/main/asciidoc/init-tasks.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'through', 'by', 'from', 'on', or 'by using' rather than 'via' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'through', 'by', 'from', 'on', or 'by using' rather than 'via' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/init-tasks.adoc", "range": {"start": {"line": 85, "column": 56}}}, "severity": "WARNING"}

== 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.

Check warning on line 90 in docs/src/main/asciidoc/init-tasks.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'.", "location": {"path": "docs/src/main/asciidoc/init-tasks.adoc", "range": {"start": {"line": 90, "column": 55}}}, "severity": "INFO"}
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`).

Check warning on line 91 in docs/src/main/asciidoc/init-tasks.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'.", "location": {"path": "docs/src/main/asciidoc/init-tasks.adoc", "range": {"start": {"line": 91, "column": 51}}}, "severity": "INFO"}

Check failure on line 91 in docs/src/main/asciidoc/init-tasks.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.RepeatedWords] 'using' is repeated! Raw Output: {"message": "[Quarkus.RepeatedWords] 'using' is repeated!", "location": {"path": "docs/src/main/asciidoc/init-tasks.adoc", "range": {"start": {"line": 91, "column": 52}}}, "severity": "ERROR"}

Check warning on line 91 in docs/src/main/asciidoc/init-tasks.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'.", "location": {"path": "docs/src/main/asciidoc/init-tasks.adoc", "range": {"start": {"line": 91, "column": 57}}}, "severity": "INFO"}

Examples:

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

[source,properties]
----
quarkus.kubernetes.init-containers.wait-for-flyway.image-pull-policy=IfNotPresent
----

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

== Coordination between Job and deployment
[source,properties]
----
quarkus.kubernetes.init-containers.wait-for-flyway.command=custom-wait-for
----


== Orchestration of the initialization tasks

The deploymnet resource should not start until the Job has succesfully completed. The common 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.
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 image
=== Using a custom wait-for container image

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

[source,properties]
----
quarkus.openshift.init-task-defaults.wait-for-image=my/wait-for-image:1.0
quarkus.kubernetes.init-task-defaults.wait-for-image=my/wait-for-image:1.0
----

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

[source,properties]
----
quarkus.kubernetes.init-containers.wait-for-flyway=my/wait-for-image:1.0
----

=== Configuring permissions

For an init container to be able to to perform the `wait for job` it needs to be able to perform `get` operations on the `Job` resource.
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 additiona permissions are required either by the init container or the `Job`, they can be configured with through the xref:deploying-to-kuberentes.adoc#generating-rbac-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 xref:deploying-to-kuberentes.adoc#generating-rbac-resources[Kubernetes RBAC configuration].

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

== Extension providing Initialization Tasks

Currently this feature is used by the following extensions:
Currently, this feature is used by the following extensions:
- xref:flyway.adoc[Flyway]
- xref:liquibase.adoc[Liquibase]
- xref:liquibase-mongodb.adoc[Liquibase MongoDB]

0 comments on commit 06dc7e4

Please sign in to comment.