Docker-images kunnen nu ook met werf worden gebouwd met een gewone Dockerfile.

Beter laat dan nooit. Of hoe we bijna een ernstige fout maakten door geen ondersteuning voor standaard Dockerfiles voor het bouwen van applicatiebeelden te hebben.

Docker-images kunnen nu ook met werf worden gebouwd met een gewone Dockerfile.

Het gaat over werf — een GitOps-tool die integreert met elke CI/CD-systeem en het beheer van de volledige levenscyclus van een applicatie mogelijk maakt, waarmee je:

  • afbeeldingen kunt bouwen en publiceren,
  • applicaties kunt implementeren in Kubernetes,
  • onderdeel beelden kunt verwijderen met behulp van speciale beleidsregels.


De filosofie van het project is om laagdrempelige tools te bundelen in ƩƩn uniforme systeem, die DevOps-engineers controle over applicaties geeft. Waar mogelijk moeten al bestaande tools (zoals Helm en Docker) worden gebruikt. Als er echter geen oplossing voor een bepaald probleem is, kunnen wij alles creƫren en onderhouden wat hiervoor nodig is.

Achtergrond: onze afbeeldingsbouwer

Zo gebeurde het met de afbeeldingsbouwer in werf: de gebruikelijke Dockerfile voldeed niet. Als we vluchtig naar de geschiedenis van het project kijken, werd dit probleem al zichtbaar in de eerste versies van werf (toen nog bekend als dapp).

Bij het creƫren van een tool voor het bouwen van applicaties in Docker-afbeeldingen, realiseerden we ons snel dat Dockerfile niet geschikt was voor sommige specifieke taken:

  1. de noodzaak om typische kleine webapplicaties te bouwen volgens het volgende standaard schema:
    • installeer de systeemafhankelijkheden van de applicatie,
    • installeer een bundel van afhankelijkheidsbibliotheken van de applicatie,
    • bouw de assets,
    • en het belangrijkste — snel en efficiĆ«nt de code in de afbeelding bijwerken.
  2. Bij wijzigingen in de projectbestanden moet de bouwer snel een nieuwe laag creƫren door een patch op de gewijzigde bestanden aan te brengen.
  3. Als bepaalde bestanden zijn gewijzigd, moet de bijbehorende afhankelijkheidsstap opnieuw worden gebouwd.

Tot nu toe heeft onze bouwer vele andere mogelijkheden, maar de oorspronkelijke wensen en impulsen waren zo.

Al met al, zonder al te veel na te denken, hebben we de programmeertaal gebruikt (zie hieronder) en zijn we op weg gegaan — om te implementeren onze eigen DSL! Voldoende voor de gestelde doelen, was deze bedoeld om het bouwproces per stap te beschrijven en de afhankelijkheden van die stappen aan bestanden te definiĆ«ren. En het werd aangevuld met onze eigen bouwer, die de DSL omzet in het einddoel — de gebouwde afbeelding. In het begin was de DSL in Ruby, maar met de overgang naar Golang werd de configuratie van onze bouwer in een YAML-bestand beschreven.

Docker-images kunnen nu ook met werf worden gebouwd met een gewone Dockerfile.
Oude configuratie voor dapp op Ruby

Docker-images kunnen nu ook met werf worden gebouwd met een gewone Dockerfile.
Huidige configuratie voor werf in YAML

Het mechanisme van de bouwer is in de loop der tijd ook gewijzigd. Eerst genereerden we gewoon on-the-fly een tijdelijke Dockerfile uit onze configuratie, en later begonnen we bouwinstructies uit te voeren in tijdelijke containers en te committen.

NB: Op dit moment is onze bouwer, die werkt met zijn eigen configuratie (in YAML) en Stapel-bouwer wordt genoemd, al uitgegroeid tot een vrij krachtig hulpmiddel. Een uitgebreide beschrijving verdient aparte artikelen, terwijl de belangrijkste details kunnen worden gevonden in de documentatie.

Het besef van het probleem

Maar we realiseerden ons, en niet meteen, dat we ƩƩn fout hadden gemaakt: we hadden de mogelijkheid niet toegevoegd om beelden te bouwen via de standaard Dockerfile en deze te integreren in dezelfde infrastructuur voor applicatiebeheer (d.w.z. beelden bouwen, implementeren en opschonen). Hoe kon je een tool voor implementatie in Kubernetes maken zonder ondersteuning voor Dockerfile te implementeren, d.w.z. de standaard manier om beelden voor de meeste projecten te beschrijven?..

In plaats van een antwoord op een dergelijke vraag bieden we de oplossing. Wat te doen als je al een Dockerfile (of een set Dockerfiles) hebt en je wilt werf gebruiken?

NB: Trouwens, waarom zou je überhaupt willen werf gebruiken? De belangrijkste functies zijn als volgt:

  • volledige cyclus van applicatiebeheer, inclusief het opschonen van beelden;
  • mogelijkheid om de bouw van meerdere beelden vanuit ƩƩn enkele configuratie te beheren;
  • verbeterd proces voor het implementeren van charts die compatibel zijn met Helm.

Een completer overzicht is te vinden op de projectpagina.

Dus, als we eerder zouden voorstellen om de Dockerfile opnieuw te schrijven naar onze configuratie, dan zeggen we nu met plezier: 'Laat werf uw Dockerfiles bouwen!'

Hoe te gebruiken?

De volledige implementatie van deze functie verscheen in de release werf v1.0.3-beta.1. Het algemene principe is eenvoudig: de gebruiker geeft het pad naar de bestaande Dockerfile in de werf-configuratie op, waarna hij het commando uitvoert werf build… en dat is het — werf zal het beeld bouwen. Laten we het bekijken aan de hand van een abstract voorbeeld.

Laten we de volgende declareren Dockerfile in de hoofdmap van het project:

FROM ubuntu:18.04
RUN echo Building ...

En laten we werf.yaml, die deze gebruikt Dockerfile:

configVersion: 1
project: dockerfile-example
---
image: ~
dockerfile: .\/Dockerfile

En dat is het! Het enige wat resteert is om te starten werf build:

Docker-images kunnen nu ook met werf worden gebouwd met een gewone Dockerfile.

Bovendien kan de volgende worden gedeclareerd werf.yaml om meerdere beelden tegelijk uit verschillende Dockerfiles te bouwen:

configVersie: 1
project: dockerfile-voorbeeld
---
image: backend
dockerfile: ./dockerfiles/Dockerfile-backend
---
image: frontend
dockerfile: ./dockerfiles/Dockerfile-frontend

Ten slotte worden ook extra buildparameters ondersteund, zoals --build-arg en --add-host — via de werf-config. Een volledige beschrijving van de Dockerfile-imageconfiguratie is beschikbaar op de documentatiepagina.

How does it work?

Tijdens de bouw wordt de standaardcache van lokale lagen in Docker gebruikt. Het is echter belangrijk dat werf ook de Dockerfile-configuratie integreert in zijn infrastructuur.Wat betekent dit?

  1. Elke afbeelding die is opgebouwd uit een Dockerfile bestaat uit ƩƩn stage genaamd dockerfile (meer over wat stages zijn in werf, kan worden gelezen op hier).
  2. Voor de stage dockerfile berekent werf een handtekening die afhankelijk is van de inhoud van de Dockerfile-configuratie. Wanneer de Dockerfile-configuratie verandert, verandert de handtekening van de stage dockerfile en werf initieert een herbouw van deze stage met de nieuwe Dockerfile-configuratie. Als de handtekening echter niet verandert, neemt werf de afbeelding uit de cache. (meer over het gebruik van handtekeningen in werf was te horen in deze presentatie).
  3. Vervolgens kunnen de gebouwde afbeeldingen worden gepubliceerd met het commando werf publish (of werf build-and-publish) en gebruikt worden voor deployment in Kubernetes. Gepubliceerde afbeeldingen in de Docker Registry zullen worden schoongemaakt met de standaard schoonmaakmethoden van werf, dat wil zeggen, er zal een automatische schoonmaak plaatsvinden van oude afbeeldingen (ouder dan N dagen), afbeeldingen die zijn gekoppeld aan niet-bestaande Git-takken, en volgens andere beleidsregels.

Meer informatie over de hier beschreven punten is te vinden in de documentatie:

Opmerkingen en voorzorgsmaatregelen

1. Externe URL in ADD wordt niet ondersteund

Op dit moment wordt het gebruik van een externe URL in de ADD-directive niet ondersteund. ADD. Werf zal geen herbouw initiƫren bij wijzigingen in de bron op de opgegeven URL. Binnenkort wordt het toevoegen van deze functionaliteit gepland.

2. .git kan niet aan de afbeelding worden toegevoegd.

Over het algemeen is het toevoegen van een directory .git aan de afbeelding een verkeerde praktijk en hier is waarom:

  1. Als .git blijft in de uiteindelijke afbeelding, dit schendt de principes van 12 factor app: omdat de uiteindelijke afbeelding aan ƩƩn commit moet zijn gekoppeld, mag er geen mogelijkheid zijn om git checkout van een willekeurige commit.
  2. .git vergroent de afbeeldingsgrootte (de repository kan groot zijn omdat er ooit grote bestanden zijn toegevoegd en later verwijderd). De grootte van de werkboom, die alleen aan een bepaalde commit is gekoppeld, hangt niet af van de bewerkingsgeschiedenis in Git. Het toevoegen en vervolgens verwijderen .git uit de uiteindelijke afbeelding zal niet werken: de afbeelding zal toch een extra laag krijgen — zo werkt Docker.
  3. Docker kan onnodige herbouwingen initiƫren, zelfs als dezelfde commit wordt gebouwd, maar vanuit verschillende werkbomen. Bijvoorbeeld, GitLab maakt aparte gekloonde mappen in /home/gitlab-runner/builds/HASH/[0-N]/yourproject bij ingeschakelde parallelle constructie. De onnodige herbouwingen zullen verband houden met het feit dat de map .git verschilt in verschillende gekloonde versies van dezelfde repository, zelfs als dezelfde commit wordt gebouwd.

Het laatste punt heeft gevolgen bij het gebruik van werf. Werf vereist dat de gebouwde cache aanwezig is bij het uitvoeren van bepaalde opdrachten (bijvoorbeeld, werf deploy). Tijdens het uitvoeren van dergelijke opdrachten berekent werf de handtekeningen van de fasen voor de afbeeldingen die zijn opgegeven in werf.yaml, en deze moeten in de bouwcache zijn — anders kan het commando niet verder. Als de handtekening van de fasen afhankelijk is van de inhoud .git, dan krijgen we een cache die niet bestand is tegen wijzigingen in irrelevante bestanden, en werf kan zo'n fout niet vergeven (zie meer in de documentatie).

Over het algemeen het toevoegen van alleen bepaalde noodzakelijke bestanden via de instructie ADD verhoogt in ieder geval de efficiƫntie en betrouwbaarheid van wat er is geschreven Dockerfile, evenals de weerstand van de cache, die is opgebouwd uit deze Dockerfile, tegen irrelevante wijzigingen in Git.

Conclusie

Onze aanvangsroute met het schrijven van onze eigen bouwer voor specifieke behoeften was zwaar, eerlijk en rechttoe rechtaan: in plaats van te leunen op tijdelijke oplossingen bovenop de standaard Dockerfile hebben we onze eigen oplossing geschreven met een aangepaste syntaxis. En dat heeft zijn voordelen gegeven: de Stapel-bouwer doet uitstekend zijn werk.

Echter, tijdens het schrijven van onze eigen bouwer hebben we de ondersteuning voor reeds bestaande Dockerfiles over het hoofd gezien. Deze tekortkoming is nu gecorrigeerd, en in de toekomst zijn we van plan de ondersteuning voor Dockerfiles verder te ontwikkelen naast onze aangepaste bouwer Stapel voor gedistribueerde bouw en voor bouw met behulp van Kubernetes (d.w.z. bouw op runners binnen Kubernetes, zoals gedaan wordt in kaniko).

Dus als je toevallig een paar Dockerfiles hebt liggen... probeer het eens werf!

P.S. Een lijst met documentatie over het onderwerp

Lees ook in onze blog: 'werf — onze tool voor CI/CD in Kubernetes (overzicht en video van de presentatie)Ā».

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster