2. ConfigMap PropertySource

Kubernetes provides a resource named ConfigMap to externalize the parameters to pass to your application in the form of key-value pairs or embedded application.properties|yaml files. The Spring Cloud Kubernetes Config project makes Kubernetes `ConfigMap`s available during application bootstrapping and triggers hot reloading of beans or Spring context when changes are detected on observed `ConfigMap`s.

The default behavior is to create a ConfigMapPropertySource based on a Kubernetes ConfigMap which has metadata.name of either the name of your Spring application (as defined by its spring.application.name property) or a custom name defined within the bootstrap.properties file under the following key spring.cloud.kubernetes.config.name.

However, more advanced configuration are possible where multiple ConfigMaps can be used This is made possible by the spring.cloud.kubernetes.config.sources list. For example one could define the following ConfigMaps

spring:
  application:
    name: cloud-k8s-app
  cloud:
    kubernetes:
      config:
        name: default-name
        namespace: default-namespace
        sources:
         # Spring Cloud Kubernetes will lookup a ConfigMap named c1 in namespace default-namespace
         - name: c1
         # Spring Cloud Kubernetes will lookup a ConfigMap named default-name in whatever namespace n2
         - namespace: n2
         # Spring Cloud Kubernetes will lookup a ConfigMap named c3 in namespace n3
         - namespace: n3
           name: c3

In the example above, it spring.cloud.kubernetes.config.namespace had not been set, then the ConfigMap named c1 would be looked up in the namespace that the application runs

Any matching ConfigMap that is found, will be processed as follows:

The single exception to the aforementioned flow is when the ConfigMap contains a single key that indicates the file is a YAML or Properties file. In that case the name of the key does NOT have to be application.yaml or application.properties (it can be anything) and the value of the property will be treated correctly. This features facilitates the use case where the ConfigMap was created using something like:

kubectl create configmap game-config --from-file=/path/to/app-config.yaml

Example:

Let’s assume that we have a Spring Boot application named demo that uses properties to read its thread pool configuration.

This can be externalized to config map in yaml format:

kind: ConfigMap
apiVersion: v1
metadata:
  name: demo
data:
  pool.size.core: 1
  pool.size.max: 16

Individual properties work fine for most cases but sometimes embedded yaml is more convenient. In this case we will use a single property named application.yaml to embed our yaml:

 ```yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: demo
data:
  application.yaml: |-
    pool:
      size:
        core: 1
        max:16
The following also works:

 ```yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: demo
data:
  custom-name.yaml: |-
    pool:
      size:
        core: 1
        max:16

Spring Boot applications can also be configured differently depending on active profiles which will be merged together when the ConfigMap is read. It is possible to provide different property values for different profiles using an application.properties|yaml property, specifying profile-specific values each in their own document (indicated by the --- sequence) as follows:

kind: ConfigMap
apiVersion: v1
metadata:
  name: demo
data:
  application.yml: |-
    greeting:
      message: Say Hello to the World
    farewell:
      message: Say Goodbye
    ---
    spring:
      profiles: development
    greeting:
      message: Say Hello to the Developers
    farewell:
      message: Say Goodbye to the Developers
    ---
    spring:
      profiles: production
    greeting:
      message: Say Hello to the Ops

In the above case, the configuration loaded into your Spring Application with the development profile will be:

  greeting:
    message: Say Hello to the Developers
  farewell:
    message: Say Goodbye to the Developers

whereas if the production profile is active, the configuration will be:

  greeting:
    message: Say Hello to the Ops
  farewell:
    message: Say Goodbye

If both profiles are active, the property which appears last within the configmap will overwrite preceding values.

To tell to Spring Boot which profile should be enabled at bootstrap, a system property can be passed to the Java command launching your Spring Boot application using an env variable that you will define with the OpenShift DeploymentConfig or Kubernetes ReplicationConfig resource file as follows:

apiVersion: v1
kind: DeploymentConfig
spec:
  replicas: 1
  ...
    spec:
      containers:
      - env:
        - name: JAVA_APP_DIR
          value: /deployments
        - name: JAVA_OPTIONS
          value: -Dspring.profiles.active=developer

Notes: - check the security configuration section, to access config maps from inside a pod you need to have the correct Kubernetes service accounts, roles and role bindings.

Table 2.1. Properties:

NameTypeDefaultDescription

spring.cloud.kubernetes.config.enableApi

Boolean

true

Enable/Disable consuming ConfigMaps via APIs

spring.cloud.kubernetes.config.enabled

Boolean

true

Enable Secrets PropertySource

spring.cloud.kubernetes.config.name

String

${spring.application.name}

Sets the name of ConfigMap to lookup

spring.cloud.kubernetes.config.namespace

String

Client namespace

Sets the Kubernetes namespace where to lookup

spring.cloud.kubernetes.config.paths

List

null

Sets the paths where ConfigMaps are mounted