Centralized Configuration Spring Application on Kubernetes

Ardiansyah
5 min readNov 4, 2018

A couple months ago, Spring Cloud Kubernetes project has been graduated from the incubation process. The project provides Kubernetes integration with Spring Cloud. For those who are not familiar with Kubernetes, you can look at this article, and this, for introduction, and you can start interactive tutorial here.

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems. [source]

One of the functionalities is integration with the Kubernetes ConfigMap.

In general, spring application configuration is created using files (e.g. properties, yaml). There is no problem with this way, until we have many service instances. Only one value changes, then the configuration should be distributed to all service nodes and… restart the services. Another problem can occur if you deploy the service uses container (e.g. Docker) and you save the configuration file in it, then you have to re-build the container image (I don’t think anyone will do this 😅).

If you don’t deploy the service to Kubernetes, then you can use Spring Cloud Config or using Consul for Distributed Configuration. But… when your service is deployed to a container and with container orchestration (in this case Kubernetes) for its management, it would be nice to try Kubernetes ConfigMap for centralized configuration.

This time, I want to share my experience trying this project, at least as far as I have learned until today.

First of all, you have to install minikube and kubectl so you can run Kubernetes on your local development machine. Next…

Start Minikube

You can start Minikube by just entering minikube start command. Because you run Kubernetes on the local machine, you have to make Kubernetes reusing your Docker daemon by entering eval $(minikube docker-env) command, as this means you don’t have to build a docker registry on your host machine and push the image into it — you can just build inside the same docker daemon as Minikube which speeds up local experiments.

Start minikube

Create ConfigMap

Next, create your configuration using ConfigMap. You can create Kubernetes object spesification definition (including ConfigMap) all in command line (like in interactive tutorial) or create yaml file, and execute kubectl create -f filename command. I prefer to use files because it can be included into version control.

ConfigMap.yaml

Above is an example of a yaml file to create a ConfigMap. Fill data property with the contents of the application.properties that we usually use, and then execute kubectl create -f ConfigMap.yaml command.

get and describe configmap

You can check the list and content of ConfigMap with the command as shown above.

Create Role

Next, create role for the namespace (in this case, default namespace), if not, then the config taken will be null, or if you use other integration such as service discovery, it will receive a forbidden response.

ClusterRoleBinding.yaml

Project Setup

Make sure to add some dependencies to your spring-boot project. I used 2.0.5.RELEASE for the parrent.

  • spring-boot-starter-web
  • spring-boot-starter-actuator
  • spring-cloud-starter-kubernetes-config
  • lombok

if you use maven, see code below…

dependencies

application.properties

Even though all application configurations already exist in the ConfigMap, at least we need configuration for integration with Kubernetes.

application.properties

spring.cloud.kubernetes.reload.* configs are for configuring the ConfigMap auto reload method, and management.endpoint.* are to configure the actuator.

Object Mapping for Configuration in ConfigMap

Actually, you can use the old method with @Value("${myconfig.properties1}") but this cannot be auto-reload. To be able to make it auto-reload, create POJO for mapping content in ConfigMap.

Config.java

and add @Configuration annotation and @ConfigurationProperties(prefix="myconfig") annotation, the prefix here is adjusted to the content in the ConfigMap.

Test the Configuration

To use the configuration, just inject Object from the Class that has been made before, using @Autowired.

TestHTTPService.java

Next, you can try it directly without deploying it to Kubernetes, because Spring Cloud Kubernetes has the Transparency feature.

All of the features described above will work equally well regardless of whether your application is running inside Kubernetes or not.

But, before you run your application, you must have an environment variable named KUBERNETES_NAMESPACE containing the namespace name that you use.

export KUBERNETES_NAMESPACE=default

Test Result

test config

The picture above shows the results of the HTTP API that was created previously to display the config.

Deploy to Kubernetes

First, build your docker image, you can see my story about Dockerize Your Java Application for more detailed step.

build docker image

After your image is ready, then it’s ready to deploy. Next…

Create Controller, i choose Replicaset

ReplicaSet.yaml
create replicaset controller

Create a Service.

Service.yaml
create and describe service

Next, test using Service port.

test result

Full source code is available on my Github page.

Are you looking for any information about remote work?
or have a cool resource about remote work?
remotework.FYI is all you need to know about remote work, find and share cool resources right now.

--

--