application configuration for java apps in kubernetes

11/6/2017

I'm new to java and k8, and I have some doubts about how to handle application configurations for my java apps. I've got one spring boot app and the other three use wildfly.

So, they all got hardcoded application configurations, and when starting them the just use something like:

java -Dswarm.project.stage=development -jar foobar/target/foobar-swarm.jar

except for the spring boot which has an application.properties file that consists of application configuration data.

So basically the three java apps have backed in two files (which I know is a no no):

 - project-stages.yml
 - standalone.xml

And when the developer wants to deploy to production he uses:

  java -Dswarm.project.stage=production -jar foobar/target/foobar-swarm.jar

And, now we come to kubernetes which has three ways of dealing with application configuration data:

1.) Env variables

2.) Config maps

3.) Secrets

I was thinking of using configmaps instead of env variables because they have more benefits.

So, the developer gave me the possibility of overwriting those hardcoded variables with an external file : Dsystem.properties.file=/var/foobar/environment.properties

But I'm still overwriting an hardcoded files with an external file, and I'm not happy with that solution!

So, I'm basically looking on advise can those hardcoded files be supplied externally and populated with configmaps in k8 - what would be the best practice of handling the config files in the world of k8?

Tnx, Tom

-- Tomislav Mikulin
configuration
docker
java
kubernetes

2 Answers

11/6/2017

There are several questions in the post, but I can address only the one related to spring-boot.

The simplest and the most convenient way of specifying configurations to spring boot app is via its built in profiling feature. As you already mentioned you have application.properties. You can create similar files according to your usage cases: application-production.properties, application-staging.properties, application-k8s.properties, etc. Kubernetes deployment doesn't change this in any way. You can control which configuration to pick by setting SPRING_PROFILES_ACTIVE env variable from the kubernetes.

You might have something like this:

docker run -e SPRING_PROFILES_ACTIVE=k8s -d -p 0.0.0.0:8080:8080 \
    --name=yourapp your_image_name bash -c "java -jar yourapp.jar"

It will pick configuration from application-k8s.properties.

Configuration files support environment variables as well. You can have placeholders like ${YOUR_DB} in your properties files and Spring will automatically pick up env variable with name YOUR_DB. It is convenient to use this feature let's say when your app pod must have its own db pod.

-- Sasha Shpota
Source: StackOverflow

12/19/2017

If I got your question right you are asking how to configure a Spring Boot application via a k8s ConfigMap. Yes, you can do that.

  1. Create a Docker image with WORKDIR work_dir in which you start the Spring Boot application eg via java -jar /work_dir/app.jar
  2. Create a ConfigMap
  3. Run a container of the above mentioned image within k8s
  4. Mount the ConfigMap for the Spring Boot application.properties into the Container as /work_dir/config/application.properties
  5. On changes in the ConfigMap the file within the container gets updated. You have to restart the Spring Boot Application to set your changes active.
-- Hubert Ströbitzer
Source: StackOverflow