Kubernetes ConfigMap Configuration and Reload Strategy

Eresh Gorantla
Dec 20, 2019 · 6 min read

This story focuses on ConfigMap resource and its usage in pods over Kubernetes container and reload strategy in application real-time.

Please go through my earlier story for Minikube installation and deploying the sample application in Kubernetes runtime in Minikube.

Why ConfigMap?

Many applications require configuration via some combination of config files, command line arguments, and environment variables. These configuration artifacts should be decoupled from image content in order to keep containerized applications portable. The ConfigMap API resource provides mechanisms to inject containers with configuration data while keeping containers agnostic of Kubernetes. ConfigMap can be used to store fine-grained information like individual properties or coarse-grained information like entire config files or JSON blobs.

This seperates the tight coupling between application and configuration properties under same package. The ConfigMap residing at container and available for the application at runtime when deployed in pod.

The ConfigMap API resource holds key-value pairs of configuration data that can be consumed in pods or used to store configuration data for system components such as controllers. ConfigMap is similar to Secrets, but designed to more conveniently support working with strings that do not contain sensitive information.

Note: ConfigMaps are not intended to act as a replacement for a properties file. ConfigMaps are intended to act as a reference to multiple properties files. You can think of them as way to represent something similar to the /etc directory, and the files within, on a Linux computer.

Example of ConfigMap

ConfigMap Example
  • kind:- The kind is ConfigMap
  • metadata:- It holds the improtant information line ConfigMap name, namespace and others. This data is mapped in Pod or deployment config.
  • data:- This field contains the configuration data. As you can see, ConfigMaps can be used to hold fine-grained information like individual properties or coarse-grained information like the contents of configuration files.

Create ConfigMap:

ConfigMaps can be created from directories, files and literal values. Here we will apply config in our sample applcation.

ConfigMap Creation
  • Maven dependencies :- Spring Boot latest version is used.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
  • bootstrap.yml :- In spring cloud applications, few of the config properties should be known to kubernetes runtime before deployment actually starts.
spring:
cloud:
kubernetes:
config:
enabled: true
sources:
- namespace: default
name: minikube-sample
management:
endpoint:
restart:
enabled: true

sources :- name is minikube-sample which is configmap mapping.

  • RestController:- properties are loaded in application for @ConfigurationProperties.
@RestController
@RequestMapping("/home")
public class HomeResource {

@Autowired
PropertiesConfig config;

@GetMapping("/data")
public ResponseEntity<ResponseData> getData() {
ResponseData responseData = new ResponseData();
responseData.setId(1);
responseData.setName(config.getName());
responseData.setPlace("Hyderabad");
responseData.setValue(config.getTest());
return new ResponseEntity<>(responseData, HttpStatus.OK);
}

@Getter
@Setter
public class ResponseData {
private String name;
private Integer id;
private String place;
private String value;
}
}

The name and value are set from config properties.

  • deployment.yaml :- Service kind as NodePort dedicated to a port number. ConfigMaps are mappedn through volume mounts. The Service and deployments binds to application from metadata : name.
  • ConfigMaps are maped to this pod from volumes and volumeMounts. ie., by name. Here in this example the value is “config”.
kind: Service
apiVersion: v1
metadata:
name: minikube-sample
spec:
selector:
app: minikube-sample
ports:
- protocol: TCP
port: 8080
nodePort: 30083
type: NodePort

---

apiVersion: apps/v1
kind: Deployment
metadata:
name: minikube-sample
namespace: default
spec:
selector:
matchLabels:
app: minikube-sample

replicas: 1
template:
metadata:
labels:
app: minikube-sample
spec:
containers:
- name: minikube-sample
image: minikube-sample:latest
imagePullPolicy: Never
ports:
- containerPort: 8080
env:
- name: env.namespace
value: default
volumeMounts:
- name: config
mountPath: /config
volumes:
- name: config
configMap:
name: minikube-sample

Deploy the application in to Kubernetes. Please see the steps from console

Now go to browser and test Rest API endpoint

RestAPI Response

The name and value above is picked from ConfigMap.

ConfigMap Reload Feature

Some applications may need to detect changes on external property sources and update their internal status to reflect the new configuration. The reload feature of Spring Cloud Kubernetes is able to trigger an application reload when a related ConfigMap or Secret changes.

This feature is disabled by default and can be enabled using the configuration property spring.cloud.kubernetes.reload.enabled=true (eg. in the application.properties/yml file).

The following levels of reload are supported (property spring.cloud.kubernetes.reload.strategy): - refresh (default): only configuration beans annotated with @ConfigurationProperties or @RefreshScope are reloaded. This reload level leverages the refresh feature of Spring Cloud Context. - restart_context: the whole Spring ApplicationContext is gracefully restarted. Beans are recreated with the new configuration. - shutdown: the Spring ApplicationContext is shut down to activate a restart of the container. When using this level, make sure that the lifecycle of all non-daemon threads is bound to the ApplicationContext and that a replication controller or replica set is configured to restart the pod.

For more details please visit here.

Now Let’s rework on same sample spring-boot application to make reloadable at run time without restarting the application.

To make it work we have to add restart enable and other configurations in bootstrap.yml

Lets rebuild the application with earlier steps like clean build and create docker image (For some reasons docker of windows version is not working properly in my laptop. So I am using minikube docker.)

Lets test Rest API Endpoint

Lets change configMap property values while the application is in running state.

Lets pull the logs

Observe the lines from highlighted to the end of it. When we changes the configMap manually, Kubernetes detected the change and reloaded the spring context gracefully.

Let’s hit again the Rest API endpoint. You will see the updated values.

Important things to keep in mind:

The view role on the service account is required in order to listen for config map changes.

kubectl create clusterrolebinding <view-name> --clusterrole=view --serviceaccount=<namespace>:default --namespace=<namespace>

The following levels of reload are supported (property spring.cloud.kubernetes.reload.strategy): - refresh (default): only configuration beans annotated with @ConfigurationProperties or @RefreshScope are reloaded. This reload level leverages the refresh feature of Spring Cloud Context. - restart_context: the whole Spring ApplicationContext is gracefully restarted. Beans are recreated with the new configuration. - shutdown: the Spring ApplicationContext is shut down to activate a restart of the container. When using this level, make sure that the lifecycle of all non-daemon threads is bound to the ApplicationContext and that a replication controller or replica set is configured to restart the pod.

The Startup

Get smarter at building your thing. Join The Startup’s +788K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Eresh Gorantla

Written by

Experience in Open source development, Technical Leader. Expert in Java/J2EE, Integration, analytics. Loves Cricket, cooking, movies and travelling.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +788K followers.

Eresh Gorantla

Written by

Experience in Open source development, Technical Leader. Expert in Java/J2EE, Integration, analytics. Loves Cricket, cooking, movies and travelling.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +788K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface.

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox.

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic.

Get the Medium app