Kubernetes – ConfigMaps
February 20, 2019Sometimes you need to add additional configurations to your running containers. Kubernetes has an object to help with this and this post will cover those ConfigMaps.
ConfigMaps – The Theory
Not all of our applications can be as simple as the basic nginx containers we’ve deployed earlier in this series. In some cases, we need to pass configuration files, variables, or other information to our apps.
The theory for this post is pretty simple, ConfigMaps store key/value pair information in an object that can be retrieved by your containers. This configuration data can make your applications more portable.
For example, you could have a key value pair of “environment:dev” in a configmap for your development Kubernetes cluster. When you deploy your apps, you can key some of your logic off of the “environment” variable and do different things for production vs. development environments. I’m not sure this is necessary, but it’s just an example to get you thinking about it. Let’s see these ConfigMaps in action and I think you’ll get the picture.
ConfigMaps – In Action
For a ConfigMap example, we’ll take a simple two tier app (lovingly called hollowapp) and we’ll configure the database connection string through a ConfigMap object. Try to put out of your mind how insecure this is for the moment, it’s just an example to prove the point.
Here is a high level diagram of the lab we’ll be building. As you can see some of the items we’ve talked about in previous posts have been generalized. The main part is the App container using the ConfigMap to configure the connection string to the database service.
First, we’ll deploy the database container and service. The database container has already been configured with new database with the appropriate username and password. The manifest file to deploy the DB and service is listed below.
apiVersion: apps/v1
kind: Deployment
metadata:
name: hollowdb
labels:
app: hollowdb
spec:
replicas: 1
selector:
matchLabels:
app: hollowdb
template:
metadata:
labels:
app: hollowdb
spec:
containers:
- name: mysql
image: theithollow/hollowapp-blog:dbv1
imagePullPolicy: Always
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: hollowdb
spec:
ports:
- name: mysql
port: 3306
targetPort: 3306
protocol: TCP
selector:
app: hollowdb
To deploy the manifests, we run our familiar command:
kubectl apply -f [manifest file].yml
Code language: CSS (css)
OK, the Database is deployed and ready to go. Now we need to deploy a ConfigMap with the database connection string.
The ConfigMap is listed below in another manifest file. Most of the configuration in the manifest should look familiar to you. The kind has been updated to a type of “ConfigMap”, but the important part is the data field. We have a key named. db.string and the value of that key is our connection string (yes, with the clear text super secret password).
apiVersion: v1
kind: ConfigMap
metadata:
name: hollow-config
data:
db.string: "mysql+pymysql://hollowapp:Password123@hollowdb:3306/hollowapp" #Key Value pair Value being a database connection string
Code language: PHP (php)
Deploy the ConfigMap using the same apply command as before and change the manifest file name.
kubectl apply -f [manifest file].yml
Code language: CSS (css)
Now you can run a get command to list the ConfigMap.
kubectl get configmap
Code language: JavaScript (javascript)
Now, before we deploy our app, lets deploy a test container to prove that we can read that key value pair from the ConfigMap.
The manifest below has an environment variable named DATABASE_URL and we’re telling it to get the value of that environment variable from the ConfigMap named hollow-config. Within the hollow-config ConfigMap, we’re looking for the key named db.string. The result that will be the value stored in our DATABASE_URL variable.
apiVersion: v1
kind: Pod
metadata:
name: shell-demo
spec:
containers:
- name: nginx
image: nginx
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: hollow-config
key: db.string
Code language: CSS (css)
Deploy the test shell-demo container with the kubectl apply command.
kubectl apply -f [manifest file].yml
Code language: CSS (css)
Once it’s deployed, you can get an interactive shell into that container by running the following command.
kubectl exec -it shell-demo -- /bin/bash
Code language: JavaScript (javascript)
Once we have a shell session, we can do an echo on our DATABASE_URL environment variable and it should show the string from our ConfigMap.
You can exit the shell session and then we’re ready to deploy our app. The manifest for the app is shown below. NOTE: it does require that you have your ingress controller running if you plan to access it through a browser.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: hollowapp
name: hollowapp
spec:
replicas: 3
selector:
matchLabels:
app: hollowapp
strategy:
type: Recreate
template:
metadata:
labels:
app: hollowapp
spec:
containers:
- name: hollowapp
image: eshanks16/k8s-hollowapp:v2
imagePullPolicy: Always
ports:
- containerPort: 5000
env:
- name: SECRET_KEY
value: "my-secret-key"
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: hollow-config
key: db.string
---
apiVersion: v1
kind: Service
metadata:
name: hollowapp
labels:
app: hollowapp
spec:
type: ClusterIP
ports:
- port: 5000
protocol: TCP
targetPort: 5000
selector:
app: hollowapp
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: hollowapp
labels:
app: hollowapp
spec:
rules:
- host: hollowapp.hollow.local
http:
paths:
- path: /
backend:
serviceName: hollowapp
servicePort: 5000
Code language: PHP (php)
Deploy the app with the same command.
kubectl apply -f [manifest file].yml
Code language: CSS (css)
The result is that our app is communicating correctly with our back end database container all because of our ConfigMap.
Summary
So this isn’t the most secure way to pass connection information to your containers, but it is a pretty effective way of storing parameters that you might need for your applications. What will you think of to use ConfigMaps for?
[…] 11. ConfigMaps […]
Hi Eric, thanks for the amazing tutorial. Always clear and concise. I wanted to ask you how to access the site http://hollowapp.hollow.local as I get “We can’t connect to the server at hollowapp.hollow.local.” all resources are up and running
hollowapp.hollow.local is a dns name I’ve added in my lab. To access this by name add this record with a matching IP address to your dns server or hosts file.