Prácticas recomendadas de GitOps

En esta página, se proporciona un punto de partida para ayudarte a planificar y diseñar canalizaciones de GitOps de CI/CD para Kubernetes. GitOps, junto con herramientas como el Sincronizador de configuración, ofrece beneficios como una mayor estabilidad del código, una mejor legibilidad y automatización.

GitOps es un enfoque de rápido crecimiento para administrar la configuración de Kubernetes a gran escala. Según los requisitos de tu canalización de CI/CD, hay muchas opciones para diseñar y organizar el código de la aplicación y de la configuración. Si aprendes algunas prácticas recomendadas de GitOps, puedes crear una arquitectura estable, bien organizada y segura.

Esta página está destinada a administradores, arquitectos y operadores que desean implementar GitOps en su entorno. Para obtener más información sobre los roles comunes y las tareas de ejemplo a las que hacemos referencia en el contenido de Cloud de Confiance by S3NS , consulta Roles y tareas comunes del usuario de GKE.

Organiza tus repositorios

Cuando configures tu arquitectura de GitOps, separa tus repositorios según los tipos de archivos de configuración almacenados en cada repositorio. En un nivel alto, puedes considerar al menos cuatro tipos de repositorios:

  1. Es un repositorio de paquetes para grupos de parámetros de configuración relacionados.
  2. Un repositorio de plataforma para la configuración de toda la flota de clústeres y espacios de nombres.
  3. Un repositorio de configuración de la aplicación
  4. Un repositorio de código de la aplicación

Usa un repositorio de paquetes privado y centralizado

Usa un repositorio central para paquetes públicos o internos, como gráficos de Helm,para ayudar a los equipos a encontrar paquetes. Por ejemplo, si el repositorio está estructurado de forma lógica o contiene un readme, el uso de repositorios de paquetes centralizados y privados puede ayudar a los equipos a encontrar información con rapidez. Puedes usar servicios como Artifact Registry o repositorios de Git para organizar tu repositorio central.

Por ejemplo, el equipo de la plataforma de tu organización puede implementar políticas en las que los equipos de aplicaciones puedan usar paquetes solo del repositorio central.

Puedes limitar los permisos de escritura en el repositorio a solo una pequeña cantidad de ingenieros. El resto de la organización puede tener acceso de lectura. Te recomendamos implementar un proceso para promover paquetes en el repositorio central y transmitir actualizaciones.

Aunque administrar un repositorio central puede agregar cierta sobrecarga adicional, ya que alguien debe mantener el repositorio central, y agrega un proceso adicional para los equipos de aplicaciones, este enfoque tiene muchos beneficios:

  • Un equipo central puede optar por agregar paquetes públicos con una cadencia definida, lo que ayuda a evitar que se interrumpa por la conectividad o la deserción ascendente.
  • Una combinación de revisores humanos y automatizados puede verificar los paquetes en busca de problemas antes de que estén disponibles de forma generalizada.
  • El repositorio central proporciona una forma para que los equipos descubran qué se usa y qué se admite. Por ejemplo, los equipos pueden encontrar la implementación estándar de Redis almacenada en el repositorio central.
  • Puedes automatizar los cambios en los paquetes upstream para asegurarte de que cumplan con los estándares internos, como los valores predeterminados, la adición de etiquetas y los repositorios de imágenes de contenedor.

Crea repositorios de WET

WET significa "Write Everything Twice" (escribe todo dos veces). Se diferencia de DRY, que significa "No te repitas". Estos enfoques representan dos tipos diferentes de archivos de configuración:

  • Parámetros de configuración DRY, en los que un solo archivo de configuración se somete a una acción de transformación para propagar campos con valores diferentes para entornos distintos. Por ejemplo, podrías tener una configuración de clúster compartida que se complete con una región diferente o con parámetros de configuración de seguridad distintos para entornos diferentes.
  • Parámetros de configuración WET (o, a veces, "completamente hidratados"), en los que cada archivo de configuración es representativo del estado final.

Aunque los repositorios WET pueden generar algunos archivos de configuración repetidos, tienen los siguientes beneficios para un flujo de trabajo de GitOps:

  • Es más fácil para los miembros del equipo revisar los cambios.
  • No se requiere ningún procesamiento para ver el estado previsto de un archivo de configuración.

Realiza pruebas antes de validar los parámetros de configuración

Esperar hasta que el Sincronizador de configuración comience a sincronizarse para verificar si hay problemas puede crear confirmaciones de Git innecesarias y un ciclo de reacción largo. Se pueden encontrar muchos problemas antes de que se aplique una configuración a un clúster con las funciones de validador de kpt.

Aunque debes agregar herramientas y lógica adicionales a tu proceso de confirmación, realizar pruebas antes de aplicar los parámetros de configuración tiene los siguientes beneficios:

  • Mostrar los cambios de configuración en una solicitud de cambio puede ayudar a evitar que los errores lleguen a un repositorio.
  • Reduce el impacto de los problemas en las configuraciones compartidas.

Usa carpetas en lugar de ramas

Usa carpetas para las variantes de los archivos de configuración en lugar de ramas. Con las carpetas, puedes usar el comando tree para ver las variantes. Con las ramas, no puedes saber si la diferencia entre una rama de producción y una de desarrollo es un cambio próximo en la configuración o una diferencia permanente entre cómo deberían verse los entornos de prod y dev.

La principal desventaja de este enfoque es que el uso de carpetas no te permite promover los cambios de configuración con una solicitud de cambio en los mismos archivos. Sin embargo, usar carpetas en lugar de ramas tiene los siguientes beneficios:

  • Es más fácil descubrir carpetas que ramas.
  • Es posible realizar una comparación de diferencias en las carpetas con muchas herramientas de CLI y GUI, mientras que la comparación de diferencias de ramas es menos común fuera de los proveedores de Git.
  • Diferenciar entre las diferencias permanentes y las diferencias no promocionadas es más fácil con las carpetas.
  • Puedes implementar cambios en varios clústeres y espacios de nombres en una solicitud de cambio, mientras que las ramas requieren varias solicitudes de cambio en diferentes ramas.

Minimiza el uso de ClusterSelectors

Los ClusterSelectors te permiten aplicar ciertas partes de una configuración a un subconjunto de clústeres. En lugar de configurar un objeto RootSync o RepoSync, puedes modificar el recurso que se aplica o agregar etiquetas a los clústeres. Aunque esta es una forma ligera de agregar rasgos a un clúster, a medida que aumenta la cantidad de ClusterSelectors con el tiempo, puede ser complicado comprender el estado final del clúster.

Como el Sincronizador de configuración te permite sincronizar varios objetos RootSync y RepoSync a la vez, puedes agregar la configuración pertinente a un repositorio independiente y, luego, sincronizarla con los clústeres que quieras. Esto facilita la comprensión del estado final del clúster, y puedes reunir los parámetros de configuración del clúster en una carpeta en lugar de aplicar esas decisiones de configuración directamente en el clúster.

Evita administrar trabajos con el Sincronizador de configuración

En la mayoría de los casos, los objetos Job y otras tareas situacionales deben administrarse con un servicio que se encargue de su ciclo de vida. Luego, puedes administrar ese servicio con el Sincronizador de configuración, en lugar de los trabajos en sí.

Si bien el Sincronizador de configuración puede aplicar trabajos por ti, estos no son adecuados para las implementaciones de GitOps por los siguientes motivos:

  • Campos inmutables: Muchos campos de Job son inmutables. Para cambiar un campo inmutable, se debe borrar y volver a crear el objeto. Sin embargo, el Sincronizador de configuración no borra tu objeto, a menos que lo quites de la fuente.

  • Ejecución no deseada de trabajos: Si sincronizas un trabajo con el Sincronizador de configuración y, luego, ese trabajo se borra del clúster, el Sincronizador de configuración considera que se desvía del estado elegido y vuelve a crear el trabajo. Si especificas un tiempo de actividad (TTL) del trabajo, el Sincronizador de configuración borra el trabajo de forma automática y lo vuelve a crear y reiniciar, hasta que lo borres de la fuente de información.

  • Problemas de conciliación: Por lo general, el Sincronizador de configuración espera a que los objetos se concilien después de aplicarse. Sin embargo, los objetos Job se consideran conciliados cuando comienzan a ejecutarse. Esto significa que el Sincronizador de configuración no espera a que el trabajo se complete antes de seguir aplicando otros objetos. Sin embargo, si el objeto Job falla más adelante, se considera un error de conciliación. En algunos casos, esto puede impedir que se sincronicen otros recursos y causar errores hasta que lo corrijas. En otros casos, la sincronización puede tener éxito y solo falla la conciliación.

Por estos motivos, no recomendamos sincronizar los objetos Job con el Sincronizador de configuración.

Usa repositorios no estructurados

El Sincronizador de configuración admite dos estructuras para organizar un repositorio: no estructurado y jerárquico.

No estructurado es el enfoque recomendado, ya que te permite organizar un repositorio de la manera que te resulte más conveniente. En cambio, los repositorios jerárquicos aplican una estructura específica, como las definiciones de recursos personalizados (CRD) en un directorio cluster. Esto puede causar problemas cuando necesites compartir configuraciones. Por ejemplo, si un equipo publica un paquete que contiene una CRD, otro equipo que necesite usar ese paquete tendría que mover la CRD a un directorio cluster, lo que agregaría más sobrecarga al proceso.

Con un repositorio no estructurado, es mucho más fácil compartir y reutilizar paquetes de configuración. Sin embargo, sin un proceso o lineamientos definidos para organizar los repositorios, las estructuras de los repositorios pueden variar entre los equipos, lo que puede dificultar la implementación de herramientas para toda la flota.

Para aprender a convertir un repositorio jerárquico, consulta Convierte un repositorio jerárquico en un repositorio no estructurado.

Separa los repositorios de código y configuración

Cuando se escala un monorrepositorio, se requiere una compilación específica para cada carpeta. Los permisos y las inquietudes de las personas que trabajan en el código y en la configuración del clúster suelen ser diferentes.

Separar los repositorios de código y configuración tiene los siguientes beneficios:

  • Evita las confirmaciones "en bucle". Por ejemplo, confirmar un repositorio de código puede activar una solicitud de CI, que puede producir una imagen, que, luego, requiere una confirmación de código.
  • La cantidad de confirmaciones requeridas puede convertirse en una carga para los miembros del equipo que contribuyen.
  • Puedes usar diferentes permisos para las personas que trabajan en el código de la aplicación y la configuración del clúster.

Separar los repositorios de código y configuración tiene las siguientes desventajas:

  • Reduce el descubrimiento de la configuración de la aplicación, ya que no se encuentra en el mismo repositorio que el código de la aplicación.
  • Administrar muchos repositorios puede llevar mucho tiempo.

Usa repositorios independientes para aislar los cambios

Cuando se escala un repositorio único, se requieren diferentes permisos en distintas carpetas. Por este motivo, separar los repositorios permite establecer límites de seguridad entre la configuración de seguridad, la plataforma y la aplicación. También es una buena idea separar los repositorios de producción y los que no son de producción.

Aunque administrar muchos repositorios puede ser una tarea grande por sí sola, aislar diferentes tipos de configuración en diferentes repositorios tiene los siguientes beneficios:

  • En una organización con equipos de plataforma, seguridad y aplicaciones, el ritmo de los cambios y los permisos son diferentes.
  • Los permisos se mantienen a nivel del repositorio. Los archivos CODEOWNERS permiten que las organizaciones limiten el permiso de escritura y, al mismo tiempo, permitan el permiso de lectura.
  • El Sincronizador de configuración admite varias sincronizaciones por espacio de nombres, lo que puede lograr un efecto similar al de obtener archivos de varios repositorios.

Fija las versiones de los paquetes

Ya sea que uses Helm o Git, debes fijar la versión del paquete de configuración en un valor que no se mueva de forma accidental sin un lanzamiento explícito.

Aunque esto agrega verificaciones adicionales a tus lanzamientos cuando se actualiza una configuración compartida, reduce el riesgo de que las actualizaciones compartidas tengan un impacto mayor de lo previsto.

Usa Workload Identity Federation for GKE

Puedes habilitar la federación de identidades para cargas de trabajo para GKE en los clústeres de GKE, lo que permite que las cargas de trabajo de Kubernetes accedan a los servicios de Google de una manera segura y administrable.

Aunque algunos servicios que no son deCloud de Confiance by S3NS , como GitHub y GitLab, no admiten la federación de identidades para cargas de trabajo para GKE, debes intentar usar la federación de identidades para cargas de trabajo para GKE siempre que sea posible debido a la mayor seguridad y la reducción de la complejidad de administrar secretos y contraseñas.

¿Qué sigue?