Balisage basé sur le contenu dans le werf builder : pourquoi et comment ça marche ?

Balisage basé sur le contenu dans le werf builder : pourquoi et comment ça marche ?

cour est notre utilitaire CLI GitOps open source pour créer et fournir des applications sur Kubernetes. DANS version v1.1 une nouvelle fonctionnalité a été introduite dans le collecteur d'images : le marquage des images par contenu ou balisage basé sur le contenu. Jusqu'à présent, le schéma de balisage typique dans werf impliquait le balisage des images Docker par balise Git, branche Git ou commit Git. Mais tous ces systèmes présentent des défauts qui sont entièrement résolus par la nouvelle stratégie de marquage. Les détails à ce sujet et pourquoi il est si bon se trouvent sous la coupe.

Déployer un ensemble de microservices à partir d'un référentiel Git

Il arrive souvent qu'une application soit divisée en plusieurs services plus ou moins indépendants. Les versions de ces services peuvent se produire indépendamment : un ou plusieurs services peuvent être publiés à la fois, tandis que les autres doivent continuer à fonctionner sans aucun changement. Mais du point de vue du stockage du code et de la gestion de projet, il est plus pratique de conserver ces services applicatifs dans un référentiel unique.

Il existe des situations où les services sont véritablement indépendants et non associés à une seule application. Dans ce cas, ils seront situés dans des projets distincts et leur publication sera effectuée via des processus CI/CD distincts dans chaque projet.

Cependant, en réalité, les développeurs divisent souvent une seule application en plusieurs microservices, mais créer un référentiel et un projet distincts pour chacun... est clairement excessif. C'est cette situation qui sera discutée plus en détail : plusieurs de ces microservices sont situés dans un seul référentiel de projet et les versions se produisent via un seul processus dans CI/CD.

Balisage par branche Git et balise Git

Disons que la stratégie de marquage la plus courante est utilisée : étiquette ou branche. Pour les branches Git, les images sont étiquetées avec le nom de la branche, pour une branche à la fois, il n'y a qu'une seule image publiée portant le nom de cette branche. Pour les balises Git, les images sont balisées en fonction du nom de la balise.

Lorsqu'une nouvelle balise Git est créée (par exemple, lorsqu'une nouvelle version est publiée), une nouvelle balise Docker sera créée pour toutes les images de projet dans le registre Docker :

  • 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

Ces nouveaux noms d'image sont transmis via les modèles Helm à la configuration Kubernetes. Au démarrage du déploiement avec la commande werf deploy le champ est en cours de mise à jour image dans les manifestes de ressources Kubernetes et en redémarrant les ressources correspondantes en raison du nom modifié de l'image.

problème: dans le cas où en fait le contenu de l'image n'a pas changé depuis le déploiement précédent (balise Git), mais seulement sa balise Docker, cela se produit superflue redémarrer cette application et, par conséquent, un certain temps d'arrêt est possible. Bien qu’il n’y ait aucune raison réelle d’effectuer ce redémarrage.

En conséquence, avec le schéma de balisage actuel, il est nécessaire de clôturer plusieurs référentiels Git distincts et le problème se pose d'organiser le déploiement de ces différents référentiels. En général, un tel schéma s’avère surchargé et complexe. Il est préférable de combiner plusieurs services dans un seul référentiel et de créer des balises Docker afin d'éviter tout redémarrage inutile.

Balisage par commit Git

werf a également une stratégie de marquage associée aux commits Git.

Git-commit est un identifiant pour le contenu d'un référentiel Git et dépend de l'historique des modifications des fichiers dans le référentiel Git, il semble donc logique de l'utiliser pour baliser des images dans le registre Docker.

Cependant, le balisage par commit Git présente les mêmes inconvénients que le balisage par branches Git ou balises Git :

  • Un commit vide peut être créé qui ne modifie aucun fichier, mais la balise Docker de l'image sera modifiée.
  • Une validation de fusion pourrait être créée sans modifier les fichiers, mais la balise Docker de l'image sera modifiée.
  • Une validation pourrait être effectuée pour modifier les fichiers dans Git qui ne sont pas importés dans l'image, et la balise Docker de l'image sera à nouveau modifiée.

Le marquage du nom de la branche Git ne reflète pas la version de l'image

Il existe un autre problème lié à la stratégie de marquage des branches Git.

Le marquage par nom de branche fonctionne tant que les validations sur cette branche sont collectées séquentiellement dans l'ordre chronologique.

Si dans le schéma actuel, l'utilisateur commence à reconstruire un ancien commit associé à une certaine branche, alors werf réécrira l'image en utilisant la balise Docker correspondante avec une version nouvellement construite de l'image pour l'ancien commit. Les déploiements utilisant cette balise courent désormais le risque d'extraire une version différente de l'image lors du redémarrage des pods, ce qui entraînerait une perte de connexion avec le système CI et une désynchronisation de notre application.

De plus, avec des poussées successives dans une branche avec un court laps de temps entre elles, l'ancien commit peut être compilé plus tard que le plus récent : l'ancienne version de l'image écrasera la nouvelle en utilisant la balise de branche Git. De tels problèmes peuvent être résolus par un système CI/CD (par exemple, dans GitLab CI, le pipeline de ce dernier est lancé pour une série de commits). Cependant, tous les systèmes ne le prennent pas en charge et il doit exister un moyen plus fiable d'éviter un problème aussi fondamental.

Qu'est-ce que le balisage basé sur le contenu ?

Alors, qu'est-ce que le balisage basé sur le contenu : le balisage des images par contenu.

Pour créer des balises Docker, ce ne sont pas des primitives Git (branche Git, balise Git...) qui sont utilisées, mais une somme de contrôle associée à :

  • contenu de l'image. La balise d'identification de l'image reflète son contenu. Lors de la construction d'une nouvelle version, cet identifiant ne changera pas si les fichiers de l'image n'ont pas changé ;
  • historique de la création de cette image dans Git. Les images associées à différentes branches Git et à différents historiques de construction via werf auront des balises d'identification différentes.

Une telle étiquette d'identification est ce qu'on appelle signature de scène d'image.

Chaque image se compose d'un ensemble d'étapes : from, before-install, git-archive, install, imports-after-install, before-setup, ... git-latest-patch etc. Chaque étape a un identifiant qui reflète son contenu - signature de scène (signature de scène).

L'image finale, constituée de ces étapes, est étiquetée avec ce que l'on appelle la signature de l'ensemble de ces étapes - signature des étapes, - ce qui se généralise à toutes les étapes de l'image.

Pour chaque image de la configuration werf.yaml dans le cas général, il y aura sa propre signature et, par conséquent, une balise Docker.

La signature scénique résout tous ces problèmes :

  • Résistant aux commits Git vides.
  • Résistant aux commits Git qui modifient des fichiers qui ne sont pas pertinents pour l'image.
  • Ne pose pas le problème de la refonte de la version actuelle de l'image lors du redémarrage des builds pour les anciens commits Git d'une branche.

Il s’agit désormais de la stratégie de balisage recommandée et de la stratégie par défaut dans werf pour tous les systèmes CI.

Comment activer et utiliser dans Werf

La commande a maintenant une option correspondante werf publish: --tag-by-stages-signature=true|false

Dans un système CI, la stratégie de marquage est spécifiée par la commande werf ci-env. Auparavant, le paramètre était défini pour cela werf ci-env --tagging-strategy=tag-or-branch. Maintenant, si vous précisez werf ci-env --tagging-strategy=stages-signature ou ne spécifiez pas cette option, werf utilisera la stratégie de marquage par défaut stages-signature. Équipe werf ci-env définira automatiquement les indicateurs nécessaires pour la commande werf build-and-publish (ou werf publish), aucune option supplémentaire ne doit donc être spécifiée pour ces commandes.

Par exemple, la commande :

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

...peut créer les images suivantes :

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

il est 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d est une signature des étapes de l'image backendEt f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 - signature des étapes d'images frontend.

Lors de l'utilisation de fonctions spéciales werf_container_image и werf_container_env Il n'est pas nécessaire de changer quoi que ce soit dans les modèles Helm : ces fonctions généreront automatiquement les noms d'images corrects.

Exemple de configuration dans un système CI :

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

Plus d’informations sur la configuration sont disponibles dans la documentation :

En tout

  • Nouvelle option werf publish --tag-by-stages-signature=true|false.
  • Nouvelle valeur d'option werf ci-env --tagging-strategy=stages-signature|tag-or-branch (si non spécifié, la valeur par défaut sera stages-signature).
  • Si vous avez déjà utilisé les options de balisage pour les commits Git (WERF_TAG_GIT_COMMIT ou en option werf publish --tag-git-commit COMMIT), puis veillez à passer à la stratégie de marquage signature d'étapes.
  • Il est préférable de basculer immédiatement les nouveaux projets vers le nouveau système de marquage.
  • Lors du transfert vers werf 1.1, il est conseillé de basculer les anciens projets vers le nouveau schéma de marquage, mais l'ancien étiquette ou branche est toujours pris en charge.

Le balisage basé sur le contenu résout tous les problèmes abordés dans l'article :

  • Résistance du nom de la balise Docker aux commits Git vides.
  • Résilience du nom de la balise Docker aux commits Git qui modifient les fichiers sans rapport avec l'image.
  • Ne pose pas le problème de la refonte de la version actuelle de l'image lors du redémarrage des builds pour les anciens commits Git pour les branches Git.

Utilise le! Et n'oubliez pas de nous rendre visite à GitHubpour créer un problème ou en trouver un existant, ajouter un plus, créer un PR ou simplement suivre l'évolution du projet.

PS

A lire aussi sur notre blog :

Source: habr.com

Ajouter un commentaire