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:
yaml the content of any property named application.yamlapplication.propertiesThe 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.
pool.size.corepool.size.maximumThis 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:16The following also works:
```yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
custom-name.yaml: |-
pool:
size:
core: 1
max:16Spring 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:
| Name | Type | Default | Description |
|---|---|---|---|
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 |