Saltar al contenido principal

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​

  1. ¿Por qué es importante verificar que todos los Pods utilizan el nuevo secret antes de eliminar el antiguo?
  2. ¿Cómo puede usted automatizar la rotación de secrets?
  3. ¿Cuál es la mejor estrategia para la rotación sin interrupciones?
  4. ¿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