Lab 5.4 - Rotación de Secrets
Objetivos
Al final de este laboratorio, usted será capaz de:
- Comprender el proceso de rotación de secrets
- Crear nuevos secrets
- Actualizar los deployments con nuevos secrets
- Eliminar los secrets antiguos
- Implementar una rotación sin interrupciones
Requisitos previos
- Cluster de Kubernetes funcional
- kubectl configurado
- Comprensión de Secrets y Deployments
Ejercicio 1: Rotación Básica
Paso 1: Crear el Secret Inicial
kubectl create secret generic db-secret-v1 \
--from-literal=password=old-password-123
Paso 2: Crear un Deployment
Cree deployment-v1.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: busybox:1.35
command: ["sh", "-c", "echo 'Password: $DB_PASSWORD' && sleep 3600"]
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret-v1
key: password
Paso 3: Desplegar
kubectl apply -f deployment-v1.yaml
kubectl get pods -l app=myapp
Ejercicio 2: Crear un Nuevo Secret
Crear el Secret v2
kubectl create secret generic db-secret-v2 \
--from-literal=password=new-password-456
Verificar
kubectl get secrets
kubectl describe secret db-secret-v2
Ejercicio 3: Actualizar el Deployment
Actualizar la Referencia
kubectl set env deployment/app-deployment \
DB_PASSWORD=$(kubectl get secret db-secret-v2 -o jsonpath='{.data.password}' | base64 -d)
O modifique el archivo YAML:
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret-v2 # Cambiado de v1 a v2
key: password
Luego:
kubectl apply -f deployment-v1.yaml
Verificar el Reinicio
kubectl get pods -l app=myapp -w
kubectl rollout status deployment/app-deployment
Ejercicio 4: Rotación con Rolling Update
Crear un Deployment con Rolling Update
Modifique el deployment para usar el nuevo secret y forzar un rolling update:
# Método 1: Modificar el secret referenciado
kubectl patch deployment app-deployment -p '{"spec":{"template":{"spec":{"containers":[{"name":"app","env":[{"name":"DB_PASSWORD","valueFrom":{"secretKeyRef":{"name":"db-secret-v2","key":"password"}}}]}]}}}}'
# Método 2: Anotación para forzar el reinicio
kubectl patch deployment app-deployment -p '{"spec":{"template":{"metadata":{"annotations":{"kubectl.kubernetes.io/restartedAt":"'$(date +%Y-%m-%dT%H:%M:%S%z)'"}}}}}'
Verificar
kubectl get pods -l app=myapp
kubectl logs <pod-name> | grep Password
Ejercicio 5: Rotación Automatizada con Script
Crear un Script de Rotación
Cree rotate-secret.sh:
#!/bin/bash
SECRET_NAME=$1
NEW_SECRET_NAME=$2
DEPLOYMENT_NAME=$3
ENV_VAR_NAME=$4
# Crear el nuevo secret (debe crearse manualmente antes)
# kubectl create secret generic $NEW_SECRET_NAME --from-literal=password=<new-password>
# Actualizar el deployment
kubectl set env deployment/$DEPLOYMENT_NAME \
$ENV_VAR_NAME=$(kubectl get secret $NEW_SECRET_NAME -o jsonpath='{.data.password}' | base64 -d)
# Esperar el rollout
kubectl rollout status deployment/$DEPLOYMENT_NAME
echo "Rotación terminada. Elimine el secret antiguo: kubectl delete secret $SECRET_NAME"
Usar el Script
chmod +x rotate-secret.sh
./rotate-secret.sh db-secret-v1 db-secret-v2 app-deployment DB_PASSWORD
Ejercicio 6: Rotación con Init Container
Crear un Deployment con Init Container
Cree deployment-init.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment-init
spec:
replicas: 3
selector:
matchLabels:
app: myapp-init
template:
metadata:
labels:
app: myapp-init
spec:
initContainers:
- name: secret-validator
image: busybox:1.35
command: ["sh", "-c", "test -n \"$DB_PASSWORD\" && echo 'Secret valid'"]
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret-v2
key: password
containers:
- name: app
image: busybox:1.35
command: ["sh", "-c", "echo 'Password: $DB_PASSWORD' && sleep 3600"]
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret-v2
key: password
Ejercicio 7: Verificación Post-Rotación
Verificar los Pods
# Ver todos los Pods
kubectl get pods -l app=myapp
# Verificar los logs
kubectl logs <pod-name> | grep Password
# Verificar las variables de entorno
kubectl exec <pod-name> -- env | grep DB_PASSWORD
Verificar los Secrets
# Ver los secrets
kubectl get secrets | grep db-secret
# Verificar que el secret antiguo ya no se utiliza
kubectl get pods -o jsonpath='{.items[*].spec.containers[*].env[*].valueFrom.secretKeyRef.name}' | grep -o db-secret-v1
Limpieza
# Eliminar los deployments
kubectl delete deployment app-deployment app-deployment-init
# Eliminar los secrets antiguos (después de verificar)
kubectl delete secret db-secret-v1
# Mantener db-secret-v2 como referencia
Preguntas de Reflexión
- ¿Por qué es importante verificar que todos los Pods utilizan el nuevo secret antes de eliminar el antiguo?
- ¿Cómo puede usted automatizar la rotación de secrets?
- ¿Cuál es la mejor estrategia para la rotación sin interrupciones?
- ¿Cómo gestionar la rotación de secrets para los StatefulSets?
Desafío Bonus
Cree un CronJob que verifique automáticamente la antigüedad de los secrets y alerte si un secret no ha sido rotado en más de 90 días.
Lab creado el: Diciembre 2024