Etiquetado basado en contenido en el generador de werf: ¿por qué y cómo funciona?

Etiquetado basado en contenido en el generador de werf: ¿por qué y cómo funciona?

patio es nuestra utilidad GitOps CLI de código abierto para crear y entregar aplicaciones a Kubernetes. EN lanzamiento v1.1 Se introdujo una nueva característica en el recopilador de imágenes: etiquetar imágenes por contenido o etiquetado basado en contenido. Hasta ahora, el esquema de etiquetado típico en werf implicaba etiquetar imágenes de Docker mediante una etiqueta Git, una rama Git o una confirmación Git. Pero todos estos esquemas tienen desventajas que se resuelven completamente con la nueva estrategia de etiquetado. Los detalles sobre él y por qué es tan bueno se encuentran debajo del corte.

Implementación de un conjunto de microservicios desde un repositorio Git

A menudo ocurre una situación en la que una aplicación se divide en muchos servicios más o menos independientes. Los lanzamientos de estos servicios pueden ocurrir de forma independiente: se pueden lanzar uno o más servicios a la vez, mientras que el resto debe continuar funcionando sin ningún cambio. Pero desde el punto de vista del almacenamiento de código y la gestión de proyectos, es más conveniente mantener dichos servicios de aplicaciones en un único repositorio.

Hay situaciones en las que los servicios son verdaderamente independientes y no están asociados a una sola aplicación. En este caso, estarán ubicados en proyectos separados y su liberación se realizará mediante procesos CI/CD separados en cada uno de los proyectos.

Sin embargo, en realidad, los desarrolladores a menudo dividen una sola aplicación en varios microservicios, pero crear un repositorio y un proyecto separados para cada uno... es claramente una exageración. Esta es la situación que se analizará más a fondo: varios de estos microservicios se encuentran en un único repositorio de proyecto y los lanzamientos se producen a través de un único proceso en CI/CD.

Etiquetado por rama de Git y etiqueta de Git

Digamos que se utiliza la estrategia de etiquetado más común: etiqueta o rama. Para las ramas de Git, las imágenes se etiquetan con el nombre de la rama; para una rama a la vez, solo hay una imagen publicada con el nombre de esa rama. Para las etiquetas de Git, las imágenes se etiquetan según el nombre de la etiqueta.

Cuando se crea una nueva etiqueta Git (por ejemplo, cuando se lanza una nueva versión), se creará una nueva etiqueta Docker para todas las imágenes del proyecto en Docker Registry:

  • myregistry.org/myproject/frontend:v1.1.10
  • myregistry.org/myproject/myservice1:v1.1.10
  • myregistry.org/myproject/myservice2:v1.1.10
  • myregistry.org/myproject/myservice3:v1.1.10
  • myregistry.org/myproject/myservice4:v1.1.10
  • myregistry.org/myproject/myservice5:v1.1.10
  • myregistry.org/myproject/database:v1.1.10

Estos nuevos nombres de imágenes se pasan a través de plantillas de Helm a la configuración de Kubernetes. Al iniciar el despliegue con el comando werf deploy El campo se está actualizando. image en los manifiestos de recursos de Kubernetes y reiniciando los recursos correspondientes debido al cambio de nombre de la imagen.

problema: en el caso de que, de hecho, el contenido de la imagen no haya cambiado desde el lanzamiento anterior (etiqueta Git), sino solo su etiqueta Docker, esto sucede exceso reiniciar esta aplicación y, en consecuencia, es posible que se produzca algún tiempo de inactividad. Aunque no había ningún motivo real para realizar este reinicio.

Como resultado, con el esquema de etiquetado actual es necesario cercar varios repositorios Git separados y surge el problema de organizar el despliegue de estos diversos repositorios. En general, un esquema de este tipo resulta sobrecargado y complejo. Es mejor combinar muchos servicios en un solo repositorio y crear etiquetas Docker para que no haya reinicios innecesarios.

Etiquetado por compromiso de Git

werf también tiene una estrategia de etiquetado asociada con las confirmaciones de Git.

Git-commit es un identificador del contenido de un repositorio Git y depende del historial de edición de archivos en el repositorio Git, por lo que parece lógico usarlo para etiquetar imágenes en el Registro Docker.

Sin embargo, el etiquetado mediante confirmación de Git tiene las mismas desventajas que el etiquetado mediante ramas de Git o etiquetas de Git:

  • Se podría crear una confirmación vacía que no cambie ningún archivo, pero se cambiará la etiqueta Docker de la imagen.
  • Se podría crear una confirmación de fusión que no cambie los archivos, pero se cambiará la etiqueta Docker de la imagen.
  • Se podría realizar una confirmación que cambie aquellos archivos en Git que no se importan a la imagen, y la etiqueta Docker de la imagen se cambiará nuevamente.

Etiquetar el nombre de la rama de Git no refleja la versión de la imagen

Hay otro problema asociado con la estrategia de etiquetado para las ramas de Git.

El etiquetado por nombre de rama funciona siempre que las confirmaciones en esa rama se recopilen secuencialmente en orden cronológico.

Si en el esquema actual el usuario comienza a reconstruir una confirmación anterior asociada con una determinada rama, entonces werf reescribirá la imagen usando la etiqueta Docker correspondiente con una versión recién creada de la imagen para la confirmación anterior. Las implementaciones que utilizan esta etiqueta a partir de ahora corren el riesgo de extraer una versión diferente de la imagen al reiniciar los pods, como resultado de lo cual nuestra aplicación perderá la conexión con el sistema CI y quedará desincronizada.

Además, con inserciones sucesivas en una rama con un corto período de tiempo entre ellas, la confirmación anterior puede compilarse más tarde que la más nueva: la versión anterior de la imagen sobrescribirá la nueva usando la etiqueta de rama de Git. Estos problemas pueden resolverse mediante un sistema CI/CD (por ejemplo, en GitLab CI el proceso de este último se inicia para una serie de confirmaciones). Sin embargo, no todos los sistemas admiten esto y debe haber una manera más confiable de prevenir un problema tan fundamental.

¿Qué es el etiquetado basado en contenido?

Entonces, ¿qué es el etiquetado basado en contenido? Etiquetar imágenes por contenido.

Para crear etiquetas Docker, no se utilizan primitivas de Git (rama Git, etiqueta Git...), sino una suma de comprobación asociada con:

  • contenido de la imagen. La etiqueta de identificación de la imagen refleja su contenido. Al crear una nueva versión, este identificador no cambiará si los archivos de la imagen no han cambiado;
  • Historia de la creación de esta imagen en Git.. Las imágenes asociadas con diferentes ramas de Git y diferentes historiales de compilación a través de werf tendrán diferentes etiquetas de identificación.

Una etiqueta de identificación de este tipo es la denominada firma de la etapa de la imagen.

Cada imagen consta de un conjunto de etapas: from, before-install, git-archive, install, imports-after-install, before-setup, ... git-latest-patch etc. Cada etapa tiene un identificador que refleja su contenido: firma escénica (firma del escenario).

La imagen final, que consta de estas etapas, está etiquetada con la llamada firma del conjunto de estas etapas: firma de etapas, - que es generalizador para todas las etapas de la imagen.

Para cada imagen de la configuración werf.yaml en el caso general, habrá su propia firma y, en consecuencia, una etiqueta Docker.

La firma del escenario resuelve todos estos problemas:

  • Resistente a confirmaciones de Git vacías.
  • Resistente a los commits de Git que cambian archivos que no son relevantes para la imagen.
  • No genera el problema de revisar la versión actual de la imagen al reiniciar las compilaciones para confirmaciones de Git antiguas de una rama.

Esta es ahora la estrategia de etiquetado recomendada y es la opción predeterminada en werf para todos los sistemas CI.

Cómo habilitar y usar en werf

El comando ahora tiene una opción correspondiente. werf publish: --tag-by-stages-signature=true|false

En un sistema CI, la estrategia de etiquetado se especifica mediante el comando werf ci-env. Anteriormente, el parámetro estaba definido para ello. werf ci-env --tagging-strategy=tag-or-branch. Ahora bien, si especificas werf ci-env --tagging-strategy=stages-signature o no especifica esta opción, werf usará la estrategia de etiquetado de forma predeterminada stages-signature. Equipo werf ci-env establecerá automáticamente las banderas necesarias para el comando werf build-and-publish (o werf publish), por lo que no es necesario especificar opciones adicionales para estos comandos.

Por ejemplo, el comando:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-by-stages-signature

...puede crear las siguientes imágenes:

  • registry.hello.com/web/core/system/backend:4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d
  • registry.hello.com/web/core/system/frontend:f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6

es 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d es una firma de las etapas de la imagen backendY f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 - firma de etapas de imagen frontend.

Cuando se utilizan funciones especiales werf_container_image и werf_container_env No es necesario cambiar nada en las plantillas de Helm: estas funciones generarán automáticamente los nombres de imágenes correctos.

Configuración de ejemplo en un sistema CI:

type multiwerf && source <(multiwerf use 1.1 beta)
type werf && source <(werf ci-env gitlab)
werf build-and-publish|deploy

Más información sobre la configuración está disponible en la documentación:

En total

  • Nueva opción werf publish --tag-by-stages-signature=true|false.
  • Nuevo valor de opción werf ci-env --tagging-strategy=stages-signature|tag-or-branch (si no se especifica, el valor predeterminado será stages-signature).
  • Si anteriormente utilizó las opciones de etiquetado para confirmaciones de Git (WERF_TAG_GIT_COMMIT u opción werf publish --tag-git-commit COMMIT), luego asegúrese de cambiar a la estrategia de etiquetado firma-etapas.
  • Es mejor cambiar inmediatamente los nuevos proyectos al nuevo esquema de etiquetado.
  • Al realizar la transferencia a werf 1.1, es aconsejable cambiar los proyectos antiguos al nuevo esquema de etiquetado, pero el antiguo etiqueta o rama todavía es compatible.

El etiquetado basado en contenido resuelve todos los problemas tratados en el artículo:

  • Resistencia del nombre de la etiqueta Docker a confirmaciones de Git vacías.
  • Resiliencia del nombre de la etiqueta Docker para confirmaciones de Git que cambian archivos irrelevantes para la imagen.
  • No genera el problema de revisar la versión actual de la imagen al reiniciar compilaciones para confirmaciones de Git antiguas para ramas de Git.

¡Úselo! Y no olvides visitarnos en GitHubpara crear un problema o encontrar uno existente, agregar un plus, crear un PR o simplemente observar el desarrollo del proyecto.

PS

Lea también en nuestro blog:

Fuente: habr.com

Añadir un comentario