Todo clúster necesita mantenimiento: actualizar el SO, el kubelet, aumentar la RAM, cambiar el disco. La diferencia entre una ventana tranquila y un incidente es el proceso.
Este capítulo cierra la Temporada 2 con el upgrade que hicimos de verdad: workers de 8 GiB a 16 GiB.
Sello del curso: probado en Kubernetes 1.35 y Ubuntu 24.04.
Antes de tocar cualquier nodo
Checklist previo al vuelo:
- Capacidad libre en los otros nodos para recibir los pods.
- PDBs de las cargas críticas.
- Anti-afinidad (bases de datos, Elasticsearch, RabbitMQ).
- Quórum (etcd, RabbitMQ, Redis Sentinel).
- Almacenamiento ligado al nodo (
local-path) y PVCs. - DaemonSets que necesitan ejecutarse en el nodo.
- Backup reciente y restore probado.
kubectl get nodes -o wide
kubectl top nodes
kubectl get pdb -A
kubectl get pods -A -o wide | grep <node>
El proceso, un nodo a la vez
1. Cordon
kubectl cordon k8s-worker-01
Ningún pod nuevo se programa allí; los existentes continúan.
2. Drain
kubectl drain k8s-worker-01 --ignore-daemonsets --delete-emptydir-data
El drain respeta los PDBs. Si se bloquea, no use --force sin entender: descubra qué PDB está bloqueando.
kubectl get pdb -A
kubectl describe pdb <pdb>
3. Valide la reprogramación
kubectl get pods -A -o wide | grep -v Running
kubectl -n <ns> get pods -o wide
Los pods con anti-afinidad obligatoria pueden quedar Pending hasta que el nodo regrese. Es esperado, pero necesita saber cuáles.
4. Apague/actualice
- Aumente la RAM en la VM/host.
- Actualice el SO y el kubelet, si corresponde.
- Reinicie.
5. Levante y uncordon
kubectl uncordon k8s-worker-01
kubectl get nodes
kubectl get pods -A -o wide | grep k8s-worker-01
6. Valide antes del próximo
- Nodos
Ready. - Cargas críticas saludables.
- Quórum restaurado.
- PDBs con interrupciones permitidas.
- Métricas sin anomalías.
El orden importa
En un clúster con datos:
- Nodo sin base de datos/estado primero.
- Réplicas antes del primario.
- Primario al final (con failover planificado).
- Nunca dos nodos al mismo tiempo.
En nuestro caso, el worker con el primario de Postgres fue el último.
Lo que salió mal en nuestro upgrade
- MinIO todo en un nodo. Los 4 pods estaban en el mismo worker; drenar ese nodo derribaría el object storage. Movimos los pods antes (cordon + reciclaje), pero descubrimos que la imagen no estaba en caché en otro nodo —
ErrImagePull. - PDB de MinIO
minAvailable: 3. Drenar un nodo con 2 pods violaba el PDB. Lo ajustamos temporalmente a 2. - Postgres primario en el nodo. El drain exigió failover; el PDB del primario bloqueaba. Hicimos el failover controlado antes.
- Pods Pending por anti-afinidad. Con un nodo fuera, Elasticsearch y RabbitMQ no podían mantener 3 réplicas. Esperado; lo documentamos.
- HPA agresivo. En otro incidente, 10 pods de backend presionaron la memoria y derribaron Postgres. La capacidad no es solo CPU.
Upgrade de versión de Kubernetes
Para el kubelet:
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
sudo apt-mark unhold kubeadm kubelet kubectl
sudo apt install -y kubeadm=1.35.x-1.1 kubelet=1.35.x-1.1 kubectl=1.35.x-1.1
sudo kubeadm upgrade node
sudo systemctl restart kubelet
kubectl uncordon <node>
Masters primero (uno por vez), después workers. Nunca salte versiones menores.
Errores comunes
| Síntoma | Causa |
|---|---|
| Drain bloqueado | PDB sin interrupciones |
Pods Pending después del drain |
anti-afinidad/capacidad |
local-path PVC atascado |
el volumen es del nodo antiguo |
| DaemonSet ausente | taint sin toleration |
| Postgres sin quórum | primario/réplica en el mismo nodo |
Nodo no vuelve Ready |
kubelet/CNI/reloj |
| HPA escala demasiado | presupuesto de memoria ignorado |
Checklist
- [ ] Capacidad en los nodos restantes.
- [ ] PDBs revisados.
- [ ] Anti-afinidad/quórum mapeados.
- [ ] Backup reciente.
- [ ] Cordon + drain + validación.
- [ ] Un nodo por vez.
- [ ] Uncordon y validación antes del próximo.
- [ ] PDBs restaurados al valor original.
Glosario
- cordon: impide nuevos pods en el nodo.
- drain: evacua pods del nodo.
- uncordon: libera el nodo.
- eviction: eliminación respetando PDB.
- quórum: mayoría para consenso.
- anti-affinity: regla de distribución.
Siguiente
Temporada 2 concluida. En la Temporada 3 vamos a empaquetar la aplicación con Helm, versionar en GitOps, montar CI/CD, endurecer la seguridad, medir la capacidad y cerrar con SLO y DR.
Siguiente: Curso Kubernetes 21 — Helm: empaquetando la aplicación
Seguir leyendo
Lea también
TutoriaisManual LSI / Broadcom MegaRAID — MegaCli y StorCLI
Con esta guía, su equipo gana autonomía para diagnosticar rebuilds, resolver foreign configurations, gestionar BBU y CacheCade — con escenarios reales de producción documentados.
20 min de leitura
Nginx Cheatsheet
Guía de bolsillo con ejemplos listos para configurar Nginx en producción: desde instalación y virtual hosts hasta ajuste de rendimiento y resolución de problemas.
12 min de leitura
KubernetesCurso Kubernetes 27 — SLO/SLI, on-call y postmortem sin culpa
Qué prometer, cómo medir y qué hacer cuando el error se dispara: SLI, SLO, presupuesto de error, alertas que despiertan a alguien y postmortem sin caza de brujas.
5 min de leitura
Comentarios
Aún sin comentarios
Sea el primero en compartir su opinión sobre este artículo.

Deje un comentario