ConfigMaps & Environtment

ConfigMaps y Variables Entorno

ConfigMaps es un objeto que permite guardar una configuración especifica para un tipo de containers y así cambiar la configuración de un container sin tener que rehacer el Dockerfile ni la imagen, esto lo hace mediante puntos de montaje o variables de entorno.

Esto puede servir para terner diferentes configuraciones de un mismo contenedor y utilizar la mas adecuada para el momento deseado.

Variables entorno

A un pod se le pueden asignar variables de entorno directamente desde el manifiesto indicándolas dentro de la sección contnedor variable env.

apiVersion: v1
kind: Pod
metadata:
  name: envar-demo
  labels:
    purpose: demonstrate-envars
spec:
  containers:
  - name: envar-demo-container
    image: nginx:alpine
    env:
    - name: DEMO_GREETING
      value: "Hello from the environment"
    - name: DEMO_FAREWELL
      value: "Such a sweet sorrow"

Dentro del contenedor se asignan correctamente

➜ sudo kubectl get pods
NAME         READY   STATUS    RESTARTS   AGE
envar-demo   1/1     Running   0          14s

➜ sudo kubectl exec -it envar-demo -- sh
/ # env | grep DEMO
DEMO_FAREWELL=Such a sweet sorrow
DEMO_GREETING=Hello from the environment

valores externos

Cada pod tiene una serie de valores perteneciente a el, pero que interiormente no están definidos, es decir desde dentro del contenedor no se ven, esto puede ser metadata, specificaciones, etc... Estos valores se pueden ver con el siguiente comando:

➜  sudo kubectl get pod envar-demo -o yaml

En ocasiones es posible que se necesiten en el interior y se pueden definir como valores de entorno.

  • name nombre de la variable dentro del container
  • fieldPath es la ruta que sigue descrita en el comando anterior en formato yaml.
apiVersion: v1
kind: Pod
metadata:
  name: dapi-envars-fieldref
spec:
  containers:
    - name: test-container
      image: nginx:alpine
      env:
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP

ConfigMap

Para utilizar ConfigMap primero se tiene que crear el objeto, para después asignarlo a los containers que queramos.

Comand-line

En est ejemplo se esta asignando solo un archivo en el configmap, en el caso de querer asignar un directorio es lo mismo pero indicando el directorio.

# creo l objeto con la configuración de nginx
➜ sudo kubectl create configmap nginx-config --from-file=configmap/cf-examples/nginx.conf
configmap/nginx-config created

# visualizo
➜ sudo kubectl get cm
NAME           DATA   AGE
nginx-config   1      12s

➜ sudo kubectl describe cm nginx-config
Name:         nginx-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx.conf:
----
server {
    listen       8080;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

Events:  <none>

ahora solo quedaría asignarlo a un contenedor, pero como en kubernetes es mejor trabajar desde manifiestos, lo haré en la siguiente sección

template

Ejemplo de manifiesto de ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
  labels:
    app: front
data:
  test: hola
  nginx: |
    server {
        listen       8080;
        server_name  localhost;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }

Para poder utilizar un configMap dentro de un contenedor se tiene que montar como volumen, por lo tanto se necesita especificar el nuevo volumen y después montarlo en el contenedor.

apiVersion: v1
kind: Pod
metadata:
  name: pod-test
  labels:
    app: front-nginx
  spec:
    containers:
    - name: nginx
      image: nginx:alpine
      volumeMounts:
        - name: nginx-vol
          mountPath: /etc/nginx/conf.d
   volumes:
     - name: nginx-vol
       configMap:
         name: nginx-config
         items:
         - key: nginx
           path: default.conf
Especificar nuevo volumen

dentro de volumes indicas el volumen configmap a montar, la sección key es la sección dentro de configmap y la path el nombre del archivo final dentro del contenedor.

Asignar volumen

volumeMounts esta indicando que volumen montar y donde.

Environtment

kubernetes también permite trabajar con variables de entorno dentro de los objetos configmap e incluso, combinar variables con archivos.

apiVersion: v1
kind: ConfigMap
metadata:
  name: vars
  labels:
    app: front
data:
  db_host: dev.host.local
  db_user: dev_user
  script: |
    echo DB host es $DB_HOST y DB user es $DB_USER > /usr/share/nginx/html/test.html
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-test
  labels:
    app: front-nginx
  spec:
    containers:
    - name: nginx
      image: nginx:alpine
      env:
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: vars
              key: db_host
        - name: DB_USER
          valueFrom:
            configMapKeyRef:
              name: vars
              key: db_user
      volumeMounts:
         - name: script-vol
           mountPath: /opt
    volumes:
      - name: script-vol
        configMap:
          name: vars
          items:
          - key: script
            path: script.sh

Comprobaciones de que todo a salido bien.

# aplico el yaml y creo el config map y el pod
➜ sudo kubectl apply -f configmap/cm-nginx-env.yml          
configmap/vars created
pod.apps/pod-test created

➜ sudo kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
pod-test   1/1     Running   0          37s

# entro dentro del contenedor para ver que todo esta bien
➜ sudo kubectl exec -it pod-test -- sh

# compruebo que las variables de entorno se han asignado y el archivo script existe.
/ # env
...
DB_HOST=dev.host.local
DB_USER=dev_user

/ # ls /opt/
script.sh
/ # sh /opt/script.sh 

# despues de ejcutar el script desde un navegador compruevo, que todo es correcto.
➜ curl 172.17.0.5/test.html
DB host es dev.host.local y DB user es dev_user