Architektur

Editing a Kubernetes Configmap with Java

Nicolas Fonnegra
Nicolas Fonnegra

I know that title of this blog entry can be very misleading and maybe this is not what you are looking for. The original title was going to be something like “Editing a Kubernetes Configmap at runtime with Java, inside a Springboot Pod in Openshift using the REST API”, but WordPress was complaining too much about its length so I decided to keep it short. In short, this blog shows how you can change the values of a ConfigMap at runtime from inside a Springboot POD running in Openshift. Lets get started!

Step one: create the map

No map no fun. So we are going to create a simple map named “simplemap”. It will only contain one key and one value and will look like this:

The key will be called “simplemap.properties” and the starting value will be “execution=1”. The Springboot project is going to edit this value and set a random execution number.

Step two: assign the required role

PODs define different kind of users: default, builder and deployer. The default user is the one who is going to run the Sprinboot application and the one who needs permission to change the map. Therefore we need to use this command to assign the edit role to the default user:

Step three: define the deployment descriptor

This is the trickiest part of all. The POD running the Springboot application will create automatically SSL certificates that you can use to call the Kubernetes API. If you log in to your POD’s terminal, you can use that certificate with ‘curl’ to invoke the API. Unfortunately it isn’t that easy with Java invocations because it needs a truststore with the certificate inside rather than the single certificate.

Since the POD doesn’t contain the truststore, it will have to be created when the POD is generated. The best way to do this is by defining an ‘init-container’ that builds the truststore and stores it in a volume that can be referenced by the main container. This Blogpost shows how to define the init-containers.

Unfortunately, init-container did not seem to be working on the openshift version I am using (openshift v3.6.173, kubernetes v1.6.1). Therefore I had to define a postStart lifecycle hook and create the truststore with it. I would recommend you to prefer init-containers, because kubernetes cannot guarantee that the post-start will run before the container is started.

The deployment file looks like this:

Step four: Call The API

Before building the Springboot application, lets take a look at the API call. The URL is quite straightforward: https://HOST:PORT/api/v1/namespaces/myproject/configmaps/simplemap. You need the address and port of your cluster, the name of the project where the map is installed and the name of the map. The request is a normal JSON object and is sent using PUT:

The other component needed for the API call is the default user’s credentials. The credentials are store in form of a token right next to the truststore under ‘/var/run/secrets/kubernetes.io/serviceaccount/token’. You can read this token as you would red a normal file with Java:

The token will be sent as a the ‘Authorization’ HTTP-Header using following format:

Authorization: Bearer <put your token here>

After that, the API call is pretty straightforward using Springboot:

Once the image is the deployed, you can see that the value has been changed.

Summary

In this blog you can see how to change the values of a kubernetes config map with Java using the provided REST API. But before the API can be consumed, a truststore has to be created using the certificates provideded by kubernetes. The API also expects the user credentials which can be found in the token file also provided by kubernetes. With those two key elements, a REST request can be made against the cluster, changing the keys and values of the map or even its whole structure.