App Configuration
(this post is part of the material I cover in my devops course)
Motivation
- In many cases we want to keep configuration data about our applications.
- Examples:
- lodations of servers/services (URLs, domain names, IP addresses)
- directory/file locations on volumes..
- credentials: user names, passwords, toekens etc.
- The idea is to decouple environment-specific configuration from your container images.
That is, keep configuration data and secrets (credentials, tokens etc) in a place other than our pod data.
ConfigMaps
(look here for more details)
- A ConfigMap is an API object that lets you store configuration for other objects to use.
- A ConfigMap has data and binaryData fields.
- These fields accept key-value pairs as their values.
- Both the data field and the binaryData are optional.
- The data field is designed to contain UTF-8 strings
- The binaryData field is designed to contain binary data as base64-encoded strings.
- The name of a ConfigMap must be a valid DNS subdomain name.
- Pods an consume ConfigMaps in the following ways:
- as environment variables
- as command-line arguments
- as configuration files in a volume
- Here's an example of a ConfigMap:
1apiVersion: v1
2kind: ConfigMap
3metadata:
4 name: my-configmap
5data:
6 key1: value1
7 key2: value2
8 key3: |
9 key31:
10 - key311: value3
11 - key312: value4
12 key4: |
13 multi line
14 data can be used
15 based on yaml syntax
16binaryData:
17 binkey1: aGVsbG8gd29ybGQK
(note the yaml pipe bars are just multiline strings, so there is really no hierarchy of key-value pairs)
Secrets
- Simmilar ideas refer to Secrets.
- Here's an example of a secret:
1apiVersion: v1
2kind: Secret
3metadata:
4 name: my-secret
5data:
6 pass: bXlwYXNzd29yZAo=
- Note that the value of pass is just the string mypassword viewd in Base64 encoding:
1$>
2$> echo mypassword | base64
3bXlwYXNzd29yZAo=
4$>
Use ConfigMap and Secret as environment variable
- Here's a pods configuration, that maps values from ConfigMap and Secret as environment variables:
1apiVersion: v1
2kind: Pod
3metadata:
4 name: envvar-pod
5spec:
6 containers:
7 - name: busybox
8 image: busybox:latest
9 command:
10 - sleep
11 - "3600"
12 ports:
13 - containerPort: 80
14 env:
15 - name: CONFIGMAP_VAR
16 valueFrom:
17 configMapKeyRef:
18 name: my-configmap
19 key: key2
20 - name: SECRET_VAR
21 valueFrom:
22 secretKeyRef:
23 name: my-secret
24 key: pass
- Now, apply everything and use the environment variables:
1$>
2$> kubectl apply -f my-configmap.yaml
3configmap/my-configmap created
4$> kubectl apply -f my-secret.yaml
5secret/my-secret created
6$> kubectl apply -f envvar-pod.yaml
7pod/envvar-pod created
8$> kubectl get pods
9NAME READY STATUS RESTARTS AGE
10envvar-pod 0/1 ContainerCreating 0 4s
11$> kubectl exec -it envvar-pod -- sh
12/ #
13/ # echo $CONFIGMAP_VAR
14value2
15/ # echo $SECRET_VAR
16mypassword
17/ #
Use the configmap and secret as volumes
- Here's a pod definition that uses ConfigMap and Secret values as file in volumes:
1apiVersion: v1
2kind: Pod
3metadata:
4 name: volume-pod
5spec:
6 containers:
7 - name: busybox
8 image: busybox:latest
9 command: ["sleep", "3600"]
10 volumeMounts:
11 - name: configmap-volume
12 mountPath: /etc/config/configmap
13 - name: secret-volume
14 mountPath: /etc/config/secret
15 volumes:
16 - name: configmap-volume
17 configMap:
18 name: my-configmap
19 - name: secret-volume
20 secret:
21 secretName: my-secret
- Let's use this definition:
1$>
2$> kubectl apply -f volume-pod.yaml
3pod/volume-pod created
4$> kubectl get pods
5NAME READY STATUS RESTARTS AGE
6envvar-pod 1/1 Running 0 4m31s
7volume-pod 0/1 ContainerCreating 0 4s
8$> kubectl exec -it volume-pod -- sh
9/ #
10/ # cat /etc/config/configmap/key1
11value1/ #
12/ #
13/ # cat /etc/config/secret/pass
14mypassword
15/ #