Desacoplar la configuración de tus pods en Kubernetes con ConfigMaps

Siempre es buena práctica desacoplar ciertos parámetros de la configuración de una aplicación que pueden ser susceptibles a cambios entre entornos, regiones, etcétera. Ayer estuvimos viendo cómo trabajar con secretos para desacoplar credenciales, tokens, información sensible en general y hoy le toca el turno a los configmaps. La diferencia fundamental entre los secretos y los configmaps es que estos primeros almacenan la información en base 64 mientras que los segundos lo hacen en texto plano. En este artículo te cuento cómo usarlos para datos menos sensibles.

Crear un ConfigMap

Como en el resto de objetos, existen diferentes formas de crear ConfigMaps en tu clúster, pero el resultado es el mismo. En este artículo vamos a crear uno a través de la linea de comandos con literales:

#Create a configmap from literals
kubectl create configmap postgres-config --from-literal=dbName=mydb --from-literal=encoding="--encoding==SQL_ASCII"

Siguiendo con el ejemplo de postgres que hemos visto en artículos anteriores, he creado un configmap que almacena el nombre de la base de datos que quiero tener creada inicialmente y el encoding que, por defecto es UTF-8, lo cambio a SQL_ASCII a modo de ejemplo. De esta manera desacoplo esta configuración del pod. Al ejecutar el comando anterior crearé un nuevo objeto del tipo ConfigMap. Puedo listar todos los existentes a través del siguiente comando:

#List all configmaps
kubectl get configmaps

Para ver las claves incluidas dentro de un configmap en concreto puedes utilizar este otro comando:

#See keys of a configmap
kubectl get configmaps postgres-config -o yaml

que tendrá una salida parecida a la siguiente:

kubectl get configmaps postgres-config -o yaml

También puedes verlos en el apartado Config Maps del dashboard de Kubernetes:

Dashboard de Kubernetes – Config Maps

Cómo se usa un ConfigMap

Ahora que ya tenemos una configuración creada el siguiente paso es usarlo. En este caso voy a modificar la plantilla que me cree para el despliegue de postgres de la siguiente manera:

#deploy-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres-deployment
  labels:
    app: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: mypostgres
        image: postgres
        env:        
        - name: POSTGRES_USER
          valueFrom:
            secretKeyRef:
              name: db-user-pass
              key: username.txt
        - name: POSTGRES_PASSWORD
          valueFrom:
             secretKeyRef:
              name: db-user-pass
              key: password.txt
        - name: POSTGRES_DB
          valueFrom:
              configMapKeyRef:
                name: postgres-config
                key: dbName
        - name: POSTGRES_INITDB_ARGS
          valueFrom:
              configMapKeyRef:
                name: postgres-config
                key: encoding

Como puedes ver, comparándolo con el uso de secretos, las variables POSTGRES_DB y POSTGRES_INITDB_ARGS recuperan su valor del configmap con nombre postgres-config utilizando valueFrom > configMapKeyRef, por lo que su uso es bastante similar.

Para comprobar que la configuración ha funcionado de manera correcta, ejecuta el despliegue:

kubectl apply -f deploy-pod.yaml

Y comprueba que tienes una base de datos con el nombre mydb y que el encoding establecido para todas es SQL_ASCII.

#Get the name of the pod
kubectl get pods

#Access to the pod
kubectl exec -it postgres-deployment-XXXXXXX  -- /bin/bash

#Access to postgres
psql -U returngis mydb

#List databases
\l

¡Saludos!