1. Introduction

This post would demo how to deploy dockerized springboot applications into kubernetes, and in the same time, I would demo how to add externalised configration files to the dockerized springboot application.

2. Environments

  • SpringBoot 2
  • Docker 18
  • Kubernetes 17

3. The tutorial

3.1 Add Dockerfile to your Springboot app

FROM openjdk:8-jdk-alpine
MAINTAINER bswen.com
LABEL appName="myserver"
ARG JAR_FILE=target/*-exec.jar #this is the fatjar located at your target folder
ENV APPROOT="/opt/myserver"
COPY ${JAR_FILE} ${APPROOT}/app.jar
WORKDIR ${APPROOT}
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar","-Droot.dir=/opt/myserver","--spring.config.location=/opt/myserver/conf/application.properties"]
EXPOSE 8086

3.2 Add Config Map from your application.propertes file

Use this command to create a Config Map in your kubernetes cluster:

kubectl create configmap myserver-config --from-file application.properties

3.3 Create a deployment in your kubernetes cluster

apiVersion: apps/v1
kind: Deployment
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      workload.user.cattle.io/workloadselector: deployment-default-myserver
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      annotations:
        cattle.io/timestamp: "2020-02-22T12:06:39Z"
      creationTimestamp: null
      labels:
        workload.user.cattle.io/workloadselector: deployment-default-myserver
    spec:
      containers:
      - image: 10.21.1.2:5000/myserver:v1
        imagePullPolicy: Always
        name: myserver
        resources: {}
        securityContext:
          allowPrivilegeEscalation: false
          capabilities: {}
          privileged: false
          readOnlyRootFilesystem: false
          runAsNonRoot: false
        stdin: true
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        tty: true
        volumeMounts:       #mount the volume defined below
        - mountPath: /opt/myserver/conf
          name: vol1
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: "161"
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:      #defines a volume which type is configMap
      - configMap:
          defaultMode: 256
          name: myserver-config
          optional: false
        name: vol1

In the upper yaml file, I defined a ConfigMap Volume named vol1, and mount it at the /opt/myserver/conf, which is used by the Dockerfile’s “–spring.config.location”.

View the k8s status:

[[email protected] ~]# kubectl get deployment
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
myserver     1/1     1            1           2h

Then everything is done.

3. Summary

Deploy springboot into k8s is easy, but if want to externalize the configuration files , you should use ConfigMap instead of adding the config file into the container, which is tightly coupled with the appcodes, ConfigMap can be changed on the fly, without interfering the application development.