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.yaml
application.properties
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.
pool.size.core
pool.size.maximum
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:
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 |