We are using InitContainer(https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ ) for running necessary initialization before the application startup.

InitContainer logic is shipped within the actual micronaut microservice, is initiated by Kubernetes before 'real' application container is started, and is run as standard micronaut application with default environment set to 'init'.

Development

InitContainer logic must be written as @Singleton that defines @Requires(env = ["init"]), so that this bean is created only when micronaut environment “init“ is active.

After the execution, it also must explicitly close beanContext to ensure that the application is stopped.

Use cases

InitDbServiceImpl is the only implementation as of now - it applies Flyway DB migration during init container phase.

Usage

Microservice that wants to use Flyway migration during initContainer phase should create their own copy of the above mentioned InitDBServiceImpl and application-init.yml has to be added to src/main/resources to be able to configure the behaviour properly.

application-init.yml has to:

  • disable kafka (so that no listener would be started and thus no chance of any message to be consumed)

  • disable temporal workers, if temporal is used (e.g. annotate those singletons with @Requires(property = "temporal.worker.enabled", value = "true")and add temporal.woker.enabled: true to application,yml

  • possibly disable other services in the future that should not be touched during init container phase

Example of application-init.yml for microservice that wants to apply flyway migration init container:

kafka.enabled: false
# if temporal is used
temporal:
  worker:
    enabled: false

There should be no change to Application.kt or any other application codebase file, its Kubernetes' job to start the application with 'init' environment during initContainer phase.

This is done by (globally) configuring InitContainer process to run the application with init environment by setting

spec.template.spec.initContainers.env:
  name: MICRONAUT_ENVIRONMENTS
  value: "init"

in deployment.yaml, according to Default environment section in https://docs.micronaut.io/latest/guide/#environments (Environments can be explicitly specified either through … or the MICRONAUT_ENVIRONMENTS environment variable), InitContainers needs to be enabled by setting

kotlin.initContainer: true

in values.yml (use appropriate environment and application folder) and by using suitable helm version (0.3.6 or higher):

dependencies.version: 0.3.6

in Chart.yml (use appropriate environment and application folder)