Consigna y contexto aplicable
Usted es responsable de una carga de trabajo de Kubernetes que ejecuta un agente de registros, un proxy de malla de servicios o un demonio de caché local junto a una aplicación. El equipo desea migrar ese componente auxiliar de un contenedor regular a un sidecar nativo de Kubernetes. La aplicación debe esperar a que el componente auxiliar esté listo, las fallas del auxiliar necesitan límites de disponibilidad explícitos, y el diseño debe contemplar Jobs, lanzamientos progresivos, cuotas de recursos y reversión. Proponga un plan de migración y explique el desfase de versiones (version skew), las sondas, el orden de terminación y el manejo de fallas.
Esta es una pregunta de diseño de sistemas. La señal evaluada es su razonamiento sobre límites y compensaciones (trade-offs), no un fragmento de YAML memorizado. Cubra ciclo de vida, compatibilidad, recursos, observabilidad y reversión.
Qué evalúa el entrevistador
- Transformar objetivos de nivel de servicio (SLO) en políticas de inicio, readiness, terminación y fallas.
- Explicar el límite entre un sidecar nativo, un contenedor regular, un Deployment separado y un DaemonSet.
- Detectar riesgos de versión entre el servidor de API, los nodos, los webhooks y los clientes.
- Reducir el riesgo de migración mediante presupuestos de recursos, despliegue por etapas, métricas y reversión.
- Manejar contraejemplos como la finalización de Jobs, un proxy bloqueado, sondas fallidas y actualizaciones de nodos.
El material de preparación para SDE II de Amazon describe la evaluación de diseño de sistemas en términos de practicidad, precisión, eficiencia, confiabilidad, optimización y escalabilidad. Esta pregunta le pide aplicar esos objetivos al ciclo de vida del Pod y a los controles de lanzamiento.
Preguntas de clarificación
- ¿El componente auxiliar es una copia por Pod o una copia por nodo? ¿Debe compartir el espacio de nombres de red o los volúmenes de la aplicación?
- ¿Puede la aplicación recibir tráfico antes de que el auxiliar esté listo? ¿Una falla en el inicio bloquea el lanzamiento, degrada el comportamiento o permite una omisión (bypass)?
- ¿Es este un servicio de larga duración, un Job de una sola ejecución o ambos? ¿Debe vaciar registros (flush) o subir datos durante la terminación?
- ¿Están alineadas las versiones de Kubernetes en el clúster, el servidor de API y los nodos? ¿Podría un webhook de admisión, un renderizador de plantillas o un cliente descartar campos desconocidos?
- ¿Cuáles son los presupuestos de CPU, memoria, almacenamiento efímero y red del auxiliar? ¿Su falla consume el presupuesto de errores (error budget) de la aplicación?
- ¿Se puede hacer un despliegue canary por espacio de nombres o carga de trabajo mientras se retiene la plantilla de contenedor regular como interruptor de reversión?
Estructura de respuesta en 30 segundos
Comience con el objetivo: mantener el auxiliar y la aplicación en un solo Pod, iniciarlos en orden, hacer que el comportamiento sea observable y mantener una reversión rápida sin permitir que un auxiliar se bloquee indefinidamente. Implemente un sidecar nativo en initContainers con restartPolicy: Always a nivel de contenedor, una sonda de readiness significativa y un presupuesto de recursos explícito. Proteja la compatibilidad con comprobaciones del clúster y de admisión. Despliegue dos plantillas por etapas, compare la latencia de inicio y las tasas de error, revierta al formato anterior ante infracciones de umbrales y pruebe la finalización de Jobs y el vaciado en la terminación por separado.
Respuesta detallada paso a paso
1. Delimitar primero el ciclo de vida
Un sidecar nativo de Kubernetes es un init container especial: restartPolicy: Always a nivel de contenedor le permite iniciarse durante la inicialización y continuar ejecutándose. Aún sigue el orden de los init containers, por lo que los init containers posteriores y los contenedores de la aplicación esperan a que esté utilizable. «El proxy está listo primero» se convierte en una garantía estructural a nivel de Pod en lugar de un bucle de sondeo en la aplicación.
La aplicación y el sidecar comparten los espacios de nombres de red y almacenamiento del Pod. Esto es útil para un socket de Unix, un volumen de registros o un puerto de proxy local. Si el componente auxiliar solo proporciona una funcionalidad a nivel de nodo, evalúe un DaemonSet en lugar de pagar el costo una vez por Pod.
2. Definir readiness y la política de fallas
Asigne al auxiliar un readinessProbe que represente una capacidad real: configuración del plano de control cargada, puerto de escucha disponible y certificados críticos válidos. La readiness del sidecar puede afectar la readiness del Pod, por lo que una sonda fallida puede retirar todo el Pod de servicio. Una sonda reporta estado; no reemplaza los reintentos, los límites de tasa ni la degradación elegante.
Separe las fallas de inicio, una caída durante la ejecución y una dependencia temporalmente no disponible. Una falla de inicio normalmente mantiene el Pod fuera de servicio. Always reinicia una caída durante la ejecución, pero el conteo de reinicios, el tiempo de recuperación y la tasa de error deben mostrar si el SLO ya se ha perdido. Un auxiliar opcional puede tener una omisión (bypass); un proxy de seguridad o autorización debe fallar de forma cerrada (fail closed) y detener el despliegue rápidamente cuando se supere su presupuesto de errores.
3. Manejar terminación, Jobs y vaciado de datos
Los sidecars nativos terminan después del contenedor de la aplicación, y múltiples sidecars se apagan en orden inverso. Por lo tanto, un agente de registros puede vaciar los búferes después de que la aplicación finalice, pero el período de gracia de terminación necesita un límite superior estricto. Registre la cantidad perdida cuando el vaciado agote el tiempo de espera; nunca espere indefinidamente.
Para un Job, verifique que el controlador considere la finalización del contenedor principal como la finalización del Job en lugar de esperar indefinidamente por un sidecar. El sidecar puede continuar reiniciándose antes de que el Job termine, por lo que debe exponer el resultado de la tarea, el resultado del vaciado del sidecar y la integridad final de los datos como señales y alertas separadas.
4. Verificar rutas de mutación y versiones
Los sidecars nativos son estables y están habilitados de forma predeterminada en Kubernetes v1.33; la funcionalidad estuvo en beta y habilitada por defecto desde la v1.29. Antes de la migración, compruebe de todos modos el kubelet real, el servidor de API, los componentes de admisión y los feature gates en cada grupo de nodos (node pool).
Un webhook mutador, una herramienta de plantillas o un cliente más antiguo pueden no comprender restartPolicy a nivel de contenedor y descartarlo al reescribir el objeto. Valide el objeto final en CI, registre la estructura del sidecar en los registros de admisión y ejecute un Pod de prueba que confirme el orden en tiempo de ejecución. Si no se puede confiar en la cadena, conserve una alternativa de contenedor regular o pause la migración.
5. Calcular el impacto en recursos y programación (scheduling)
Un sidecar no es gratuito. Sus solicitudes de CPU, memoria y almacenamiento efímero participan en el cálculo de recursos efectivos del Pod, afectando la QoS, la cuota y la programación. Utilice los picos de la aplicación, los picos de inicio del auxiliar y los límites de búfer para calcular requests y limits; observe la fragmentación de nodos, los desalojos (evictions), los OOM y el tiempo en cola de inicio.
Si el auxiliar necesita escalado independiente, una cadencia de lanzamientos separada o un dominio de fallas más amplio, un Deployment independiente puede ajustarse mejor. Un sidecar nativo ofrece uso compartido local y orden en el ciclo de vida, al tiempo que acopla la programación, los recursos y el lanzamiento en una sola unidad.
6. Diseñar canary, observabilidad y reversión
Prepare dos plantillas de Pod: sidecar nativo y el formato anterior de contenedor regular. Despliegue por espacio de nombres, etiqueta o carga de trabajo, con una condición de parada automática para cada lote. Monitoree al menos la latencia desde la creación del Pod hasta Ready, las fallas de readiness del sidecar, el conteo de reinicios, los errores en solicitudes de la aplicación, la profundidad del búfer, la pérdida de vaciado, los picos de CPU y memoria, y la latencia de finalización de Jobs.
Durante la migración, registre la estructura esperada y la observada; no basta con que el objeto Deployment sea exitoso. Si un webhook descarta campos, la latencia a Ready empeora o los reinicios del auxiliar cruzan el umbral, detenga la expansión y cambie a la plantilla anterior. La reversión también debe comprobar que las plantillas antiguas no hereden nuevas configuraciones, formatos de volumen o supuestos de puertos.
7. Integrar seguridad y observabilidad dentro del límite
Dado que el sidecar comparte la red y los volúmenes del Pod, tiene la misma superficie de acceso que este. Otórguele el menor privilegio posible, un sistema de archivos raíz de solo lectura, una cuenta de servicio explícita y una política de red. No omita los controles de auditoría por ser «solo un auxiliar». Añada etiquetas de Pod, contenedor y versión de lanzamiento a los registros, métricas y trazas para poder separar las fallas de la aplicación de las del auxiliar.
Respuesta de muestra de alta calidad
Primero clasificaría el auxiliar como una dependencia por Pod y confirmaría que realmente necesita redes o almacenamiento compartidos. Si se trata de una capacidad a nivel de nodo, elegiría un DaemonSet. La plantilla de migración utiliza un sidecar nativo: colocar el auxiliar en initContainers y configurar restartPolicy: Always a nivel de contenedor. Se inicia en orden de inicialización, su readinessProbe confirma que la configuración y el puerto son utilizables, y solo entonces la aplicación entra en servicio.
Dividiría las fallas en: falla de inicio, caída en ejecución y dependencia temporalmente no disponible. Un proxy de seguridad falla cerrado; una mejora opcional mantiene un bypass. Durante la terminación, el orden de apagado del sidecar posterior a la aplicación permite un vaciado acotado. Para los Jobs, verificaría la finalización del contenedor principal y el vaciado del sidecar por separado para que un auxiliar de larga duración no bloquee el estado del Job.
Antes del despliegue, comprobaría el servidor de API, cada grupo de nodos, los feature gates, los webhooks y los clientes de plantillas, ya que las herramientas antiguas pueden descartar restartPolicy. CI valida el objeto final y un despliegue canary valida el orden y la readiness reales del Pod. Los presupuestos de recursos incluyen los picos del auxiliar en QoS, cuotas y programación; los paneles muestran latencia a Ready, reinicios, errores, búferes y pérdidas. Se despliegan dos plantillas por lotes, y cualquier transgresión de umbrales detiene la expansión y revierte al formato antiguo. Esto aprovecha las garantías del ciclo de vida nativo mientras convierte los límites de versiones, recursos y fallas en compuertas de lanzamiento observables.
Errores comunes
- Pegar YAML sin explicar por qué se necesita un sidecar nativo o cuándo es mejor un contenedor regular o una carga de trabajo separada.
- Escribir
restartPolicy: Alwaysa nivel de Pod en lugar de dentro de la definición del contenedor del sidecar. - Configurar únicamente livenessProbe y omitir cómo una falla de readiness altera el tráfico y el comportamiento del despliegue.
- Asumir que la versión de Kubernetes es suficiente sin verificar el desfase en nodos, webhooks y clientes.
- Considerar que el sidecar es gratuito y pasar por alto su efecto en cuotas de recursos, picos de inicio, almacenamiento en búfer y QoS.
- Probar únicamente servicios de larga duración y olvidar la finalización de Jobs, el tiempo de espera de vaciado y el orden inverso de terminación.
- Revertir únicamente la imagen sin comprobar la plantilla antigua, los puertos, los volúmenes y la salida de admisión.
Preguntas de seguimiento y respuestas
¿Qué ocurre si un nodo antiguo no admite sidecars nativos?
Detenga el despliegue y aísle por grupo de nodos. Si no se puede garantizar que el objeto preserve la política a nivel de contenedor, use la plantilla de contenedor regular o actualice los nodos; descartar silenciosamente un campo desconocido no constituye compatibilidad.
¿Qué sucede cuando la readiness del sidecar falla continuamente?
El Pod debe permanecer fuera del estado Ready y el controlador de despliegue debe detener la expansión. Distinga entre errores de configuración, dependencias no disponibles y fallas en la sonda, y luego corrija o revierta. No oculte la falta de disponibilidad real haciendo que la sonda sea infinitamente permisiva.
¿El sidecar sigue ejecutándose después de que finaliza el contenedor principal de un Job?
Un sidecar nativo puede continuar ejecutándose y reiniciándose, mientras que el controlador del Job puede reconocer la finalización del contenedor principal. Limite el tiempo de vaciado y registre el resultado de la tarea de forma independiente de la integridad de los datos para que la actividad prolongada del auxiliar no se interprete erróneamente como un fallo de la tarea.
¿Por qué no utilizar un Deployment independiente para el proxy?
Elija la separación cuando el proxy requiera escalabilidad independiente, lanzamientos separados o un dominio de fallas más amplio. Elija un sidecar nativo cuando los sockets locales, la red compartida y un orden de inicio estricto sean esenciales. La decisión depende del acoplamiento y de los SLO.
¿Cómo diagnosticar una mayor presión de recursos tras la migración?
Compare las solicitudes efectivas del Pod, los picos de inicio, la fragmentación de nodos, los desalojos y los OOM antes y después de la migración; inspeccione los búferes y la concurrencia del auxiliar. Si el auxiliar solo proporciona capacidad a nivel de nodo, evalúe un DaemonSet. Si debe permanecer en el Pod, revise el presupuesto o reduzca el tamaño del canary.
¿Cómo demostrar que la reversión es segura?
Conserve el hash de la plantilla anterior. Durante la reversión, valide la estructura del contenedor, los puertos, los volúmenes, la cuenta de servicio y la salida del webhook, luego observe un lote canary respecto a latencia a Ready, tasa de error y pérdida de vaciado. Continúe la expansión únicamente después de que las señales se recuperen.