All Blogs in the series
|1||Docker Set up by Ronnie André Bjørvik Sletta|
|2||Hello World – Containers|
|3||Container meet Orchestrator|
|6||Secrets and Configurations|
PS:Demo video in the end.
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
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%';
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