Planteamiento y alcance
Después de que un nodo arranca, kubelet puede reportar Ready incluso si un controlador de GPU, CNI, plugin de almacenamiento o agente local no está utilizable. Si el scheduler coloca Pods demasiado pronto, las cargas de trabajo fallan repetidamente o se degradan silenciosamente. Diseña un Node Readiness Controller que declare prerrequisitos adicionales, bloquee la programación hasta que se cumplan y maneje una dependencia que falle más adelante en el ciclo de vida del nodo.
Esto encaja en entrevistas de ingeniería de plataformas, SRE y controladores de Kubernetes. El material público de entrevistas de Kubernetes cubre nodos NotReady, taints y tolerations, y resolución de problemas de Pods en estado Pending. El proyecto oficial de Node Readiness Controller describe una API de NodeReadinessRule, administración automatizada de taints, modos solo de bootstrap y continuos, y dry run. El diseño a continuación es una respuesta razonada de entrevista, no una pregunta atribuida a una empresa.
Qué evalúa el entrevistador
El entrevistador quiere que separes "el nodo está Ready" de "el nodo es adecuado para esta clase de carga de trabajo". Una respuesta sólida define fuentes de condiciones, alcance de las reglas, idempotencia de taints, recuperación tras reinicios, estado observable y protección contra el bloqueo accidental de toda la flota.
Una respuesta débil escribe un DaemonSet que verifica todo. Una respuesta sólida explica por qué el reporte de condiciones está desacoplado de la aplicación de políticas, en qué se diferencia el modo solo de bootstrap de la aplicación continua, cómo el dry run estima el radio de impacto y cómo manejar condiciones obsoletas, particiones del controlador y reglas en conflicto.
Preguntas clarificadoras antes de responder
- ¿Debe el controlador proteger solo el bootstrap del nodo o también detener nueva programación cuando un controlador falle más adelante? Esto determina el modo de aplicación y la acción de recuperación.
- ¿Quién produce las condiciones: Node Problem Detector, un device plugin, un agente de CNI o un DaemonSet personalizado? Las fuentes no confiables necesitan verificaciones de identidad y de actualización.
- ¿Deben cumplirse todas las condiciones o basta con que pase una sola? GPU, red y almacenamiento generalmente necesitan diferentes pools de nodos y reglas.
- ¿Una condición falsa bloquea nuevos Pods o expulsa Pods existentes? Lo primero es reversible; lo segundo necesita evidencia más sólida y una política de expulsión separada.
Estructura de respuesta en 30 segundos
"Separaría el reporte de condiciones, la evaluación de reglas y la ejecución de taints. Una NodeReadinessRule selecciona nodos y enumera las condiciones que deben ser True; el controlador agrega o elimina un taint NoSchedule según la aplicación solo de bootstrap o continua. Las escrituras deben ser idempotentes, observables y capaces de ejecutar dry-run. Las reglas y el estado de las condiciones residen en el API server para que el estado se pueda reconstruir tras un reinicio. Primero registraría el impacto en logs, habilitaría un solo pool de nodos y, ante una falla, detendría las escrituras o revertiría la regla en lugar de dejar todo el clúster sin capacidad de programación".
Respuesta paso a paso
Comienza con el límite de responsabilidad. El controlador no sondea GPUs ni redes; consume Node Conditions. Node Problem Detector, un device plugin o un agente personalizado reportan hechos. Esto reutiliza el ecosistema de sondeo existente y separa "la comprobación falló" de "la programación está permitida". Una condición debe incluir tipo, estado, hora de actualización, fuente y una generación de observación; una condición obsoleta no puede seguir autorizando cargas de trabajo.
El modelo de reglas contiene un selector de nodos, conjunto de condiciones, taint de destino y modo de aplicación. El proyecto oficial requiere que cada condición listada se satisfaga antes de eliminar el taint y admite la selección de nodos heterogéneos mediante etiquetas. bootstrap-only deja de evaluar esa regla después de que la inicialización tiene éxito. continuous vuelve a agregar el taint cuando una condición crítica pasa a False más tarde. El primer modo se adapta a la precarga de imágenes o a la configuración de hardware; el segundo se adapta a dependencias que deben permanecer saludables.
El bucle de control lee reglas, nodos y condiciones, calcula los taints deseados y aplica actualizaciones mediante versiones de recursos. Las escrituras deben ser idempotentes y reintentarse en caso de conflicto: administra únicamente los taints que pertenecen a este controlador, nunca elimines el taint de un administrador o de otro controlador. Si dos reglas reclaman la misma clave de taint con significados diferentes, la validación de admisión debe rechazar el conflicto; de lo contrario, una regla puede eliminar accidentalmente la protección de otra regla.
Haz explícitas las rutas de falla. Cuando un reportero deja de actualizarse, fallar cerrado (fail-closed) o fallar abierto (fail-open) es una decisión de producto: una dependencia crítica de seguridad puede fallar cerrado, mientras que un bootstrap de bajo riesgo puede fallar abierto con un TTL corto. Un controlador desconectado no debe borrar los taints existentes; se reconcilia tras la recuperación. Si se elimina un nodo o cambian sus etiquetas, marca la regla como no aplicable para que el estado obsoleto no bloquee a un nodo de reemplazo.
La observabilidad debe incluir nodos coincidentes por regla, condiciones faltantes u obsoletas, discrepancia entre el taint deseado y el real, latencia desde que una condición pasa a True hasta la capacidad de programación y el recuento de Pods retenidos (gated-Pod). El estado debe exponer la condición fallida y la hora de la última evaluación sin registrar credenciales ni datos confidenciales del dispositivo. Para proteger el plano de control, encola por nodo y regla, agrupa cambios rápidos de condición y evita una escritura en el API-server por cada heartbeat.
Despliega con dry run. El dry run del proyecto oficial registra las acciones previstas y actualiza el estado de las reglas sin aplicar taints. Observa los nodos afectados y los Pods en Pending, luego habilita un pool de nodos. El rollback pausa la evaluación de nuevas reglas, preserva los taints de protección existentes, repara la fuente de la condición y reconcilia de nuevo; no elimina todos los taints NoSchedule con un solo comando.
Las alternativas incluyen agregar nodeSelector a cada carga de trabajo, usar Pod schedulingGates o agregar taints desde un script de bootstrap. Los selectores de carga de trabajo se adaptan a un conjunto reducido de consumidores conocidos, pero omiten futuros Pods. Un Pod gate protege a un Pod, mientras que este problema protege a un nodo. Los scripts carecen de estado compartido y recuperación. Un controlador se adapta a nodos heterogéneos y clústeres compartidos, a costa de un CRD, un bucle de control y otro dominio de falla.
Respuesta de ejemplo de alta calidad
Construiría un controlador declarativo responsable únicamente de "¿se pueden programar nuevos Pods aquí?". Node Problem Detector, los device plugins o los agentes de CNI escriben condiciones; el controlador no duplica sus sondeos. Una regla selecciona nodos, enumera las condiciones que deben ser True, nombra un taint NoSchedule y elige un modo. El trabajo de bootstrap usa bootstrap-only: una vez que el controlador de GPU y el agente de red están listos, se elimina el taint. Las dependencias continuas usan continuous: una falla posterior vuelve a agregar el taint, pero no expulsa los Pods existentes automáticamente.
El controlador posee y reconcilia únicamente los taints que llevan su marca de propietario, utilizando versiones de recursos y reintentos ante conflictos para garantizar la idempotencia. Las reclamaciones en conflicto para la misma clave de taint se rechazan. El estado de la regla reporta nodos coincidentes, condiciones faltantes u obsoletas, discrepancia de taints y tiempo de evaluación. Desplegaría dry run primero, compararía el impacto proyectado con los Pods en Pending y haría un canary en un pool de nodos. Durante la pérdida del controlador, mantén la protección existente; tras la recuperación, reconcilia. El rollback pausa la evaluación y repara la fuente de la condición en lugar de borrar todos los taints del clúster.
Errores comunes
- Error → Hacer que el controlador se conecte por SSH a cada nodo; fallo → elude las fuentes de condiciones de Kubernetes y amplía el límite de permisos; solución → dejar que agentes especializados reporten condiciones y mantener la evaluación de políticas en el controlador.
- Error → Usar
continuouspara el bootstrap de una sola vez; fallo → los nodos completados continúan fluctuando y permanecen no programables; solución → usarbootstrap-onlyy registrar la finalización. - Error → Eliminar cualquier taint con la misma clave; fallo → la protección de seguridad de un administrador o de otro controlador puede desaparecer; solución → usar marcas de propiedad, validación de conflictos y actualizaciones a nivel de campo.
- Error → Borrar todos los taints tras reiniciar el controlador; fallo → las cargas de trabajo caen en nodos no listos durante la ventana de recuperación; solución → preservar el estado y reconciliar con comprobaciones de versión de recursos.
Preguntas de seguimiento y respuestas
¿Qué pasa si el reportero de condiciones deja de actualizarse: fail-open o fail-closed?
Clasifica la dependencia. Los controladores de GPU, los módulos criptográficos y la red entre zonas pueden usar fail-closed con un tiempo de expiración, aceptando una pérdida temporal de capacidad. El bootstrap de bajo riesgo y de una sola vez puede usar fail-open con un registro exitoso y un TTL corto. En ambos casos, mide "unknown" por separado de False para que la falta de telemetría no se confunda con un buen estado de salud.
Dos reglas coinciden con un nodo y reclaman la misma clave de taint. ¿Qué haces?
Rechaza el conflicto semántico durante la admisión o la compilación de reglas, exigiendo claves distintas o un único propietario agregado explícito. El controlador mantiene el estado deseado para cada regla y elimina un taint agregado solo cuando cada propietario satisface su condición de liberación. La última regla en reconciliarse no debe eliminarlo por sí sola.
¿Cómo demuestras que el dry run no agotará la capacidad del clúster?
Reúne los nodos coincidentes, la capacidad programable disponible, las solicitudes de Pods y la dispersión topológica en un solo informe de impacto. Simula un pool de nodos, observa los Pods retenidos, las colas del autoscaler y la latencia de programación, y luego expande. Si las cargas de trabajo críticas carecen de margen de maniobra, cambia el pool de nodos o la regla antes de la aplicación obligatoria.
¿Por qué no expulsar los Pods existentes cuando un nodo falla en la preparación continua?
"No admitir nuevos Pods" y "los Pods existentes no son seguros" son decisiones independientes. NoSchedule preserva la continuidad mientras bloquea nuevas asignaciones; la expulsión necesita su propio PDB, terminación ordenada y política de seguridad de datos. Un controlador de expulsión independiente solo debe actuar cuando haya evidencia de que las cargas de trabajo existentes no son seguras.