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/ #