Configuración: ConfigMaps y Secrets
Mantén los ajustes y las credenciales fuera de tus imágenes, inyéctalos en los Pods y evita las trampas más comunes.
Si una URL de base de datos o un nivel de log está incrustado en la imagen de tu contenedor, cambiarlo significa reconstruir, subir y volver a desplegar la imagen. Kubernetes separa la configuración de las imágenes con dos objetos: los ConfigMaps para ajustes normales y los Secrets para valores sensibles. Esta guía muestra cómo crear ambos, cómo hacerlos llegar a un Pod y qué protegen y qué no protegen los Secrets.
Crea un ConfigMap
Un ConfigMap es un conjunto de pares clave-valor. Los valores pueden ser cadenas cortas o archivos enteros:
apiVersion: v1
kind: ConfigMap
metadata:
name: web-config
data:
LOG_LEVEL: info
API_URL: http://api.internal:8080
motd.txt: |
Welcome to the demo environment
También puedes crear uno desde la línea de comandos, lo que resulta práctico para archivos:
kubectl create configmap web-config \
--from-literal=LOG_LEVEL=info \
--from-file=motd.txt
kubectl describe configmap web-config
Los ConfigMaps son para datos pequeños y no sensibles (el límite es 1 MiB) y pertenecen a un namespace. Un Pod solo puede usar ConfigMaps de su propio namespace.
Úsalo como variable de entorno o como archivo
El mismo Pod puede consumir un ConfigMap de ambas maneras:
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: web
image: nginx:1.25
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: web-config
key: LOG_LEVEL
volumeMounts:
- name: config
mountPath: /usr/share/nginx/html/motd.txt
subPath: motd.txt
volumes:
- name: config
configMap:
name: web-config
Aquí ocurren dos cosas. La entrada env copia una clave en una variable de entorno. (envFrom puede importar todas las claves de una vez, aunque las claves que no son nombres de variable válidos se omiten.) volumes y volumeMounts montan el ConfigMap como archivos, un archivo por clave.
Si montas el ConfigMap completo en un directorio como este, el directorio se reemplaza por los archivos montados:
volumeMounts:
- name: config
mountPath: /etc/web
Eso está bien para un directorio que es tuyo, pero oculta lo que ya hubiera en esa ruta. Montar sobre un directorio de configuración existente, como /etc/nginx, puede romper la aplicación, y el contenedor puede entrar en crash-loop con un error de “file not found”. Para eso sirve subPath, como en el primer ejemplo: monta una sola clave como un solo archivo y deja intacto el resto del directorio. La contrapartida es que los archivos montados con subPath no reciben las actualizaciones posteriores del ConfigMap.
Verifica lo que llegó al contenedor:
kubectl exec web -- ls /usr/share/nginx/html
kubectl exec web -- env | grep LOG_LEVEL
Guarda credenciales en un Secret
Un Secret se parece a un ConfigMap pero está pensado para contraseñas, tokens y claves:
kubectl create secret generic db-credentials \
--from-literal=username=app \
--from-literal=password='S3cr3t-value'
En YAML, usa stringData para escribir texto plano y dejar que Kubernetes lo codifique:
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
stringData:
username: app
password: S3cr3t-value
Si escribes tú mismo el campo codificado data, codifica con echo -n 'value' | base64. Sin -n, el salto de línea final pasa a formar parte de la contraseña y la autenticación falla de formas confusas. Consume un Secret de la misma manera que un ConfigMap:
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
Evita subir a Git manifiestos de Secret con valores reales. Herramientas como Sealed Secrets, External Secrets Operator y SOPS existen para que puedas mantener secretos cifrados o referenciados en un repositorio.
Sabe qué protegen y qué no protegen los Secrets
Base64 es una codificación, no un cifrado. Cualquiera que pueda leer el Secret a través de la API puede decodificarlo:
kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d
Por defecto, los Secrets también se almacenan sin cifrar en etcd. Para protegerlos de verdad:
- Restringe quién puede leer Secrets con RBAC, y recuerda que cualquiera que pueda crear un Pod en un namespace puede montar sus Secrets.
- Habilita el cifrado en reposo de etcd, o usa la gestión de claves de un proveedor de nube.
- Considera un gestor de secretos externo si tus requisitos son estrictos.
Las variables de entorno son cómodas pero fáciles de filtrar, ya que aparecen en kubectl exec ... env, en volcados de fallos y a veces en logs. Montar un Secret como archivo suele ser una mejor opción para valores sensibles.
Actualiza la configuración a propósito
Las variables de entorno se leen una sola vez, cuando arranca el contenedor, así que un ConfigMap o Secret modificado no llega a los Pods en ejecución. Reinícialos para recoger el cambio:
kubectl rollout restart deployment/web
Los archivos de un montaje de directorio completo sí se actualizan con el tiempo, pero muchas aplicaciones solo leen su configuración al arrancar de todos modos. Para configuraciones automatizadas, haz que la plantilla del Pod cambie siempre que cambie la configuración. Para eso sirven las técnicas de hash de configuración de la guía de Helm y Kustomize de Argo CD.
Guías populares
-
Qué es Kubernetes y los problemas que resuelve Por qué los contenedores por sí solos dejan de escalar y cómo Kubernetes convierte un grupo de máquinas en una sola plataforma. -
Cómo funciona un clúster de Kubernetes: plano de control y nodos Los componentes que hacen funcionar un clúster y qué ocurre entre kubectl apply y un contenedor en ejecución. -
Deployments: escalado, autorreparación y rolling updates Ejecuta réplicas de un Pod, actualízalas sin tiempo de inactividad y revierte cuando un despliegue sale mal. -
Services: networking estable para Pods efímeros Dale a los Pods una dirección estable, exponlos dentro y fuera del clúster y restringe quién puede hablar con quién. -
Depura un Pod que falla: describe, logs, exec y port-forward Una lista de comprobación repetible para averiguar por qué un Pod está Pending, se cae o no responde.