⏱ Tiempo estimado: 25 minutos
🎯 Rama / Perfil: Devs y DevOps que dan el paso de Docker a orquestación.
🧠 Conocimiento previo necesario: Clases 2, 3, 13 y 15 del curso (Docker y estrategias Blue/Green, Canary y Rolling).
💡 ¿Qué vas a lograr? Actualizar una app en un clúster local sin downtime, romper un despliegue a propósito y recuperarte con un comando.
🛠 Lo que necesitas antes de empezar
- Docker Desktop → 🔗 https://www.docker.com/products/docker-desktop/
- kind → 🔗 https://kind.sigs.k8s.io/docs/user/quick-start/
- kubectl → 🔗 https://kubernetes.io/docs/tasks/tools/
📋 Pasos
Paso 1: Crea el clúster y la app
bash
kind create cluster --name lab
En una carpeta nueva, crea server.js:
js
const http = require('http');
http.createServer((req, res) => {
if (req.url === '/healthz') return res.end('ok');
res.end('Hola desde la version ' + process.env.APP_VERSION + '\n');
}).listen(3000);
Y Dockerfile:
dockerfile
FROM node:20-alpine
WORKDIR /app
COPY server.js .
ARG APP_VERSION=1
ENV APP_VERSION=$APP_VERSION
CMD ["node", "server.js"]
Paso 2: Construye dos versiones y cárgalas al clúster
bash
docker build --build-arg APP_VERSION=1 -t web:v1 .
docker build --build-arg APP_VERSION=2 -t web:v2 .
kind load docker-image web:v1 web:v2 --name lab
kind load copia las imágenes locales dentro del clúster, así que no necesitas un registry.
Paso 3: Despliega 3 réplicas con estrategia Rolling
Crea deploy.yaml:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels: { app: web }
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
template:
metadata:
labels: { app: web }
spec:
containers:
- name: web
image: web:v1
ports:
- containerPort: 3000
readinessProbe:
httpGet: { path: /healthz, port: 3000 }
initialDelaySeconds: 2
periodSeconds: 2
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector: { app: web }
ports:
- port: 80
targetPort: 3000
bash
kubectl apply -f deploy.yaml
kubectl rollout status deployment/web
maxUnavailable: 0 garantiza que nunca baje la capacidad durante la actualización, y el readinessProbe evita enviar tráfico a un pod que aún no responde.
🔗 Referencia: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
Paso 4: Actualiza a v2 sin downtime
Abre una segunda terminal y lanza un cliente que consulte el Service sin parar:
bash
kubectl run curl --rm -it --image=curlimages/curl --restart=Never -- \
sh -c 'while true; do curl -s web; sleep 0.5; done'
En la primera terminal:
bash
kubectl set image deployment/web web=web:v2
kubectl rollout status deployment/web
Verás cómo las respuestas pasan de “version 1” a “version 2” sin errores ni cortes.
Paso 5: Rompe un despliegue a propósito
bash
kubectl set image deployment/web web=web:v9
kubectl rollout status deployment/web --timeout=30s
kubectl get pods
La imagen web:v9 no existe, así que los pods nuevos quedan en ErrImagePull o ImagePullBackOff. Observa en la segunda terminal que tu app sigue respondiendo con v2: Kubernetes no retiró los pods sanos porque los nuevos nunca estuvieron Ready.
Paso 6: Haz rollback
bash
kubectl rollout undo deployment/web
kubectl rollout status deployment/web
kubectl rollout history deployment/web
Todo vuelve a un estado sano en segundos. Cuando termines, limpia con kind delete cluster --name lab.
✅ Resultado esperado
Un clúster local con 3 réplicas de tu app, una actualización a v2 con cero cortes (comprobada con tráfico continuo) y un despliegue roto contenido y revertido con rollout undo.
🔥 Tu reto (siguiente acción)
Cambia el readinessProbe para que apunte a una ruta que no existe (por ejemplo /nope) y predice qué pasará con el rollout antes de aplicarlo. Luego intenta una variante canary manual: crea un segundo Deployment con 1 réplica de v2 detrás del mismo Service y compara cómo se reparte el tráfico.
📚 Recursos para ir más lejos
- Tutorial oficial de rolling update: 🔗 https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/ (el mismo flujo con la herramienta oficial de aprendizaje)
- Argo Rollouts: 🔗 https://argoproj.github.io/argo-rollouts/ (Canary y Blue/Green automatizados sobre Kubernetes)
Curso Profesional de DevOps
COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE