Planteamiento y contexto
Kubernetes v1.36 promovió la validación declarativa a GA y habilitó el feature gate DeclarativeValidation de forma predeterminada. Las reglas se escriben como marcadores +k8s: junto a las definiciones de tipos y luego son generadas por validation-gen. La pregunta evalúa si puede conectar contratos de API, generadores, compatibilidad y operaciones de lanzamiento.
Qué evalúa el entrevistador
- Si puede explicar los riesgos de mantenimiento y consistencia en la validación escrita a mano.
- Si distingue entre reglas declarativas, código generado, exposición en OpenAPI y rechazo en tiempo de ejecución.
- Si explica correctamente cómo afecta el ambient ratcheting a las actualizaciones de objetos antiguos.
- Si diseña pruebas, reversión (rollback) y migración gradual para que el endurecimiento de las reglas no rompa los objetos almacenados.
Preguntas para aclarar primero
Confirme si la API es un tipo nativo de Kubernetes o un CRD, si los clientes dependen de OpenAPI y si la restricción es nueva, relajada o endurecida. También confirme si los objetos antiguos contienen valores que históricamente fueron aceptados y qué versiones de generador, linter y servidor deben interoperar.
Una respuesta de 30 segundos
La validación declarativa coloca las restricciones junto a las definiciones de tipos, permite que un único generador produzca código consistente y hace que las reglas estén disponibles para OpenAPI. El plan debe cubrir el diseño de reglas, la generación y comprobaciones estáticas, la validación en tiempo de ejecución del servidor, la compatibilidad con objetos antiguos y la reversión. Al endurecer una regla, el ambient ratcheting protege un campo heredado que no cambia, pero los nuevos valores aún necesitan una revisión de compatibilidad y una validación por etapas.
Análisis detallado paso a paso
1. Definir la fuente de la regla
Utilice marcadores como +k8s:required, +k8s:minimum=0 o restricciones de enumeración para que las reglas sean fáciles de descubrir junto a los campos. Para invariantes entre campos, documente el invariante, el mensaje de error y las versiones compatibles en lugar de ocultar la lógica de negocio fuera del generador.
2. Generar y verificar
validation-gen analiza los marcadores, genera funciones de validación de Go y las registra con el esquema de la API. CI ejecuta el generador, las pruebas unitarias, kube-api-linter y comprobaciones de diferencias (diff) de OpenAPI para que los marcadores, el código generado y el esquema público no diverjan. Los archivos generados deben ser reproducibles y nunca editarse a mano.
3. Gestionar la evolución de versiones
Evalúe los objetos almacenados y el comportamiento del cliente antes de agregar una restricción. El ambient ratcheting compara objetos antiguos y nuevos: si un campo no cambia semánticamente, la nueva regla no bloquea la actualización debido a su valor antiguo; si el campo cambia, se aplica la nueva regla. El endurecimiento aún necesita herramientas de migración, métricas de auditoría y errores claros.
4. Lanzamiento y reversión
Mida las tasas de rechazo en suites de compatibilidad y validación en la sombra (shadow validation) antes del despliegue por etapas. Monitoree códigos de error de API, versiones de recursos y reintentos de clientes. Si las tasas de error se disparan, revierta la versión del generador o de la regla mientras mantiene legibles los objetos aceptados. Un feature gate en GA habilitado de forma predeterminada no elimina las pruebas de migración.
Ejemplo de una respuesta sólida
Trato la validación como un contrato de API versionado. Marcadores como +k8s: expresan restricciones de campo, validation-gen produce código Go reproducible y CI utiliza pruebas unitarias, un linter y diferencias de OpenAPI para mantener alineadas las tres vistas. Los invariantes entre campos necesitan pruebas dedicadas y errores estables, y los archivos generados no deben editarse manualmente.
Antes de endurecer una regla, reproduzco los objetos almacenados y mido el comportamiento del cliente. El ambient ratcheting solo exime un valor heredado que no cambia; una vez que un usuario edita ese campo, se aplica la nueva regla, por lo que las herramientas de migración y el despliegue por etapas siguen siendo necesarios. Tras el lanzamiento, observo las tasas de rechazo, la distribución de versiones y los reintentos, revirtiendo la versión de la regla si es necesario. GA proporciona un mecanismo unificado, no un sustituto para la gobernanza de compatibilidad.
Errores comunes
- Tratar al generador como una herramienta de formateo y pasar por alto su papel en el comportamiento del servidor en tiempo de ejecución.
- Tratar a OpenAPI como el único punto de validación mientras se ignora el código generado del servidor y la compatibilidad de versiones.
- Malinterpretar el ambient ratcheting como una relajación permanente a pesar de que los campos editados aún se someten a una nueva validación.
- Agregar reglas sin un plan de migración, métricas de despliegue o una ruta de reversión para los objetos almacenados.
Preguntas de seguimiento y respuestas
¿Por qué no seguir escribiendo funciones de validación a mano?
La lógica escrita a mano está dispersa, es difícil de descubrir y es propensa a un comportamiento inconsistente entre recursos. Los marcadores, un generador y un linter hacen que las reglas sean revisables, reproducibles y más fáciles de publicar a través de OpenAPI.
¿Endurecer un mínimo rompería inmediatamente los objetos antiguos?
Una actualización que deja el campo sin cambios puede conservar su valor histórico mediante ambient ratcheting. Crear un objeto o editar ese campo debe satisfacer la nueva regla, por lo que los clientes que leen, copian o reescriben objetos aún necesitan revisión.
¿Cómo demuestra que el código generado no ha divergido?
Fije la versión del generador en CI, ejecute la generación y falle si el árbol de trabajo cambia. Compare OpenAPI, pruebas unitarias y el comportamiento de rechazo de extremo a extremo; revise el diff generado antes de implementar una actualización del generador.