Innehållsbaserad taggning i werf-samlaren: varför och hur fungerar det?

Innehållsbaserad taggning i werf-samlaren: varför och hur fungerar det?

werf är vårt GitOps CLI-verktyg med öppen källkod för att bygga och leverera applikationer till Kubernetes. I släpp v1.1 en ny funktion introducerades i bildsamlaren: tagga bilder efter innehåll eller innehållsbaserad taggning. Hittills har det typiska taggningsschemat i werf innefattat taggning av Docker-bilder med Git-tagg, Git-gren eller Git-commit. Men alla dessa system har brister som helt löses av den nya taggningsstrategin. Detaljer om det och varför det är så bra finns under klippet.

Rulla ut en uppsättning mikrotjänster från ett Git-förråd

En situation uppstår ofta när en ansökan är uppdelad i många mer eller mindre fristående tjänster. Releaser av dessa tjänster kan ske oberoende av varandra: en eller flera tjänster kan släppas åt gången, medan resten måste fortsätta att fungera utan några förändringar. Men ur synvinkeln av kodlagring och projekthantering är det bekvämare att hålla sådana applikationstjänster i ett enda arkiv.

Det finns situationer då tjänster verkligen är oberoende och inte associerade med en enda applikation. I det här fallet kommer de att placeras i separata projekt och deras release kommer att utföras genom separata CI/CD-processer i vart och ett av projekten.

Men i verkligheten delar utvecklare ofta upp en enskild applikation i flera mikrotjänster, men att skapa ett separat arkiv och projekt för varje... är en klar överdrift. Det är denna situation som kommer att diskuteras vidare: flera sådana mikrotjänster finns i ett enda projektförråd och releaser sker genom en enda process i CI/CD.

Taggning med Git-gren och Git-tagg

Låt oss säga att den vanligaste taggningsstrategin används - tag-eller-gren. För Git-grenar är bilder taggade med namnet på grenen, för en gren åt gången finns det bara en publicerad bild med namnet på den grenen. För Git-taggar är bilder taggade enligt taggnamnet.

När en ny Git-tagg skapas – till exempel när en ny version släpps – skapas en ny Docker-tagg för alla projektbilder i Docker-registret:

  • 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

Dessa nya bildnamn skickas genom Helm-mallar till Kubernetes-konfigurationen. När du startar distributionen med kommandot werf deploy fältet uppdateras image i Kubernetes resursmanifester och startar om motsvarande resurser på grund av det ändrade bildnamnet.

problem: i de fall då innehållet i bilden faktiskt inte har ändrats sedan den tidigare lanseringen (Git-taggen), utan bara dess Docker-tagg, händer detta extra omstart av denna applikation och följaktligen är viss driftstopp möjlig. Även om det inte fanns någon egentlig anledning att utföra denna omstart.

Som ett resultat är det med det nuvarande taggningsschemat nödvändigt att inhägna flera separata Git-förråd och problemet uppstår med att organisera utbyggnaden av dessa flera förvar. I allmänhet visar sig ett sådant system vara överbelastat och komplext. Det är bättre att kombinera många tjänster till ett enda arkiv och skapa Docker-taggar så att det inte finns några onödiga omstarter.

Taggning av Git commit

werf har också en taggningsstrategi associerad med Git commits.

Git-commit är en identifierare för innehållet i ett Git-förråd och beror på redigeringshistoriken för filer i Git-förvaret, så det verkar logiskt att använda det för att tagga bilder i Docker-registret.

Men att tagga med Git commit har samma nackdelar som att tagga med Git-grenar eller Git-taggar:

  • En tom commit kan skapas som inte ändrar några filer, men Docker-taggen för bilden kommer att ändras.
  • En merge commit kan skapas som inte ändrar filerna, men Docker-taggen för bilden kommer att ändras.
  • En commit kan skapas som ändrar de filer i Git som inte importeras till bilden, och Docker-taggen för bilden kommer att ändras igen.

Taggning av Git-grenens namn återspeglar inte bildversionen

Det finns ett annat problem förknippat med taggningsstrategin för Git-grenar.

Taggning efter filialnamn fungerar så länge som commits på den grenen samlas in sekventiellt i kronologisk ordning.

Om användaren i det nuvarande schemat börjar bygga om en gammal commit associerad med en viss gren, kommer werf att skriva om bilden med motsvarande Docker-tagg med en nybyggd version av bilden för den gamla commit. Implementeringar som använder den här taggen från och med nu riskerar att dra en annan version av bilden vid omstart av pods, vilket resulterar i att vår applikation förlorar anslutningen till CI-systemet och blir avsynkroniserad.

Dessutom, med successiva push in i en gren med en kort tidsperiod mellan dem, kan den gamla commit kompileras senare än den nyare: den gamla versionen av bilden kommer att skriva över den nya med hjälp av Git branch-taggen. Sådana problem kan lösas med ett CI/CD-system (till exempel i GitLab CI lanseras pipelinen för den senare för en serie åtaganden). Alla system stöder dock inte detta och det måste finnas ett mer tillförlitligt sätt att förhindra ett sådant grundläggande problem.

Vad är innehållsbaserad taggning?

Så, vad är innehållsbaserad taggning - taggning av bilder efter innehåll.

För att skapa Docker-taggar är det inte Git-primitiver (Git-gren, Git-taggar...) som används, utan en kontrollsumma associerad med:

  • innehållet i bilden. Bild-ID-taggen återspeglar dess innehåll. När du bygger en ny version kommer denna identifierare inte att ändras om filerna i bilden inte har ändrats;
  • historia av att skapa den här bilden i Git. Bilder associerade med olika Git-grenar och olika bygghistorik via werf kommer att ha olika ID-taggar.

En sådan identifieringstagg är den så kallade bild scen signatur.

Varje bild består av en uppsättning steg: from, before-install, git-archive, install, imports-after-install, before-setup, ... git-latest-patch etc. Varje steg har en identifierare som återspeglar dess innehåll − scensignatur (scensignatur).

Den slutliga bilden, som består av dessa stadier, är taggad med den så kallade signaturen för uppsättningen av dessa steg - etapper signatur, - vilket är generaliserande för alla stadier av bilden.

För varje bild från konfigurationen werf.yaml i det allmänna fallet kommer det att finnas en egen signatur och följaktligen en Docker-tagg.

Scensignaturen löser alla dessa problem:

  • Motståndskraftig mot tomma Git-commits.
  • Resistant to Git commits som ändrar filer som inte är relevanta för bilden.
  • Leder inte till problemet med att se över den nuvarande versionen av bilden vid omstart av builds för gamla Git-commits av en gren.

Detta är nu den rekommenderade taggningsstrategin och är standard i werf för alla CI-system.

Hur man aktiverar och använder i werf

Kommandot har nu ett motsvarande alternativ werf publish: --tag-by-stages-signature=true|false

I ett CI-system specificeras taggningsstrategin av kommandot werf ci-env. Tidigare definierades parametern för den werf ci-env --tagging-strategy=tag-or-branch. Nu, om du specificerar werf ci-env --tagging-strategy=stages-signature eller ange inte det här alternativet, kommer werf att använda taggningsstrategin som standard stages-signature. Team werf ci-env kommer automatiskt att ställa in de nödvändiga flaggorna för kommandot werf build-and-publish (eller werf publish), så inga ytterligare alternativ behöver anges för dessa kommandon.

Till exempel kommandot:

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

...kan skapa följande bilder:

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

Här 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d är en signatur för bildens stadier backendOch f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 - signatur av bildstadier frontend.

Vid användning av specialfunktioner werf_container_image и werf_container_env Det finns inget behov av att ändra något i Helm-mallarna: dessa funktioner genererar automatiskt de korrekta bildnamnen.

Exempelkonfiguration i ett CI-system:

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

Mer information om konfiguration finns i dokumentationen:

Totalt

  • Nytt alternativ werf publish --tag-by-stages-signature=true|false.
  • Nytt optionvärde werf ci-env --tagging-strategy=stages-signature|tag-or-branch (om det inte anges kommer standarden att vara stages-signature).
  • Om du tidigare använt taggningsalternativen för Git commits (WERF_TAG_GIT_COMMIT eller alternativ werf publish --tag-git-commit COMMIT), se till att byta till taggningsstrategin etapper-signatur.
  • Det är bättre att omedelbart byta nya projekt till det nya taggningsschemat.
  • Vid överföring till werf 1.1 är det tillrådligt att byta gamla projekt till det nya taggningsschemat, men det gamla tag-eller-gren stöds fortfarande.

Innehållsbaserad taggning löser alla problem som tas upp i artikeln:

  • Docker-taggnamn motstånd mot tomma Git-commits.
  • Motståndskraften hos Docker-taggnamnet till Git-commits som ändrar filer som är irrelevanta för bilden.
  • Leder inte till problemet med att se över den nuvarande versionen av bilden vid omstart av builds för gamla Git-commits för Git-grenar.

Använd den! Och glöm inte att besöka oss kl GitHubför att skapa ett problem eller hitta ett befintligt, lägga till ett plus, skapa en PR eller helt enkelt se utvecklingen av projektet.

PS

Läs även på vår blogg:

Källa: will.com

Lägg en kommentar