Content-based tagging in de werfcollector: waarom en hoe werkt het?

Content-based tagging in de werfcollector: waarom en hoe werkt het?

werf is ons open source GitOps CLI-hulpprogramma voor het bouwen en leveren van applicaties aan Kubernetes. IN versie v1.1 er is een nieuwe functie geïntroduceerd in de afbeeldingenverzamelaar: afbeeldingen taggen op inhoud of op inhoud gebaseerde tagging. Tot nu toe bestond het typische tagschema in de werf uit het taggen van Docker-images met een Git-tag, Git branch of Git commit. Maar al deze schema's hebben nadelen die volledig worden opgelost door de nieuwe tagging-strategie. Details erover en waarom het zo goed is, staan ​​​​onder de snede.

Een set microservices uitrollen vanuit één Git-repository

Vaak doet zich een situatie voor waarin een applicatie is opgedeeld in veel min of meer onafhankelijke services. Releases van deze services kunnen onafhankelijk plaatsvinden: er kunnen één of meer services tegelijk worden vrijgegeven, terwijl de rest ongewijzigd moet blijven werken. Maar vanuit het oogpunt van codeopslag en projectbeheer is het handiger om dergelijke applicatieservices in één repository te bewaren.

Er zijn situaties waarin services echt onafhankelijk zijn en niet aan één enkele applicatie zijn gekoppeld. In dit geval worden ze in afzonderlijke projecten geplaatst en wordt de vrijgave ervan uitgevoerd via afzonderlijke CI/CD-processen in elk van de projecten.

In werkelijkheid splitsen ontwikkelaars echter vaak een enkele applicatie op in verschillende microservices, maar het creëren van een aparte repository en project voor elke microservice... is duidelijk een overkill. Het is deze situatie die verder zal worden besproken: verschillende van dergelijke microservices bevinden zich in één projectrepository en releases vinden plaats via één enkel proces in CI/CD.

Tagging per Git-branch en Git-tag

Laten we zeggen dat de meest voorkomende taggingstrategie wordt gebruikt: tag-of-tak. Voor Git-vertakkingen worden afbeeldingen getagd met de naam van de vertakking, voor één vertakking tegelijk is er slechts één gepubliceerde afbeelding met de naam van die vertakking. Voor Git-tags worden afbeeldingen getagd op basis van de tagnaam.

Wanneer een nieuwe Git-tag wordt gemaakt, bijvoorbeeld wanneer een nieuwe versie wordt uitgebracht, wordt er een nieuwe Docker-tag gemaakt voor alle projectimages in het Docker-register:

  • 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

Deze nieuwe afbeeldingsnamen worden via Helm-sjablonen doorgegeven aan de Kubernetes-configuratie. Bij het starten van de implementatie met de opdracht werf deploy veld wordt bijgewerkt image in Kubernetes-bronmanifesten en het opnieuw opstarten van de bijbehorende bronnen vanwege de gewijzigde afbeeldingsnaam.

probleem: in het geval dat de inhoud van de afbeelding feitelijk niet is veranderd sinds de vorige implementatie (Git-tag), maar alleen de Docker-tag, gebeurt dit extra het herstarten van deze applicatie en dienovereenkomstig is enige downtime mogelijk. Al was er geen echte reden om deze herstart uit te voeren.

Als gevolg hiervan is het met het huidige tagging-schema noodzakelijk om verschillende afzonderlijke Git-repository's af te schermen en ontstaat het probleem van het organiseren van de uitrol van deze verschillende repository's. Over het algemeen blijkt een dergelijk schema overbelast en complex te zijn. Het is beter om veel services in één repository te combineren en Docker-tags te maken, zodat er geen onnodige herstarts plaatsvinden.

Tagging door Git commit

werf heeft ook een tagstrategie die verband houdt met Git-commits.

Git-commit is een identificatie voor de inhoud van een Git-repository en is afhankelijk van de bewerkingsgeschiedenis van bestanden in de Git-repository, dus het lijkt logisch om het te gebruiken voor het taggen van afbeeldingen in de Docker Registry.

Het taggen door Git commit heeft echter dezelfde nadelen als het taggen door Git branches of Git tags:

  • Er kan een lege commit worden gemaakt die geen bestanden wijzigt, maar de Docker-tag van de afbeelding wordt gewijzigd.
  • Er kan een merge commit worden aangemaakt die de bestanden niet verandert, maar de Docker-tag van de afbeelding wordt wel gewijzigd.
  • Er zou een commit gemaakt kunnen worden die de bestanden in Git verandert die niet in de afbeelding zijn geïmporteerd, en de Docker-tag van de afbeelding zal opnieuw worden gewijzigd.

Het taggen van de Git-vertakkingsnaam weerspiegelt niet de afbeeldingsversie

Er is nog een ander probleem verbonden aan de tagstrategie voor Git-takken.

Het taggen op vertakkingsnaam werkt zolang de commits op die vertakking opeenvolgend in chronologische volgorde worden verzameld.

Als de gebruiker in het huidige schema begint met het opnieuw opbouwen van een oude commit die aan een bepaalde branch is gekoppeld, dan zal werf de afbeelding herschrijven met behulp van de corresponderende Docker-tag met een nieuw gebouwde versie van de afbeelding voor de oude commit. Implementaties die deze tag gebruiken lopen voortaan het risico dat er bij het herstarten van pods een andere versie van de image wordt opgehaald, waardoor onze applicatie de verbinding met het CI-systeem verliest en gedesynchroniseerd raakt.

Bovendien, met opeenvolgende pushs in één branch met een korte tijd ertussen, kan de oude commit later worden gecompileerd dan de nieuwere: de oude versie van de image zal de nieuwe overschrijven met behulp van de Git branch tag. Dergelijke problemen kunnen worden opgelost door een CI/CD-systeem (in GitLab CI wordt bijvoorbeeld de pijplijn van laatstgenoemde gelanceerd voor een reeks commits). Niet alle systemen ondersteunen dit echter en er moet een betrouwbaardere manier zijn om een ​​dergelijk fundamenteel probleem te voorkomen.

Wat is op inhoud gebaseerde tagging?

Dus wat is op inhoud gebaseerde tagging: afbeeldingen taggen op inhoud.

Om Docker-tags te maken, worden geen Git-primitieven (Git branch, Git-tag...) gebruikt, maar een controlesom die is gekoppeld aan:

  • inhoud van de afbeelding. De afbeeldings-ID-tag weerspiegelt de inhoud ervan. Bij het bouwen van een nieuwe versie zal deze identificatie niet veranderen als de bestanden in de afbeelding niet zijn gewijzigd;
  • geschiedenis van het maken van deze afbeelding in Git. Afbeeldingen die zijn gekoppeld aan verschillende Git-takken en verschillende bouwgeschiedenis via werf zullen verschillende ID-tags hebben.

Een dergelijk identificatielabel is het zogenaamde handtekening van het beeldstadium.

Elke afbeelding bestaat uit een reeks fasen: from, before-install, git-archive, install, imports-after-install, before-setup, ... git-latest-patch enz. Elke fase heeft een identificatie die de inhoud weerspiegelt − podium handtekening (podiumhandtekening).

Het uiteindelijke beeld, bestaande uit deze fasen, wordt getagd met de zogenaamde handtekening van de set van deze fasen - stadia handtekening, - wat generaliserend is voor alle stadia van het beeld.

Voor elke afbeelding uit de configuratie werf.yaml in het algemene geval zal er een eigen handtekening zijn en dienovereenkomstig een Docker-tag.

De podiumsignatuur lost al deze problemen op:

  • Bestand tegen lege Git-commits.
  • Resistent tegen Git-commits die bestanden wijzigen die niet relevant zijn voor de afbeelding.
  • Leidt niet tot het probleem van het herzien van de huidige versie van de image bij het herstarten van builds voor oude Git-commits van een branch.

Dit is nu de aanbevolen tagstrategie en is de standaard in werf voor alle CI-systemen.

Hoe in te schakelen en te gebruiken in werf

Het commando heeft nu een overeenkomstige optie werf publish: --tag-by-stages-signature=true|false

In een CI-systeem wordt de tagstrategie gespecificeerd door de opdracht werf ci-env. Voorheen werd de parameter ervoor gedefinieerd werf ci-env --tagging-strategy=tag-or-branch. Als u het nu specificeert werf ci-env --tagging-strategy=stages-signature of specificeer deze optie niet, werf zal standaard de taggingstrategie gebruiken stages-signature. Team werf ci-env stelt automatisch de benodigde vlaggen voor de opdracht in werf build-and-publish (Of werf publish), dus er hoeven geen extra opties te worden opgegeven voor deze opdrachten.

Het commando is bijvoorbeeld:

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

...kan de volgende afbeeldingen maken:

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

Hier 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d is een handtekening van de stadia van het beeld backendEn f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 - handtekening van beeldstadia frontend.

Bij gebruik van speciale functies werf_container_image и werf_container_env In de Helm-sjablonen hoeft u niets te wijzigen: deze functies genereren automatisch de juiste afbeeldingsnamen.

Voorbeeldconfiguratie in een CI-systeem:

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

Meer informatie over de configuratie is beschikbaar in de documentatie:

In totaal

  • Nieuwe optie werf publish --tag-by-stages-signature=true|false.
  • Nieuwe optiewaarde werf ci-env --tagging-strategy=stages-signature|tag-or-branch (indien niet gespecificeerd, is de standaardwaarde stages-signature).
  • Als je eerder de tagging-opties voor Git-commits gebruikte (WERF_TAG_GIT_COMMIT of optie werf publish --tag-git-commit COMMIT), zorg er dan voor dat u overschakelt naar de taggingstrategie stadia-handtekening.
  • Het is beter om nieuwe projecten onmiddellijk over te zetten naar het nieuwe tagging-schema.
  • Bij de overstap naar werf 1.1 is het raadzaam om oude projecten over te zetten naar het nieuwe tagging-schema, maar de oude tag-of-tak wordt nog steeds ondersteund.

Op inhoud gebaseerde tagging lost alle problemen op die in het artikel worden behandeld:

  • Docker-tagnaamweerstand tegen lege Git-commits.
  • Veerkracht van de Docker-tagnaam voor Git-commits die bestanden wijzigen die niet relevant zijn voor de afbeelding.
  • Leidt niet tot het probleem van het herzien van de huidige versie van de image bij het herstarten van builds voor oude Git-commits voor Git-takken.

Gebruik het! En vergeet niet om ons te bezoeken op GitHubom een ​​probleem aan te maken of een bestaand probleem te vinden, een plus toe te voegen, een PR te creëren of gewoon de ontwikkeling van het project te bekijken.

PS

Lees ook op onze blog:

Bron: www.habr.com

Voeg een reactie