Skip to Content
Technical Articles

#HelloWorld SAPUI5 meets Kubernetes – Secrets & Configurations

All Blogs in the series

PS:Demo video in the end.

Background

In our previous blog we have managed to persist our database using Persistent Volume claim method. If you look at the deployment of the MySQL pod it is using some secrets for defining the passwords rather than hard coding in the deployment. Hard Coding passwords or some other configuration variables such as logging  in the deployment file is very risky. In the past many a times such sensitive details have been leaked publicly leading losses. So what Kubernetes does is provide us an option to store the secrets and configuration variables separately outside the application, we will cover those in this blog. This is more on similar line of how we maintain configurations in SAP or avoid hard coding.

How do we manage Configurations in declaring our yaml spec?

Lets first understand how do we keep configurations separate from our deployment file. K8s provides us with ConfigMaps service type to store the different configuration variables. A sample ConfiMap files looks like below. As can be seen the time of declaration is ConfigMap and Data contains the configuration values in this case log_level as INFO more like a JSON like.

apiVersion: v1
kind: ConfigMap
metadata:
 name: env-config
 namespace: default
data:
 log_level: INFO

Source

The configmap can also refer to a separate file also rather specifying everything in a yaml file. We can directly create it from existing configuration file using below command. In the below command the config name is game-config-2 and path of the file is provided.

kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/kubectl/game.properties

Source

We have different ways of creating the conifgmap file for more details refer this. Now we know how to make a conifigmap file but how do we use it inside our deployment. It is very simple as can be seen below by using configMapKeyRef we pass name of config and then value. Hold on we will see how we use it in our MySQL deployment:)

apiVersion: v1
kind: Pod
metadata:
 name: dapi-test-pod
spec:
 containers:
   - name: test-container
     image: k8s.gcr.io/busybox
     command: [ "/bin/sh", "-c", "env" ]
     env:
       # Define the environment variable
       - name: SPECIAL_LEVEL_KEY
         valueFrom:
           configMapKeyRef:
             # The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY
             name: special-config
             # Specify the key associated with the value
             key: special.how
 restartPolicy: Never

Now we understand how do we handle configurations but in the our MySQL deployment we have used secrets what are those? Read on!

How are secrets handled?

Secrets are more like Configmaps but they contain sensitive data like passwords, keys etc. They actually reduce the risk of exposing the sensitive data via Yaml files. So how do we create a secret, they are also one of the object type.  They are stored with base64 encoding in the master node.

We can create a secret from the file also or directly passing the key value pair.

$ kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret "db-user-pass" created

So now we understand what are configmaps and secrets let’s try to utilize them in our deployment.

Let’s make a deployment using Configuration and Secrets

In this demo we are trying to use secrets for the MySQL root password and ConfigMaps for setting the MySQL default character set. First lets create a secret for our mysql root password

kubectl create secret generic mysqlsecret --from-literal=password=pass1234

Then create the configmap for the character set, rather than hard coding in the deployment file.

apiVersion: v1
kind: ConfigMap
metadata:
  name: sqlconfigmap
  namespace: default
data:
  charset: --character-set-server=utf8mb4
  ci: --collation-server=utf8mb4_unicode_ci

Our Deployment file with use of configmaps and secrets

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - image: mysql:5.6
          name: mysql
          args:
            - $(CHARSET) #variables
            - $(CI)
          env:
            - name: MYSQL_ROOT_PASSWORD #secret
              valueFrom:
                secretKeyRef:
                  name: mysqlsecret
                  key: password
            - name: CHARSET # environment variables
              valueFrom:
                configMapKeyRef:
                  name: sqlconfigmap
                  key: charset
            - name: CI
              valueFrom:
                configMapKeyRef:
                  name: sqlconfigmap
                  key: ci       
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts:
            - name: mysql-persistent-storage
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql-persistent-storage
          persistentVolumeClaim:
            claimName: mysql-volumeclaim

Service File

apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  type: ClusterIP
  ports:
    - port: 3306
  selector:
    app: mysql

Command to login to the create MySQL pod to check the default character set

kubectl exec  -ti <pod id> -- mysql --user=root --password=pass1234
SHOW VARIABLES LIKE 'char%';

Demo

What is next?

So far we understand how to create pod with persistent database and use configmaps/secrets. Next we will explore in the direction of Scaling, upgrades RBAC etc. It is like the more you learn the more is still left to be learnt. Feel free to provide your feedback

Be the first to leave a comment
You must be Logged on to comment or reply to a post.