Dockerizing Spring boot application for Kubernetes Deployment

3/29/2018

I have a spring boot application with some properties as below in my application.properties.

server.ssl.keyStore=/users/admin/certs/appcert.jks
server.ssl.keyStorePassword=certpwd
server.ssl.trustStore=/users/admin/certs/cacerts
server.ssl.trustStorePassword=trustpwd

Here the cert paths are hardcoded to some path. But, I dont want to hard code this as the path will not be known in Mesos or Kubernetes world.

I have a docker file as follows.

FROM docker.com/base/jdk1.8:latest

MAINTAINER Application Engineering [ https://docker.com/ ]

RUN mkdir -p /opt/docker/svc

COPY application/weather-service.war /opt/docker/svc/

CMD java -jar /opt/docker/svc/weather-service.war --spring.config.location=file:/conf/application.properties -Dlogging.config=/conf/logback.xml

Here, I can use the volume mount option in kubernetes so as to place the application.proerties.

How can i achieve the same thing for cert files in the application.properties?

Here, the cert props are optional for few applications and mandatory for few applications.

I need options to integrate within the docker images and having the cert files outside the docker image.

Approach 1. Within the docker image

Remove the property "server.ssl.keyStore" from application.properties and pass it as a environment variable like the below one.

CMD java -jar /opt/docker/svc/weather-service.war --spring.config.location=file:/conf/application.properties -Dlogging.config=/conf/logback.xml -Dserver.ssl.keyStore=/certs/appcert.jks

Now, the cert should be places in secrets and use the volume mount options with kubernetes.

Approach 2. No need to have -Dserver.ssl.keyStore=/certs/appcert.jks in the docker file, but still remove the property "server.ssl.keyStore" from application.properties and do as follows.

a. Create secret

kubectl create secret generic svc-truststore-cert --from-file=./cacerts

b. Create one env variable as below.

{ "name": "JAVA_OPTS", "value": "-Dserver.ssl.trustStore=/certs/truststore/cacerts" }

c. Create Volume mounts under container for pod.

"volumeMounts": [ { "name": "truststore-cert", "mountPath": "/certs/truststore" } ]

d. Create a volume under spec.

{ "name": "truststore-cert", "secret": { "secretName": "svc-truststore-cert", "items": [ { "key": "cacerts", "path": "cacerts" } ] } }

Approach 3.

Using Kubernetes Persistent Volume.

Created a persistent volume on Kubernetes .

Mount the volume to the Pod of each microservice (changes in the pod script file). Mounted file system accessible via - '/shared/folder/certs' path.

CMD java -jar /opt/docker/svc/weather-service.war --spring.config.location=file:/conf/application.properties -Dlogging.config=/conf/logback.xml -Dserver.ssl.keyStore=/certs/appcert.jks

I have taken the second approach. Is this correct? Is there any other better approach?

Thanks

-- user1578872
docker
kubernetes
spring-boot

1 Answer

4/13/2018

Yes, the second approach is the best one, and it is the only way if you are storing some sensitive data like certificates, keys, etc. That topic is covered in the documentation.

Moreover, you can encrypt your secrets to add another level of protection.

-- Anton Kostenko
Source: StackOverflow