Drenar nodos en Kubernetes parece una tarea rutinaria hasta que coincide con una ventana tensa, un autoscaler inquieto y una guardia que ya viene cansada. El comando es facil. Lo dificil es saber si, justo antes del cambio, tus alertas siguen diciendo la verdad. Cuando eso falla, el mantenimiento sale "bien" pero el equipo pierde visibilidad durante los minutos que más importan.
Me ha tocado ver este patrón varias veces: el kubectl drain termina, los pods vuelven, los dashboards se ponen verdes y aun así la guardia queda medio ciega. No porque Kubernetes falle, sino porque el cambio movió ownership, silenció una ruta de alertas o dejó un umbral mirando al nodo equivocado. Es un detalle chico, pero pega bastante en producción.
La idea útil es tratar el drenado como un cambio de observabilidad, no solo de capacidad. El 2024 State of DevOps Report insiste en reducir fricción operativa y estandarizar respuestas para recuperar servicio más rápido (https://cloud.google.com/devops/state-of-devops/). En la practica, eso significa hacer una preflight corta y repetible antes de tocar el nodo.
Donde se tuerce el drenado de nodos
El problema más comun es asumir que si el scheduler recoloca pods, la telemetría también se recoloca sin fricción. A veces sí, a veces no. He visto reglas que seguían filtrando por node_name, exporters que tardaban demasiado en volver y canales de alerta que dependían de labels efimeros. Cuando juntas eso con una ventana corta, aparece el clasico "todo parece sano, pero nadie confia del todo".
Otro fallo muy humano es mezclar señal de mantenimiento con señal de incidente. Si no dejas claro qué alertas esperas ver degradadas y durante cuánto tiempo, cualquier pico menor se convierte en ruido. Es parecido a la idea de mantener feedback visible sin romper el foco: la gente necesita contexto estable para actuar bien, no solo mensajes que cambian de sitio.
También conviene desconfiar de la documentación escrita con prisa. En un runbook viejo llegué a encontrar referencias como temp org mail usadas como texto de prueba, y eso no rompía nada por sí solo. Lo que sí rompe es copiar esa misma ligereza a procesos de SRE donde una alerta sin dueño o sin ventana clara te hace perder minutos buenos.
La preflight que si ayuda en guardia
Mi versión favorita cabe en cinco preguntas:
- ¿Qué workloads saldrán del nodo y cuáles tienen
PodDisruptionBudgetajustado? - ¿Qué alertas dependen de métricas o labels a nivel de nodo?
- ¿Qué degradación temporal es esperable y cuánto debe durar?
- ¿Quién confirma que el servicio volvió sano desde fuera del cluster?
- ¿Qué condición exacta obliga a abortar o pausar?
Si estas respuestas no están listas antes del cambio, el drenado ya empezó flojo. No hace falta un documento enorme. Basta con una tabla o bloque corto en el runbook con servicio, nodo, riesgo principal y verificación externa. En equipos que operan varios clusters, esta mini disciplina evita bastantes confusiones, aunque suene poco glamorosa.
Yo suelo añadir una comprobación más: mirar si la ruta de alerta post-cambio sigue teniendo sentido para el on-call real. Si el nodo pertenece a un pool nuevo, o si cambió el reparto de tenants, puede que la notificación llegue al canal correcto pero con prioridad equivocada. Y ahí arranca el triage raro, ese que nadie pidió.
Un flujo simple para validar alertas antes del cambio
Un flujo pequeño suele bastar:
- Marca el nodo candidato y anota un
change_id. - Lista pods críticos, PDBs y afinidades activas.
- Simula qué alertas podrían moverse o quedar brevemente mudas.
- Ejecuta el drenado en ventana acotada.
- Confirma salud desde una fuente ajena al nodo drenado.
- Revisa que las alertas sigan describiendo bien el estado real.
Cuando un equipo ya trabaja con señales de producto y operación mejor ordenadas, le resulta más facil reactivar flujos con senales de producto claras y también separar un mantenimiento esperado de un incidente real. La lógica es la misma: menos ambigüedad, menos decisiones apuradas.
Si quieres algo muy concreto, esta es la parte que no me salto:
kubectl get pdb -A
kubectl get pods -A --field-selector spec.nodeName=<node>
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
kubectl uncordon <node>
El comando no tiene misterio. Lo importante es el criterio de salida. Para mí, el cambio no termina cuando el nodo queda drenado, sino cuando las alertas, los checks externos y el servicio cuentan la misma historia. Si uno de esos tres queda fuera de fase, mejor quedarse cinco minutos más y revisar. Suena lento, pero luego ahorra bastante desgaste.
Checklist corto para el siguiente mantenimiento
- El runbook explica qué alertas pueden degradarse temporalmente.
- Hay una verificación externa al nodo antes y después del drenado.
- Los
PodDisruptionBudgetfueron revisados ese mismo día. - El canal de guardia y la severidad siguen alineados con el riesgo.
- Existe un criterio escrito para pausar o revertir.
- Alguien confirma que observabilidad y servicio volvieron a coincidir.
Preguntas frecuentes
¿Esto aplica solo a clusters grandes?
No. En clusters pequeños duele igual, a veces más, porque un solo nodo concentra demasiadas piezas y cualquier silencio de alertas se nota enseguida.
¿Hace falta automatizar todo?
No del todo. Una preflight manual pero consistente ya mejora mucho el resultado. Luego, si ves patrones repetidos, automatizas lo que valga la pena. Ir de menos a más suele salir mejor.
Top comments (0)