Tema representativo de entrevista

Entrevista de backend: diseñar el apagado correcto (graceful shutdown) y el drenaje de conexiones en Kubernetes

BackendIntermedio
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Un Pod HTTP ocasionalmente pierde solicitudes durante implementaciones continuas (rolling releases) y mantenimiento de nodos. ¿Cómo detienes el trabajo nuevo, drenas conexiones de larga duración, evitas trabajos en segundo plano duplicados y demuestras que terminationGracePeriodSeconds es suficiente?

Enunciado y alcance

Un servicio HTTP se ejecuta en un Deployment. Después de que se elimina un Pod, algunas solicitudes aún llegan a la instancia anterior, mientras que el sondeo largo (long polling) y los trabajos en segundo plano se interrumpen. Explica la línea de tiempo de terminación a través de Kubernetes, el Service, los balanceadores de carga y el proceso; luego diseña el drenaje, la cancelación, los reintentos y la verificación. La habilidad fundamental es delimitar las conexiones y los efectos secundarios durante el apagado, por lo que esto pertenece al backend.

Qué evalúa el entrevistador

Una respuesta sólida separa la eliminación del Pod, las actualizaciones de EndpointSlice, la propagación en los balanceadores de carga, preStop, SIGTERM y SIGKILL. Recibir SIGTERM no significa que el tráfico se haya detenido. Cubre conexiones de larga duración, trabajos en cola, reintentos idempotentes, cortes de energía inesperados en los nodos y un período de gracia insuficiente.

Preguntas para aclarar primero

  • ¿Es el servicio de solicitudes cortas, SSE, WebSocket o long polling? ¿Se pueden migrar las conexiones?
  • ¿Qué verifican las sondas de readiness, liveness y startup, y la aplicación expone el estado de drenaje?
  • ¿Es preStop un comando sleep, un hook HTTP o un endpoint de drenaje de la aplicación? ¿Quién realiza la salida final?
  • ¿El Pod ejecuta workers, y cómo se gestionan los leases y las entregas duplicadas?
  • ¿Cuáles son los retrasos de propagación del balanceador de carga de ingress, el service mesh y el LB en la nube?

Estructura de respuesta de 30 segundos

“Primero marca la aplicación como no lista (not-ready) y deja de aceptar trabajo nuevo, luego espera la propagación del endpoint y del balanceador de carga. Ingresa en modo de drenaje: finaliza las solicitudes cortas, cierra o migra las conexiones de larga duración y evita que los workers reclamen nuevos trabajos mientras liberan los leases que no pueden terminar. preStop es solo una ventana de coordinación; SIGTERM realiza la limpieza. El período de gracia debe cubrir la propagación p99, el drenaje y la limpieza, ejecutando SIGKILL solo después de que expire. Prueba los lanzamientos con métricas de conexiones y trabajos para demostrar que no hay solicitudes perdidas ni efectos duplicados.”

Solución paso a paso

Dibuja la línea de tiempo: el controlador elimina el Pod, el kubelet inicia la terminación, EndpointSlice y los balanceadores de carga eliminan el endpoint de forma asíncrona, y el contenedor puede ejecutar preStop antes de SIGTERM. Debido a que la propagación es asíncrona, la aplicación debe rechazar trabajo nuevo tan pronto como sepa que está drenando, incluso si el tráfico todavía llega a la dirección anterior.

Mantén estados separados para ready y draining. La ruta de apagado establece el drenaje, hace fallar el readiness y deja de aceptar nuevas conexiones o devuelve una respuesta reintentable. Las solicitudes cortas existentes finalizan. SSE, WebSocket y long polling deben recibir una señal de cierre, un cursor o un token de reanudación para que el cliente pueda reconectarse de forma segura.

El comando sleep en preStop no puede reemplazar la lógica de la aplicación. Solo gana tiempo de propagación y consume el período de gracia. Prefiere un endpoint de drenaje en la aplicación que registre el tiempo de inicio y el presupuesto restante; el manejador de SIGTERM detiene el trabajo nuevo, cierra el listener, espera las solicitudes activas y libera los pools de conexiones.

Diseña el drenaje de los workers por separado del drenaje HTTP. Deja de reclamar mensajes nuevos. Protege los trabajos activos con un lease o un tiempo de espera de visibilidad (visibility timeout), y libéralos cuando el presupuesto restante sea insuficiente para que otro worker pueda reintentar. Las escrituras de trabajos y los efectos externos necesitan claves de idempotencia; un Pod terminado forzosamente no debe cobrar ni enviar dos veces.

Elige terminationGracePeriodSeconds a partir de valores p99 medidos: propagación de ingress, la solicitud más larga permitida, cierre de conexiones, limpieza de workers y vaciado de logs (log flushing), más un margen de variación (jitter). Una vez que expira el límite de tiempo, el kubelet puede forzar la terminación; las solicitudes no finalizadas y el estado en el proceso no pueden depender de la ejecución de finally.

El mantenimiento de nodos es diferente de la eliminación de Pods. El apagado correcto de nodos en Kubernetes (graceful node shutdown) otorga al kubelet y a los Pods una ventana planificada, pero los cortes de energía, los kernel panics y los reinicios forzados del host no lo hacen. Los trabajos críticos necesitan puntos de control duraderos (checkpoints), múltiples réplicas y recuperación basada en colas.

Verifica implementaciones continuas, eliminación manual, drenaje de nodos, propagación lenta de LB, conexiones largas y tiempo de espera después de SIGTERM. Revisa errores 5xx, desconexiones, tasa de finalización, rechazos por drenaje, reintentos de trabajos, efectos duplicados, retraso en la eliminación de endpoints y eliminaciones forzadas de Pods, todo correlacionado con la versión del lanzamiento.

Respuesta modelo de alta calidad

“No trataría preStop: sleep 30 como un apagado correcto. Ante la señal de apagado, la aplicación se marca a sí misma en drenaje, hace fallar el readiness y deja de aceptar trabajo nuevo. Las actualizaciones de endpoints y LB se propagan de forma asíncrona, por lo que la instancia anterior aún rechaza nuevas solicitudes. Las solicitudes cortas finalizan; las conexiones SSE y WebSocket reciben un token de cierre o reanudación; los workers dejan de reclamar trabajos y liberan los leases que no pueden terminar.

preStop solo gana tiempo de propagación. El manejador de SIGTERM cierra el listener, espera las solicitudes activas, libera los pools y finaliza antes de un único límite de tiempo. Dimensiono el período de gracia a partir de la propagación p99 medida, la solicitud más larga, la limpieza de workers y el vaciado de logs. Las pruebas cubren implementación continua, drenaje de nodos, conexiones largas, caídas (crash) y finalización forzada, comprobando que no haya solicitudes perdidas, efectos duplicados ni trabajos no recuperados.”

Errores comunes

  • Esperar únicamente a SIGTERM → el tráfico propagado aún llega al Pod anterior → hacer fallar el readiness e ingresar primero en drenaje.
  • Usar un sleep fijo en lugar de drenaje → si cambia la propagación o la duración de la solicitud, se rompe → guiar la lógica a partir del límite de tiempo restante.
  • Detener el Pod pero seguir reclamando trabajos de la cola → la finalización forzada duplica el trabajo → dejar de reclamar y liberar leases.
  • Tratar las conexiones largas como solicitudes ordinarias → los clientes no pueden reanudar → enviar señales de cierre y cursores.
  • Dimensionar el período de gracia a partir de la latencia promedio → las solicitudes p99 reciben SIGKILL → medir la latencia de cola y la propagación.
  • Asumir que finally siempre se ejecuta → la finalización forzada y el corte de energía omiten la limpieza → persistir el estado crítico.
  • Monitorear solo el estado del Pod → no detectar la propagación lenta de LB y las desconexiones → correlacionar endpoints, solicitudes y métricas de lanzamiento.
  • Hacer fallar liveness durante el drenaje → desencadenar tormentas de reinicios → readiness significa elegibilidad para el tráfico; liveness significa salud del proceso.

Preguntas de seguimiento y respuestas

Pregunta de seguimiento 1: ¿Por qué pueden llegar solicitudes después de que falla readiness?

Las actualizaciones de endpoints, service mesh y balanceadores de carga en la nube se propagan con retraso, y las conexiones existentes no se migran automáticamente. La aplicación en drenaje debe rechazar trabajo nuevo y cerrar las conexiones existentes de forma segura.

Pregunta de seguimiento 2: ¿Cuánto tiempo debe durar el sleep en preStop?

No adivines. Mide el p99 de propagación de endpoints y LB, combínalo con los presupuestos de solicitudes y limpieza de workers, y trata el sleep como una ventana de coordinación acotada.

Pregunta de seguimiento 3: ¿Cómo se cierran los WebSockets de forma adecuada?

Deja de aceptar nuevas conexiones y envía un código de cierre con instrucciones de reconexión. Permite que los clientes reanuden con una sesión o cursor, y persiste suficiente estado para evitar reproducir efectos secundarios.

Pregunta de seguimiento 4: ¿Qué sucede si un Pod muere a la mitad de un trabajo?

Persiste el estado del trabajo y un lease. Un nuevo worker lo reclama después del tiempo de espera de visibilidad; las claves de idempotencia o las consultas de estado protegen los efectos externos. No dependas de finally en el proceso.

Pregunta de seguimiento 5: ¿Puede ser elegante un corte de energía en un nodo?

No de manera confiable. El manejo planificado de apagado de nodos cubre flujos de mantenimiento observables; los cortes de energía y los bloqueos del kernel requieren réplicas, puntos de control duraderos y trabajos reintentables.

Pregunta de seguimiento 6: ¿Cómo se elige el período de gracia?

Suma la propagación de endpoints, la solicitud máxima, el cierre de conexiones largas, la liberación de leases, la limpieza de conexiones y el vaciado de logs; luego valida con el p99 medido y un margen, en lugar de promedios.

Pregunta de seguimiento 7: ¿Cómo se evita una tormenta de reinicios durante el drenaje?

Haz fallar el readiness mientras mantienes saludable el liveness. Separa las responsabilidades de las sondas para que “temporalmente no aceptar tráfico” no se confunda con un proceso caído.

Fuentes públicas

Preguntas relacionadas