This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Cloud Kubernetes 5.0.4!

AOT and Native Images (Preview)

Native Image support in Spring Cloud Kubernetes is a preview and is subject to change in subsequent releases, including breaking changes. This page describes the current support.

Configuration Watcher

A native image build has two relevant steps: Spring AOT processes the application first, then GraalVM Native Image compiles the AOT output into an executable. During AOT processing, Spring evaluates conditions such as @ConditionalOnProperty and generates the bean definitions that will be compiled into the image. A property used by one of these conditions must be set when AOT runs; otherwise, a bean omitted at that point cannot be added when the native image starts.

For example, Configuration Watcher can enable secrets monitoring with the runtime environment variable SPRING_CLOUD_KUBERNETES_SECRETS_ENABLED=TRUE. For a native image, that runtime variable cannot restore the Secrets detector if AOT omitted its bean. Set the equivalent property for the JVM used by the process-aot goal with spring-boot.aot.jvmArguments (notice also the -Pnative profile activation that is mantatory for native image) builds):

mvn -pl spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher \
    -am clean install -Pnative -DskipITs -DskipTests \
    -Dspring-boot.build-image.cleanCache=true \
    '-Dspring-boot.aot.jvmArguments=-Dspring.cloud.kubernetes.secrets.enabled=true'

The last argument has two parts:

  • -Dspring-boot.aot.jvmArguments=…​ is a Maven property read by the Spring Boot Maven plugin for AOT processing.

  • The nested -Dspring.cloud.kubernetes.secrets.enabled=true is passed to the JVM running process-aot, so Spring sees Secrets as enabled when it evaluates the conditions and generates the bean definitions.

The build-time sequence is:

  1. Maven passes the nested property to the JVM running process-aot.

  2. Spring AOT sees Secrets enabled and includes the Secrets detector in the generated bean definitions.

  3. GraalVM Native Image compiles those definitions into the native executable.

The quotes keep the complete Maven property together in the shell. This is a build-time setting for the AOT-generated bean graph; a Kubernetes environment variable set at runtime cannot add a detector that was left out during AOT processing.

Another example is enabling HA for Configuration Watcher. Its HA auto-configuration is conditional on spring.cloud.kubernetes.configuration.watcher.ha.enabled, so that property must also be set while process-aot runs. Add it to the same spring-boot.aot.jvmArguments value:

mvn -pl spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher \
    -am clean install -Pnative -DskipITs -DskipTests \
    -Dspring-boot.build-image.cleanCache=true \
    '-Dspring-boot.aot.jvmArguments=-Dspring.cloud.kubernetes.secrets.enabled=true -Dspring.cloud.kubernetes.configuration.watcher.ha.enabled=true'