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.
- namenombre de la variable dentro del container
- fieldPathes 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