U kunt nu Docker-images bouwen in werf met behulp van een gewone Dockerfile

Beter laat dan nooit. Of hoe we bijna een ernstige fout maakten door geen ondersteuning te hebben voor reguliere Dockerfiles om applicatie-images te bouwen.

U kunt nu Docker-images bouwen in werf met behulp van een gewone Dockerfile

We zullen erover praten werf — GitOps-hulpprogramma dat met elk CI/CD-systeem kan worden geïntegreerd en de gehele levenscyclus van applicaties kan beheren, waardoor:

  • afbeeldingen verzamelen en publiceren,
  • applicaties implementeren in Kubernetes,
  • verwijder ongebruikte afbeeldingen met behulp van speciaal beleid.


De filosofie van het project is om tools op laag niveau te verzamelen in één enkel systeem dat DevOps-ingenieurs controle geeft over applicaties. Indien mogelijk moeten bestaande hulpprogramma's (zoals Helm en Docker) worden gebruikt. Als er geen oplossing is voor een probleem, kunnen wij alles wat daarvoor nodig is creëren en ondersteunen.

Achtergrond: je eigen beeldverzamelaar

Dit is wat er gebeurde met de beeldverzamelaar in de werf: de gebruikelijke Dockerfile was voor ons niet genoeg. Als je snel naar de geschiedenis van het project kijkt, verscheen dit probleem al in de eerste versies van werf (toen nog bekend als dapp).

Tijdens het maken van een tool voor het inbouwen van applicaties in Docker-images, realiseerden we ons al snel dat Dockerfile niet geschikt was voor ons voor een aantal zeer specifieke taken:

  1. De noodzaak om typische kleine webapplicaties te bouwen volgens het volgende standaardschema:
    • installeer systeembrede applicatie-afhankelijkheden,
    • installeer een bundel applicatie-afhankelijkheidsbibliotheken,
    • activa verzamelen,
    • en het allerbelangrijkste: werk de code in de afbeelding snel en efficiënt bij.
  2. Wanneer er wijzigingen worden aangebracht in projectbestanden, moet de bouwer snel een nieuwe laag maken door een patch op de gewijzigde bestanden toe te passen.
  3. Als bepaalde bestanden zijn gewijzigd, is het noodzakelijk om de overeenkomstige afhankelijke fase opnieuw op te bouwen.

Tegenwoordig heeft onze verzamelaar nog veel meer mogelijkheden, maar dit waren de aanvankelijke wensen en driften.

Over het algemeen hebben we ons, zonder er twee keer over na te denken, bewapend met de programmeertaal die we gebruikten (zie hieronder) en ga op pad om te implementeren eigen DSL! Conform de doelstellingen was het de bedoeling om het assemblageproces in fasen te beschrijven en de afhankelijkheden van deze fasen op bestanden te bepalen. En vulde het aan eigen verzamelaar, waardoor de DSL het uiteindelijke doel werd: een samengesteld beeld. Aanvankelijk was de DSL in Ruby, maar zoals overgang naar Golang — de configuratie van onze verzamelaar werd beschreven in een YAML-bestand.

U kunt nu Docker-images bouwen in werf met behulp van een gewone Dockerfile
Oude configuratie voor dapp in Ruby

U kunt nu Docker-images bouwen in werf met behulp van een gewone Dockerfile
Huidige configuratie voor werf op YAML

Ook het mechanisme van de verzamelaar veranderde in de loop van de tijd. In eerste instantie genereerden we eenvoudigweg een tijdelijk Docker-bestand vanuit onze configuratie, en daarna begonnen we montage-instructies in tijdelijke containers uit te voeren en vast te leggen.

NB: Op dit moment heeft onze collector, die met een eigen config (in YAML) werkt en de Stapel-collector wordt genoemd, zich al ontwikkeld tot een redelijk krachtige tool. De gedetailleerde beschrijving ervan verdient aparte artikelen, en basisdetails zijn te vinden in documentatie.

Bewustwording van het probleem

Maar we beseften, en niet meteen, dat we één fout hadden gemaakt: we hadden de mogelijkheid niet toegevoegd afbeeldingen bouwen via standaard Dockerfile en integreer ze in dezelfde end-to-end applicatiebeheerinfrastructuur (dat wil zeggen: verzamel afbeeldingen, implementeer en schoon ze op). Hoe zou het mogelijk kunnen zijn om een ​​tool te maken voor implementatie in Kubernetes en geen Dockerfile-ondersteuning te implementeren, d.w.z. standaardmanier om afbeeldingen te beschrijven voor de meeste projecten?

In plaats van deze vraag te beantwoorden, bieden wij een oplossing. Wat als u al een Dockerfile (of een set Dockerfiles) heeft en werf wilt gebruiken?

NB: Trouwens, waarom zou je eigenlijk werf willen gebruiken? De belangrijkste kenmerken komen op het volgende neer:

  • volledige applicatiebeheercyclus inclusief het opschonen van afbeeldingen;
  • de mogelijkheid om de assemblage van meerdere afbeeldingen tegelijk vanuit één enkele configuratie te beheren;
  • Verbeterd implementatieproces voor Helm-compatibele grafieken.

Een meer volledige lijst ervan is te vinden op projectpagina.

Dus als we eerder hadden aangeboden om de Dockerfile in onze configuratie te herschrijven, zeggen we nu met plezier: “Laat werf je Dockerfiles bouwen!”

Hoe te gebruiken?

De volledige implementatie van deze functie verscheen in de release werf v1.0.3-bèta.1. Het algemene principe is eenvoudig: de gebruiker specificeert het pad naar een bestaand Dockerbestand in de werfconfiguratie en voert vervolgens de opdracht uit werf build... en dat is alles: werf zet het beeld in elkaar. Laten we een abstract voorbeeld bekijken.

Laten we de volgende aankondigen Dockerfile in de projectroot:

FROM ubuntu:18.04
RUN echo Building ...

En wij zullen het bekendmaken werf.yamldie hiervan gebruik maakt Dockerfile:

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

Alle! Links rennen werf build:

U kunt nu Docker-images bouwen in werf met behulp van een gewone Dockerfile

Daarnaast kunt u het volgende aangeven werf.yaml om meerdere afbeeldingen tegelijk van verschillende Dockerfiles te bouwen:

configVersion: 1
project: dockerfile-example
---
image: backend
dockerfile: ./dockerfiles/Dockerfile-backend
---
image: frontend
dockerfile: ./dockerfiles/Dockerfile-frontend

Ten slotte ondersteunt het ook het doorgeven van aanvullende buildparameters, zoals --build-arg и --add-host - via werfconfig. Een volledige beschrijving van de Dockerfile-imageconfiguratie is beschikbaar op documentatie pagina.

Hoe werkt het?

Tijdens het bouwproces functioneert de standaardcache van lokale lagen in Docker. Wat echter wel belangrijk is, is dat werf ook integreert Dockerfile-configuratie in zijn infrastructuur. Wat betekent dit?

  1. Elke afbeelding die is opgebouwd uit een Dockerfile bestaat uit één fase genaamd dockerfile (je leest meer over welke etappes er op de werf zijn hier).
  2. Voor podium dockerfile werf berekent een handtekening die afhankelijk is van de inhoud van de Dockerfile-configuratie. Wanneer de Dockerfile-configuratie verandert, verandert de fasehandtekening dockerfile en werf initieert een herbouw van deze fase met een nieuwe Dockerfile-configuratie. Als de handtekening niet verandert, haalt werf de afbeelding uit de cache (meer details over het gebruik van handtekeningen op de werf zijn beschreven in dit verslag).
  3. Vervolgens kunnen de verzamelde afbeeldingen worden gepubliceerd met het commando werf publish (Of werf build-and-publish) en gebruik deze voor implementatie in Kubernetes. Gepubliceerde afbeeldingen in het Docker-register worden opgeschoond met behulp van standaard werfopruimingstools, d.w.z. Oude afbeeldingen (ouder dan N dagen), afbeeldingen die zijn gekoppeld aan niet-bestaande Git-vertakkingen en ander beleid worden automatisch opgeschoond.

Meer details over de hier beschreven punten vindt u in de documentatie:

Opmerkingen en voorzorgsmaatregelen

1. Externe URL wordt niet ondersteund in ADD

Momenteel wordt het niet ondersteund om een ​​externe URL in een richtlijn te gebruiken ADD. Werf zal geen herbouw starten wanneer de bron op de opgegeven URL verandert. We zijn van plan deze functie binnenkort toe te voegen.

2. Je kunt .git niet aan de afbeelding toevoegen

Over het algemeen voegt u een map toe .git in beeld - een wrede slechte gewoonte en dit is waarom:

  1. als .git in het uiteindelijke beeld blijft staan, dit is in strijd met de principes 12-factor-app: Aangezien de uiteindelijke afbeelding aan één enkele commit moet worden gekoppeld, zou dit niet mogelijk moeten zijn git checkout willekeurige verbintenis.
  2. .git vergroot de grootte van de afbeelding (de repository kan groot zijn vanwege het feit dat er ooit grote bestanden aan zijn toegevoegd en vervolgens zijn verwijderd). De grootte van een werkboom die alleen geassocieerd is met een specifieke commit zal niet afhangen van de geschiedenis van operaties in Git. In dit geval de toevoeging en daaropvolgende verwijdering .git van de uiteindelijke afbeelding zal niet werken: de afbeelding krijgt nog steeds een extra laag - zo werkt Docker.
  3. Docker kan een onnodige herbouw initiëren, zelfs als dezelfde commit wordt gebouwd, maar vanuit verschillende werkbomen. GitLab maakt bijvoorbeeld afzonderlijke gekloonde mappen in /home/gitlab-runner/builds/HASH/[0-N]/yourproject wanneer parallelle montage is ingeschakeld. De extra hermontage zal te wijten zijn aan het feit dat de directory .git is verschillend in verschillende gekloonde versies van dezelfde repository, zelfs als dezelfde commit wordt gebouwd.

Dit laatste punt heeft ook consequenties bij het gebruik van werf. Werf vereist dat de ingebouwde cache aanwezig is bij het uitvoeren van sommige opdrachten (bijv. werf deploy). Wanneer deze opdrachten worden uitgevoerd, berekent werf de podiumhandtekeningen voor de afbeeldingen die zijn opgegeven in werf.yaml, en ze moeten zich in de assembly-cache bevinden - anders kan de opdracht niet blijven werken. Als de podiumhandtekening afhankelijk is van de inhoud .git, dan krijgen we een cache die onstabiel is voor wijzigingen in irrelevante bestanden, en werf zal een dergelijke vergissing niet kunnen vergeven (voor meer details, zie documentatie).

globaal alleen bepaalde noodzakelijke bestanden toevoegen via de instructies ADD verhoogt in ieder geval de efficiëntie en betrouwbaarheid van het geschrevene Dockerfile, en verbetert ook de stabiliteit van de cache die hiervoor wordt verzameld Dockerfile, tot irrelevante wijzigingen in Git.

Totaal

Ons aanvankelijke pad naar het schrijven van onze eigen builder voor specifieke behoeften was moeilijk, eerlijk en duidelijk: in plaats van krukken bovenop het standaard Docker-bestand te gebruiken, schreven we onze oplossing met aangepaste syntaxis. En dit had zijn voordelen: de Stapel-verzamelaar kan zijn taak uitstekend uitvoeren.

Tijdens het schrijven van onze eigen builder verloren we echter de ondersteuning voor bestaande Dockerfiles uit het oog. Deze fout is nu verholpen en in de toekomst zijn we van plan Dockerfile-ondersteuning te ontwikkelen samen met onze aangepaste Stapel-builder voor gedistribueerde builds en voor builds met behulp van Kubernetes (d.w.z. builds op runners binnen Kubernetes, zoals wordt gedaan in kaniko).

Dus als je ineens een paar Dockerfiles hebt liggen... попробуйте werf!

PS Lijst met documentatie over het onderwerp

Lees ook in onze blog: “werf - onze tool voor CI/CD in Kubernetes (overzicht en videoverslag).

Bron: www.habr.com

Voeg een reactie