Technical Articles
#HelloWorld SAPUI5 meets Kubernetes – Secrets & Configurations
All Blogs in the series
Part | Description |
1 | Docker Set up by Ronnie André Bjørvik Sletta |
2 | Hello World – Containers |
3 | Container meet Orchestrator |
4 | Database integration |
5 | Persistence Storage |
6 | Secrets and Configurations |
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
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
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