Introducción
En el desarrollo de software, guardar directamente en el código de la aplicación configuraciones como las URL de bases de datos o las contraseñas es una mala práctica. Esto dificulta los cambios y aumenta los riesgos de seguridad.
Kubernetes resuelve este problema mediante dos objetos:
- ConfigMap: considérelo un tablón de anuncios público. Aquí puede colocar información, como «El color de fondo es azul» o «La dirección de la base de datos es 10.0.0.1». Cualquier persona de la oficina (los Pods) puede leerla.
- Secret: se utiliza para valores confidenciales, como contraseñas o tokens.
Separar el código de la aplicación de la configuración de ejecución es un principio fundamental del diseño de plataformas, no solo una característica de Kubernetes.
En este laboratorio, usted:
- Escribirá una nota en el tablón de anuncios (ConfigMap).
- Guardará una contraseña en la caja fuerte (Secret).
- Enseñará a un Pod a leer ambos objetos.
Crear un ConfigMap
Creemos un archivo de configuración para un servidor web. En lugar de incorporarlo a la imagen, lo almacenaremos en un ConfigMap.
Este patrón forma parte de un principio más amplio del diseño de contenedores: crear una única imagen reutilizable y proporcionar la configuración específica del entorno durante la ejecución. Así, la imagen es más portable, porque desarrollo, pruebas y producción pueden utilizar el mismo contenedor con configuraciones diferentes.
Primero, cree un archivo de configuración sencillo de Nginx llamado nginx.conf:
echo 'events {} http { server { listen 80; location / { return 200 "Hello from ConfigMap!"; } } }' > nginx.conf
Ahora, cree un ConfigMap llamado nginx-config a partir de este archivo. De este modo, el archivo quedará «colocado» en el tablón de anuncios del clúster de Kubernetes.
kubectl create configmap nginx-config --from-file=nginx.conf
Compruebe que existe:
kubectl describe configmap nginx-config
En la sección «Data» debería aparecer el contenido de nginx.conf.
Crear un Secret
Ahora almacenaremos un dato confidencial. Un Secret funciona de forma similar a un ConfigMap, pero Kubernetes lo trata con mayor cuidado (ofusca los datos almacenados).
Es importante ser precisos: un Secret es más seguro que guardar contraseñas directamente en manifiestos o imágenes, pero la codificación base64 no es cifrado real. En producción, la gestión de Secrets suele combinarse con cifrado en reposo, reglas RBAC más estrictas y sistemas externos de gestión de Secrets.
Cree un Secret llamado app-secret para almacenar una contraseña de prueba:
kubectl create secret generic app-secret --from-literal=password=SuperSecretPass123
Compruebe que existe:
kubectl get secret app-secret
Si consulta sus detalles, no verá la contraseña directamente. Estará oculta (codificada).
kubectl get secret app-secret -o yaml
Observe que el campo password contiene una combinación de caracteres. Se trata de una codificación base64, diseñada para evitar que alguien vea el valor por encima del hombro o que aparezca accidentalmente en los registros.
Montar un ConfigMap como archivo
Ahora enseñaremos a un Pod a leer el tablón de anuncios.
La forma más habitual de utilizar un ConfigMap es montarlo como archivo. Dentro del contenedor aparece como un archivo normal del disco.
Este enfoque basado en archivos resulta útil cuando una aplicación ya espera encontrar un archivo de configuración en una ruta concreta. Kubernetes proyecta los datos del ConfigMap en el sistema de archivos del contenedor, de modo que la aplicación puede seguir utilizando su comportamiento habitual de lectura de archivos.
Cree un archivo llamado pod-config.yaml:
nano pod-config.yaml
Pegue el contenido siguiente. Este Pod monta el ConfigMap nginx-config en /etc/nginx/nginx.conf.
apiVersion: v1
kind: Pod
metadata:
name: config-pod
spec:
containers:
- name: nginx
image: nginx:alpine
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: config-volume
configMap:
name: nginx-config
Guarde el archivo y salga (Ctrl+X, Y, Enter).
Aplíquelo:
kubectl apply -f pod-config.yaml
Espere unos segundos a que se inicie. Ahora, compruebe dentro del contenedor si el archivo está presente:
kubectl exec config-pod -- cat /etc/nginx/nginx.conf
Debería ver su configuración personalizada. El Pod ha «leído el tablón de anuncios» y ha utilizado ese archivo.
Inyectar un Secret como variable de entorno
Ahora trabajaremos con el Secret. Una forma habitual de pasar contraseñas es mediante variables de entorno.
Este método es práctico, pero también muestra una contrapartida. Las aplicaciones pueden leer fácilmente las variables de entorno, aunque estas pueden quedar expuestas mediante comandos de diagnóstico o la inspección de procesos. Kubernetes admite tanto la inyección mediante archivos como mediante variables de entorno, porque cada aplicación y cada perfil de riesgo requiere un enfoque diferente.
Cree un archivo llamado pod-secret.yaml:
nano pod-secret.yaml
Pegue el contenido siguiente. Este Pod obtiene password de app-secret y lo asigna a una variable de entorno llamada APP_PASSWORD.
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: busybox
image: busybox
command: ["sleep", "3600"]
env:
- name: APP_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: password
Guarde el archivo y salga (Ctrl+X, Y, Enter).
Aplíquelo:
kubectl apply -f pod-secret.yaml
Cuando el Pod esté en ejecución, compruebe las variables de entorno dentro del contenedor:
kubectl exec secret-pod -- env | grep APP_PASSWORD
Debería ver APP_PASSWORD=SuperSecretPass123.
La clave está en que la definición del Pod no contiene la contraseña. La contraseña se encuentra en la «caja fuerte» (Secret), y el Pod solo tiene una clave para abrirla durante la ejecución.
Resumen
En este laboratorio, practicó cómo separar el código de la configuración.
Ha logrado:
- Utilizar un ConfigMap (tablón de anuncios) para inyectar un archivo de configuración en un servidor.
- Utilizar un Secret (caja fuerte) para inyectar una contraseña oculta en una aplicación.
A partir de ahora, podrá actualizar la configuración o rotar las contraseñas sin tener que volver a crear sus imágenes de Docker.


