Friday, July 9, 2021

Kubernetes for Developers #18: Manage app settings using Kubernetes ConfigMap

In general, we use configuration files (i.e. web.config and .rc ) or environment files (.env) for separating application settings from the code. The same application settings can be implemented using Kubernetes ConfigMap Object in the K8 world.
  • It stores data as key-value pair.
  • It helps us to separate application environment specific configurations from the code.
  • Each Pod uses ConfigMap values as environment variables, volumes or command-line arguments.
  • Key name must contain alphanumeric, dash (-), underscore (_) and dot(.) only
  •  It is not suitable for storing confidential data.

Create ConfigMap

There are multiple ways to create K8 ConfigMap object
  1. from YAML file
apiVersionv1
kindConfigMap
metadata:
  nameconfigmap-db
data:
  db_host"mydb.rds.amazonaws.com"
  db_port"3306"
  db_name"testuser"


Here, we should specify key-value pair as data property in the K8 ConfigMap object

Save above yaml content as "configmapdb.yaml" and run following kubectl command
// create configmap object from yaml file
$ kubectl apply -f configmapdb.yaml
configmap/configmap-db created

// display all configmap objects
$ kubectl get configmap
NAME             DATA   AGE
configmap-db     3      2m


// view configmap object details using describe command
$ kubectl describe configmap configmap-db

// view configmap object details as yaml file 
$ kubectl get configmap configmap-db -o yaml

    2. from literals        
        In this approach, we pass key-value pair as part of kubectl command directly.

// create configmap object from literals

// syntax
kubectl create configmap <configmap-name> --from-literal=<key_name>=<key_value>

$ kubectl create configmap configmap-ui --from-literal=app_name=mytestapp --from-literal=app_theme=bluetheme
configmap/configmap-ui created


// display all configmap objects
$ kubectl get configmap
NAME             DATA   AGE
configmap-db     3      134m
configmap-ui     2      19s

// view configmap object details using describe command
$ kubectl describe configmap configmap-ui

// view configmap object details as yaml file 
$ kubectl get configmap configmap-ui -o yaml

    3. from an env-file   
        In this approach, we create an env file with list of environment variables and values

db_host=mydb.rds.amazonaws.com
db_port=3306
db_name=testuser

save above content as "configmap-db-env.txt" or "configmap-db-env.properties"  and run following kubectl command

// create configmap object from env file
$ kubectl create configmap configmap-db-env --from-env-file=configmap-db-env.txt
configmap-db-env created

// display all configmap objects
$ kubectl get configmap
NAME               DATA   AGE
configmap-db       3      153m
configmap-db-env   3      6s
configmap-ui       2      18m

// view configmap object details using describe command
$ kubectl describe configmap configmap-db-env

// view configmap object details as yaml file 
$ kubectl get configmap configmap-db-env -o yaml

Passing ConfigMap values to Pod

    1. passing ConfigMap values to container environment variables

       In the below example, we are setting Pod container individual environment variables from “configmap-db” object

apiVersionv1
kindPod
metadata:
  nameconfigmap-pod
spec:
  containers:
    - namebusybox
      imagek8s.gcr.io/busybox
      command: ["/bin/sh""-c""env"]
      env:
        - nameDATABASE_PORT
          value"3306"
        - nameDATABASE_HOST
          valueFrom:
            configMapKeyRef:
              nameconfigmap-db
              keydb_host
        - nameDATABASE_NAME
          valueFrom:
            configMapKeyRef:
              nameconfigmap-db
              keydb_name

 
save above yaml content as "configmap-pod-valuefrom.yaml" and run following kubectl command
// create busybox Pod 
$ kubectl apply -f configmap-pod-valuefrom.yaml
pod/configmap-pod created

// check environment values from busybox Pod
$ kubectl logs pod/configmap-pod | grep DATABASE
DATABASE_PORT=3306
DATABASE_NAME=testuser
DATABASE_HOST=mydb.rds.amazonaws.com

    2. passing complete ConfigMap Object as environment variables to the container

       In the below example, we are passing all "configmap-db" object key-value pairs as container environment variables.

apiVersionv1
kindPod
metadata:
  nameconfigmap-pod-env
spec:
  containers:
    - namebusybox
      imagek8s.gcr.io/busybox
      command: ["/bin/sh""-c""env"]
      envFrom:
        - configMapRef:
            nameconfigmap-db

save above yaml content as "configmap-pod-envfrom.yaml" and run following kubectl command
// create busybox Pod 
$ kubectl apply -f configmap-pod-envfrom.yaml
pod/configmap-pod-env created

// check environment values from busybox Pod
$ kubectl logs pod/configmap-pod-env | grep db
db_port=3306
db_name=testuser
db_host=mydb.rds.amazonaws.com


 3. passing ConfigMap defined environment variables as container command arguments

       In the below example, we are passing environment variables as container command arguments with $(environment_variable) syntax

apiVersionv1
kindPod
metadata:
  nameconfigmap-pod-command
spec:
  containers:
    - namebusybox
      imagek8s.gcr.io/busybox
      command:
        [
          "/bin/echo",
          "dbhostname:  $(DATABASE_HOST) and dbport:  $(DATABASE_PORT)",
        ]
      env:
        - nameDATABASE_HOST
          valueFrom:
            configMapKeyRef:
              nameconfigmap-db
              keydb_host
        - nameDATABASE_PORT
          valueFrom:
            configMapKeyRef:
              nameconfigmap-db
              keydb_port


save above yaml content as "configmap-pod-command.yaml" and run following kubectl command
// create busybox Pod 
$ kubectl apply -f configmap-pod-command.yaml
pod/configmap-pod-command created

// check logs from busybox Pod
$ kubectl logs pod/configmap-pod-command
dbhostname:  mydb.rds.amazonaws.com and dbport:  3306

 4. Attaching ConfigMap as container volume

       In the below example, 
  •  we are first creating volumes by setting configMap name property as "configmap-db"
  • we are accessing this volume by setting volumeMounts property
apiVersionv1
kindPod
metadata:
  nameconfigmap-pod-volume
spec:
  containers:
    - namebusybox
      imagek8s.gcr.io/busybox
      command: ["/bin/sh""-c""ls /etc/configmap/"]
      volumeMounts:
        - nameconfigmap-volume
          mountPath/etc/configmap
  volumes:
    - nameconfigmap-volume
      configMap:
        nameconfigmap-db

save above yaml content as "configmap-pod-volume.yaml" and run following kubectl command
// create busybox Pod 
$ kubectl apply -f configmap-pod-volume.yaml
pod/configmap-pod-volume created

// check logs from busybox Pod
$ kubectl logs pod/configmap-pod-volume
db_host
db_name
db_port

Kubernetes for Developers Journey.

Happy Coding :)


No comments:

Post a Comment