DEV Community

loading...
Cover image for Best practices on   Spring Cloud Kubernetes bootstrap configuration

Best practices on Spring Cloud Kubernetes bootstrap configuration

Artem Ptushkin
Java/Kotlin clean code developer; Consumer-Driven contracts expert; Spring expert
・3 min read

In this article I want to show the best way to configure any Spring Cloud bootstrap properties in your application, making it the a most flexible and future-proof way.

Jump to the code here!

Microservices stack

Following or switching into more microservice architecture, most modern Spring boot applications start using one day something from Spring Cloud stack additionally due to its features and compatibility with Spring Boot stack it already has, i.e. you take the whole ecosystem.

I describe an example in this article of how neat you it is possible to integrate Spring and Spring Boot by using starters.

Along side with Spring Cloud stack, most applications start using Kubernetes as microservices orchestration service, and for this we have the growing Spring Cloud Kubernetes project.

On purpose to externalise application's properties there are two most commons ways to implement this:

  1. k8s configmap
  2. Spring Cloud Config server

Considering pros and cons both of these are worth to use and none is really better than another.

Definitely, stack and complexity grows with this and following the hello world approaches online developers rather implement configuration in a way that still brings problems and/or kept unclear for other developers.

One of the crucial and the most important things is enabling/disabling of configuration, as it brings the most influence to your runtime, activating or disabling beans. This is partially confirmed by Stackoverflow questions, querying:

  • spring configuration doesn't start: 973
  • spring configuration disable: 2748
  • and all the other questions on bean duplication / missing problems

In order to make the best out of your configuration, I'd like to show some best practices on an example with Spring Cloud Kubernetes config.

Before jumping to the example it's better to know the basis about the Spring application properties order of precedence:

How to configure bootstrap properties

What are the requirements to the best configuration?

  1. It always starts in each k8s environment
  2. It doesn't start in tests
  3. It start's for a local application run easily when you need it

What do we know?

  1. bootstrap properties start before application one
  2. application in k8s cluster container fetchs data from k8s configmap only if it's enabled beforehand
  3. application must know where to take the properties from before the load
  4. spring.cloud.kubernetes.enabled enables all the sub-configurations
  5. spring.cloud.kubernetes.config.enabled enables fetching configmap
  6. kubernetes profile exists out of box and will be activated always when the application runs as a pod inside Kubernetes

Then we need:

  • bootstrap.yaml in resources directory containing:
spring:
  cloud:
    kubernetes:
      config:
        enabled: false
      enabled: false
Enter fullscreen mode Exit fullscreen mode
  • bootstrap-kubernetes.yaml containing:
spring:
  cloud:
    kubernetes:
      config:
        enabled: true
      enabled: true
Enter fullscreen mode Exit fullscreen mode
  • application.yaml or application-kubernetes.yaml containing:
spring:
  cloud:
    kubernetes:
      config:
        name: your-configmap-name
        namespace: ${KUBERNETES_NAMESPACE}
Enter fullscreen mode Exit fullscreen mode

Env variable KUBERNETES_NAMESPACE can't be determined on bootstrap configuration loading as the k8s configmap won't be fetched yet. Hence, we put it into application properties.

  • k8s service.yaml containing:
spec:
  containers:
    env:
    - name: "KUBERNETES_NAMESPACE"
      valueFrom:
      fieldRef:
        fieldPath: "metadata.namespace"
Enter fullscreen mode Exit fullscreen mode
  • [OPTIONAL] To make it more transparent to developers and let everyone know that kubernetes profile will be enabled I'd advice to put this profile explicitly, service.yaml. Another argument here, that if you already use SPRING_PROFILES_ACTIVE than it definitely will be clearer if you put additionally the kubernetes profile, defining all the profiles list at the same place:
spec:
  containers:
    env:
    - name: SPRING_PROFILES_ACTIVE
      value: "your-profile,kubernetes"
Enter fullscreen mode Exit fullscreen mode

Conclusions

With this configuration you can easily enable k8s by activating kubernetes profile and it will disabled on any other run.

Hints

  • Staring common @SpringBootApplication main class with kubernetes profile we aware that
    1. You might need env variable KUBERNETES_NAMESPACE
    2. It uses k8s context and namespace from the one that is used in your configuration (kubectl) now

Discussion (0)