Tema representativo de entrevista

Entrevista de diseño de sistemas: ¿Cómo diseñarías el ciclo de vida de un Job con Sidecar en Kubernetes?

Diseño de sistemasDifícil
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Diseña un Job por lotes de Kubernetes con un Sidecar de registro (logging). El contenedor principal debe permitir que el Job termine puntualmente mientras el Sidecar vacía los datos (flushes) de forma confiable. Cubre reintentos, volúmenes compartidos, probes, orden de terminación y observabilidad.

Prompt y contexto

Un Job por lotes necesita un Sidecar de logging, proxy o sincronización de archivos. Después de que el contenedor principal finaliza, el Job no debe permanecer en estado Pending porque un helper se ejecute indefinidamente; durante la terminación del Pod, el Sidecar aún debe tener la oportunidad de vaciar los datos antes de salir. Explica el ciclo de vida del Sidecar en Kubernetes, los recursos compartidos y el comportamiento ante fallas.

Esta pregunta es adecuada para roles de diseño de sistemas, ingeniería de plataformas y cloud-native. La clave está en separar las condiciones de finalización del Pod, Job, contenedor principal y Sidecar mientras se diseñan límites observables y reintentables.

Qué evalúa el entrevistador

Una respuesta sólida señala que el modelo estable de Sidecar puede expresarse como un contenedor init con restartPolicy: Always; este se ejecuta concurrentemente con el contenedor principal, comparte la red y opcionalmente volúmenes, permite que un Job se complete después de que el contenedor principal finalice, y se termina después de la aplicación principal en el orden inverso de declaración. También debe cubrir probes, presupuestos de recursos, reintentos, idempotencia y señales.

Aclaraciones para hacer primero

  • ¿El Sidecar proporciona logging, proxying, sincronización o seguridad, y debe estar listo antes de que comience la tarea principal?
  • ¿Qué datos deben sobrevivir al éxito, falla, tiempo de espera (timeout) y reintento del contenedor principal?
  • ¿Cuáles son el tamaño del volumen compartido, la tasa de escritura, los permisos y la ventana de limpieza?
  • ¿La finalización del Job se basa en la salida del principal, un drenado explícito del Sidecar o ambos?
  • ¿Qué métricas, eventos, logs y trazas localizan las fallas entre los dos contenedores?

Una respuesta de 30 segundos

“Modelaría el Sidecar como un servicio de soporte concurrente con un contrato explícito de disponibilidad (readiness), fallas y drenado. Usaría la semántica de Sidecar de Kubernetes para que el Job pueda completarse cuando el contenedor principal termine, preservando al mismo tiempo una ruta de volumen compartido y drenado de logs. Cada contenedor recibe probes, presupuestos de recursos y observabilidad; se definen timeouts, reintentos, SIGTERM y limpieza idempotente. Probaría el éxito, las fallas, las caídas del Sidecar y la expulsión (eviction) de nodos.”

Solución paso a paso

Paso 1: Definir roles y finalización

El contenedor principal es dueño del resultado de negocio; el Sidecar proporciona soporte. El éxito del Job debe centrarse en la tarea principal mientras se define qué debe drenar el Sidecar dentro de una ventana acotada. Nunca hagas que un helper sin límite de tiempo sea la única condición de finalización.

Paso 2: Elegir la representación del Sidecar

El modelo estable de Kubernetes utiliza un contenedor init con restartPolicy: Always. Participa en la disponibilidad de inicio del Pod y luego se ejecuta junto al contenedor principal, adaptándose a servicios de logging o proxy que necesitan su propio ciclo de vida.

yaml
initContainers:
  - name: log-shipper
    image: example/log-shipper:1.0
    restartPolicy: Always
    volumeMounts:
      - name: shared-data
        mountPath: /var/app

Paso 3: Diseñar volúmenes compartidos y presupuestos

El Sidecar y el contenedor principal comparten un espacio de nombres de red y pueden compartir un volumen cuando sea necesario. Limita el volumen de escritura, la rotación, los permisos, el almacenamiento efímero, la CPU y la memoria para que una ráfaga de logs no deje sin recursos a la tarea ni distorsione el comportamiento de expulsión.

Paso 4: Establecer probes y preparación (readiness)

La preparación del Sidecar significa que puede dar servicio, no que la tarea principal haya tenido éxito; una falla de liveness necesita una política de reinicio y backoff. Si el contenedor principal debe esperarlo, expón una señal de preparación observable en lugar de adivinar con un sleep fijo.

Paso 5: Manejar éxito, falla y reintento

Tras el éxito del principal, el Sidecar debe leer y enviar la salida restante, y luego salir ante una señal explícita de drenado o timeout. Tras una falla del principal, preserva los diagnósticos. Los reintentos deben hacer que la limpieza de volúmenes, la entrega remota y las escrituras de negocio sean idempotentes para evitar cobros o subidas duplicadas.

Paso 6: Diseñar la terminación y las señales

Al terminar el Pod, kubelet espera a que el contenedor de la aplicación principal se detenga antes de terminar los Sidecars, y luego apaga los Sidecars en el orden inverso al de su aparición en la especificación del Pod. Las aplicaciones aún necesitan un manejo correcto de SIGTERM, un período de gracia de terminación finito y un respaldo de SIGKILL; la salida ordenada no está garantizada.

Paso 7: Conectar el estado del Job y la observabilidad

Registra el código de salida del principal, el estado de drenado del Sidecar, las condiciones del Job, el conteo de reintentos, la marca de agua del volumen y la latencia de entrega. Las alertas deben distinguir entre la falla del principal, un Sidecar que nunca estuvo listo, el timeout de drenado y la expulsión del nodo, en lugar de depender de una sola señal Pod Ready.

Paso 8: Validar una matriz de fallas

Prueba el éxito rápido del principal, fallas de negocio, caída del Sidecar, backend de logs no disponible, volumen compartido lleno, timeout del Job, expulsión de nodos y actualizaciones progresivas. Verifica la finalización del Job, la salida rastreable, el reintento idempotente y la preservación del segmento final de logs.

Compensaciones y límites

Los Sidecars se adaptan a funciones de soporte estrechamente acopladas a la tarea que comparten red o archivos y necesitan un ciclo de vida independiente. Poner cada aspecto de la plataforma en un Sidecar multiplica los recursos, las actualizaciones y las superficies de falla; un DaemonSet a nivel de nodo, un sistema de logging administrado o un servicio separado pueden ser un mejor límite.

El orden de terminación de Kubernetes reduce el riesgo de pérdida, pero no garantiza la disponibilidad de la red externa ni reemplaza la lógica de vaciado, reintento y consistencia de la aplicación. Conecta el éxito del Job y el drenado del Sidecar mediante un contrato explícito.

Plan de despliegue y evidencia

Comienza con un Job de logging: contenedor principal, Sidecar, volumen compartido, probes, límites de recursos y timeout de drenado. Registra las condiciones de finalización y cada ruta de salida antes de agregar reintentos y alertas.

Documenta la versión del Sidecar, el origen de la imagen, los permisos del volumen, los probes, la ventana de terminación, las condiciones del Job y la idempotencia. Utiliza volúmenes de logs realistas y experimentos de expulsión de nodos para verificar las marcas de agua de recursos y la trazabilidad de la salida final.

Errores comunes y preguntas de seguimiento

Tratar un contenedor init regular como un Sidecar concurrente

Un contenedor init regular finaliza antes de que inicie el contenedor principal y no puede proporcionar un proxy o registrador continuo. Usa la semántica estable de Sidecar cuando se requiera concurrencia.

Esperar indefinidamente al Sidecar

Proporciona al Sidecar una señal de drenado y un timeout. Centra el éxito del Job en la tarea principal y verifica que el controlador finalice después de que esta lo haga.

Limitar únicamente el contenedor principal

La CPU, la memoria y el almacenamiento efímero del Sidecar afectan la programación y la expulsión. Define y monitorea requests y limits para ambos roles.

Depender únicamente de Pod Ready

Ready no demuestra el éxito del negocio ni la entrega de los logs. Combina condiciones del Job, códigos de salida, estado de drenado, marcas de agua de colas y latencia de entrega.

¿Qué pasa si el segmento final de logs aún se pierde?

Inspecciona el vaciado del volumen, los reintentos de entrega, la señalización de drenado, el período de gracia de terminación y la disponibilidad del backend; reproduce la matriz de fallas en lugar de simplemente extender el tiempo de sleep.

Fuentes públicas

Preguntas relacionadas

Herramienta de entrevista relacionada

Usa Resolver para una respuesta de diseño de sistemas

Aclara primero los requisitos y luego avanza a través de la escala, la arquitectura, la elección de componentes y las compensaciones (trade-offs).

Ver la herramienta