Balisage basé sur le contenu dans le collecteur werf: pourquoi et comment cela fonctionne-t-il?



werf est notre utilitaire CLI GitOps open source pour la création et la livraison d'applications à Kubernetes. Dans la version v1.1 a une nouvelle fonctionnalité pour le collecteur d'images: balisage des images par contenu, ou balisage basé sur le contenu . Jusqu'à présent, le schéma de balisage typique de werf impliquait le balisage d'images Docker à l'aide d'une balise Git, d'une branche Git ou d'une validation Git. Mais tous ces schémas ont des défauts qui sont complètement résolus par la nouvelle stratégie de marquage. Détails sur elle et pourquoi elle est si bonne - sous la coupe.

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


Il existe souvent une situation où l'application est divisée en de nombreux 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 devraient continuer à fonctionner sans aucun changement. Mais du point de vue du stockage de code et de la gestion de projet, il est plus pratique de conserver ces services d'application dans un référentiel unique.

Il existe des situations où les services sont vraiment indépendants et ne sont pas connectés à une seule application. Dans ce cas, ils seront situés dans des projets distincts et leur publication se fera par le biais de processus CI / CD distincts dans chacun des projets.

Cependant, en réalité, les développeurs divisent souvent une seule application en plusieurs microservices, mais avoir un référentiel et un projet séparés pour chacun ... est une exagération évidente. C'est à propos de cette situation qui sera discutée plus loin: plusieurs de ces microservices se trouvent dans un référentiel de projet unique et les versions se produisent via un processus unique dans CI / CD.

Git tag et Git tagging


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

Lors de la création d'une nouvelle balise Git - par exemple, lorsqu'une nouvelle version est publiée - une nouvelle balise Docker sera créée pour toutes les images de projet dans le 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

Ces nouveaux noms d'images passent par les modèles Helm dans la configuration Kubernetes. Lorsque le déploiement démarre, l'équipe werf deploymet à jour le champ imagedans les manifestes de ressources Kubernetes et redémarre les ressources correspondantes en raison du nom d'image modifié.

Problème : Dans le cas où le vykata réel précédent (Git-tag) n'a pas changé le contenu de l'image, mais seulement son Docker-tag qui se produit une fois redémarré cette application et, en conséquence, un simple possible. Bien qu'il n'y ait aucune raison réelle de faire ce redémarrage.

Par conséquent, avec le schéma de balisage actuel, vous devez clôturer plusieurs référentiels Git distincts et le problème se pose d'organiser le déploiement de ces plusieurs référentiels. En général, un tel schéma est surchargé et complexe. Il est préférable de combiner de nombreux services dans un seul référentiel et de créer de telles balises Docker afin qu'il n'y ait pas de redémarrages inutiles.

Git commit tagging


Werf a également une stratégie de balisage liée aux commits Git.

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

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

  • , , Docker- .
  • merge-, , Docker- .
  • , Git, , Docker- .

Git-


Il existe un autre problème lié à la stratégie de balisage pour les branches Git.

Le marquage par le nom d'une branche fonctionne tant que les commits de cette branche sont collectés séquentiellement dans l'ordre chronologique.

Si dans le schéma actuel, l'utilisateur commence à reconstruire l'ancien commit associé à une branche, alors werf effacera l'image en utilisant la balise Docker correspondante avec la version nouvellement assemblée de l'image pour l'ancien commit. Les déploiements utilisant cette balise risquent désormais de redémarrer le pod pour extraire une autre version de l'image, à la suite de quoi notre application perdra la connexion avec le système CI et sera désynchronisée.

De plus, avec des push'ahs consécutifs dans une branche avec un petit intervalle de temps entre eux, l'ancien commit peut être collecté plus tard que le plus récent: l'ancienne version de l'image effacera la nouvelle en utilisant le tag de la branche Git. Ces problèmes peuvent être résolus par le système CI / CD (par exemple, dans GitLab CI, le pipeline de ce dernier est lancé pour une série de validations). Cependant, cela n'est pas pris en charge par tous les systèmes et il devrait y avoir un moyen plus fiable de prévenir un problème aussi fondamental.

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


Alors, quel est exactement le balisage basé sur le contenu - baliser les images par contenu.

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

  • . - . , ;
  • Git. , Git- werf, -.

La soi-disant signature des étapes de l'image agit comme une telle étiquette d'identification .

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

L'image finale, constituée de ces étapes, est étiquetée avec la soi-disant signature de l'ensemble de ces étapes - signature des étapes - qui se généralise pour toutes les étapes de l'image.

Chaque image de la configuration werf.yamlaura généralement sa propre signature et, par conséquent, la balise Docker.

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

  • Résistant aux gits vides commis.
  • Résistant à git s'engage à modifier les fichiers qui ne sont pas pertinents pour l'image.
  • Ne conduit pas à un problème de meulage de la version actuelle de l'image lors du redémarrage des assemblys pour les anciens commits Git de la branche.

C'est maintenant la stratégie de marquage recommandée et est utilisée par défaut dans werf pour tous les systèmes CI.

Comment activer et utiliser dans werf


L'option correspondante est apparue pour l'équipe werf publish: --tag-by-stages-signature=true|false

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

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

Voici 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386dla signature des étapes de l'image backend, et f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6c'est la signature des étapes de l'image frontend.

Lorsque vous utilisez des fonctions spéciales werf_container_imageet werf_container_envdans des modèles Helm, rien ne doit être changé: 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:


Total


  • Nouvelle option werf publish --tag-by-stages-signature=true|false.
  • La nouvelle valeur de l'option werf ci-env --tagging-strategy=stages-signature|tag-or-branch(si non spécifiée, elle sera par défaut stages-signature).
  • Si les options de balisage pour les validations Git ont été utilisées auparavant ( WERF_TAG_GIT_COMMITou l'option werf publish --tag-git-commit COMMIT), assurez-vous de passer à la stratégie de balisage par étapes de signature .
  • Les nouveaux projets sont mieux de passer immédiatement à un nouveau schéma de marquage.
  • Lors de la traduction vers werf 1.1, il est conseillé de basculer les anciens projets vers le nouveau schéma de balisage, mais l'ancienne balise ou branche est toujours prise en charge.

Le balisage basé sur le contenu résout tous les problèmes mis en évidence dans l'article:

  • Stabilité du nom de la balise Docker pour vider les validations git.
  • La stabilité du nom de la balise Docker dans Git s'engage à modifier les fichiers qui ne sont pas pertinents pour l'image.
  • Ne conduit pas à un problème de meulage de la version actuelle de l'image lors du redémarrage des assemblys pour les anciennes validations Git pour les branches Git.

Utilise le! Et n'oubliez pas de passer par notre GitHub pour créer un problème ou en trouver un existant, mettre un plus, créer un PR, ou simplement regarder le développement du projet.

PS


Lisez aussi dans notre blog:


All Articles