En esta página, se proporciona un punto de partida para ayudarte a planificar y diseñar canalizaciones de CI/CD de GitOps para Kubernetes. GitOps, junto con herramientas como Config Sync, ofrece beneficios como una mejor estabilidad del código, una mejor legibilidad y la 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, existen muchas opciones para la arquitectura y la organización de tu aplicación y código de 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 deseen 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 Google Cloud , consulta Tareas y roles comunes de los usuarios de GKE Enterprise.
Organiza tus repositorios
Cuando configures tu arquitectura de GitOps, separa los repositorios según los tipos de archivos de configuración almacenados en cada uno. En un nivel alto, puedes considerar al menos cuatro tipos de repositorios:
- Es un repositorio de paquetes para grupos de parámetros de configuración relacionados.
- Un repositorio de plataforma para la configuración de la flota en clústeres y espacios de nombres.
- Un repositorio de configuración de la aplicación
- Un repositorio de código de la aplicación
En el siguiente diagrama, se muestra el diseño de estos repositorios:
En la Figura 2:
- Los equipos de desarrollo envían el código de las aplicaciones y sus configuraciones a un repositorio.
- El código de las apps y las configuraciones se almacena en el mismo lugar, y los equipos de aplicaciones tienen control sobre estos repositorios.
- Los equipos de aplicaciones envían código a una compilación.
Usa un repositorio de paquetes privado y centralizado
Usa un repositorio central para paquetes públicos o internos, como los 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
, usar repositorios de paquetes privados y centralizados puede ayudar a los equipos a encontrar información rápidamente. 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 solo puedan usar paquetes 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 promocionar paquetes en el repositorio central y transmitir actualizaciones.
Si bien administrar un repositorio central puede agregar una sobrecarga adicional, ya que alguien debe mantenerlo 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 produzcan interrupciones debido a la conectividad o la deserción upstream.
- Una combinación de revisores automatizados y manuales puede verificar si los paquetes tienen problemas antes de que estén disponibles para el público en general.
- El repositorio central proporciona una forma para que los equipos descubran qué se está usando y es compatible. 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 contenedores.
Crea repositorios WET
WET significa "Escribe todo dos veces". Contrasta con DRY, que significa "No te repitas". Estos enfoques representan dos tipos diferentes de archivos de configuración:
- Configuraciones DRY, en las que un solo archivo de configuración se somete a una acción de transformación para propagar campos con valores diferentes para diferentes entornos Por ejemplo, puedes tener una configuración de clúster compartida que se propague con una región o una configuración de seguridad diferentes para diferentes entornos.
- WET (o, a veces, "completamente hidratadas"), en las que cada archivo de configuración representa el 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 deseado de un archivo de configuración.
Realiza pruebas antes cuando valides los parámetros de configuración
Esperar a que el Sincronizador de configuración comience a sincronizarse para verificar si hay problemas puede crear confirmaciones de Git innecesarias y un largo ciclo de retroalimentación. Se pueden encontrar muchos problemas antes de que se aplique una configuración a un clúster con las funciones de validación kpt
.
Si bien debes agregar herramientas y lógica adicionales a tu proceso de confirmación, las pruebas antes de aplicar las configuraciones tienen los siguientes beneficios:
- Mostrar los cambios de configuración en una solicitud de cambio puede ayudar a evitar que los errores se conviertan en 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 prod
y dev
.
La principal desventaja de este enfoque es que usar carpetas no te permite promover 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:
- El descubrimiento de carpetas es más fácil que el de ramas.
- Es posible hacer una diferencia en las carpetas con muchas herramientas de CLI y GUI, mientras que la diferencia 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
ClusterSelectors
te permite 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. Si bien esta es una forma liviana de agregar atributos a un clúster, a medida que la cantidad de ClusterSelectors
crece con el tiempo, puede complicarse comprender el estado final del clúster.
Dado que el Sincronizador de configuración te permite sincronizar varios objetos RootSync
y RepoSync
a la vez, puedes agregar la configuración relevante a un repositorio independiente y
luego sincronizarla con los clústeres que desees. Esto facilita la comprensión del estado final del clúster y puedes ensamblar las configuraciones 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, un servicio que controla la administración del ciclo de vida debe administrar las tareas y otras tareas situacionales. Luego, puedes administrar ese servicio con el Sincronizador de configuración, en lugar de las tareas 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 el objeto y volver a crearlo. 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, se borra del clúster, el Sincronizador de configuración considera que se produjo un desfase del estado que elegiste y vuelve a crear el trabajo. Si especificas un tiempo de tiempo de actividad (TTL) del trabajo, el Sincronizador de configuración lo borra automáticamente y lo vuelve a crear y reiniciar, hasta que lo borres de la fuente de información.
Problemas de conciliación: Por lo general, Sincronizador de configuración espera a que los objetos se concilien después de aplicarse. Sin embargo, los trabajos se consideran reconciliados cuando comenzaron a ejecutarse. Esto significa que el Sincronizador de configuración no espera a que se complete la tarea antes de seguir aplicando otros objetos. Sin embargo, si el trabajo falla más adelante, se considera que no se pudo conciliar. En algunos casos, esto puede impedir que se sincronicen otros recursos y causar errores hasta que lo corrijas. En otros casos, es posible que la sincronización se realice correctamente y solo falle la conciliación.
Por estos motivos, no recomendamos sincronizar trabajos 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.
El enfoque no estructurado es el recomendado porque te permite organizar un repositorio de la manera que te resulte más conveniente.
En comparación, 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 parámetros de configuración. 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.
Cuando usas un repositorio no estructurado, se vuelve 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 Cómo convertir un repositorio jerárquico en un repositorio no estructurado.
Separa los repositorios de código y configuración
Cuando se escala un repositorio mono, 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 los commits en bucle. Por ejemplo, confirmar en un repositorio de código podría activar una solicitud de CI, que podría 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 realizan contribuciones.
- 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 separados para aislar los cambios
Cuando se escala un repositorio mono, se requieren permisos diferentes en diferentes carpetas. Por este motivo, separar los repositorios permite establecer límites de seguridad entre la seguridad, la plataforma y la configuración de la aplicación. También es una buena idea separar los repositorios de producción y no producción.
Si bien administrar muchos repositorios puede ser una tarea grande en sí misma, aislar diferentes tipos de configuración en diferentes repositorios tiene los siguientes beneficios:
- En una organización con equipos de plataforma, seguridad y aplicación, la cadencia de los cambios y los permisos es diferente.
- Los permisos permanecen 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.
Cómo fijar versiones de paquetes
Ya sea que uses Helm o Git, debes fijar la versión del paquete de configuración a algo que no se avance accidentalmente sin un lanzamiento explícito.
Si bien 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 la federación de identidades para cargas de trabajo para 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 forma segura y administrable.
Aunque algunos servicios que no son deGoogle Cloud , 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.