Du kan nu bygge Docker-billeder i werf ved hjælp af en almindelig Dockerfil

Bedre sent end aldrig. Eller hvordan vi næsten lavede en alvorlig fejl ved ikke at have support til almindelige Dockerfiler til at bygge applikationsbilleder.

Du kan nu bygge Docker-billeder i werf ved hjælp af en almindelig Dockerfil

Det kommer til at handle om werf — Et GitOps-værktøj, der integreres med ethvert CI/CD-system og administrerer hele applikationens livscyklus, så du kan:

  • indsamle og udgive billeder,
  • implementere applikationer til Kubernetes,
  • slet ubrugte billeder ved hjælp af særlige politikker.


Filosofien i projektet er at samle værktøjer på lavt niveau i et enkelt samlet system, der giver DevOps-ingeniører kontrol over applikationer. Hvis det er muligt, bør eksisterende hjælpeprogrammer (som Helm og Docker) bruges. Hvis der ikke findes en løsning på et problem, kan vi skabe og vedligeholde alt, hvad der er nødvendigt for dette.

Baggrund: din egen billedsamler

Dette er, hvad der skete med billedbyggeren i werf: vi manglede den sædvanlige Dockerfile. Hvis du kort kaster dig ind i projektets historie, så manifesterede dette problem sig allerede i de første versioner af werf (dengang kendt som dapp).

Mens vi lavede et værktøj til at bygge applikationer ind i Docker-billeder, indså vi hurtigt, at Dockerfilen ikke var egnet til os til nogle meget specifikke opgaver:

  1. Behovet for at samle typiske små webapplikationer i henhold til følgende standardskema:
    • installere applikationens systemdækkende afhængigheder,
    • installere et bundt af applikationsafhængighedsbiblioteker,
    • indsamle aktiver,
    • og vigtigst af alt, opdatere koden i billedet hurtigt og effektivt.
  2. Når der foretages ændringer i projektfiler, skal bygherren hurtigt oprette et nyt lag ved at patche de ændrede filer.
  3. Hvis visse filer er ændret, skal det tilsvarende afhængige trin genopbygges.

I dag er der mange andre muligheder i vores vandhane, men de indledende ønsker og drifter var som følger.

Generelt, uden at tænke to gange, bevæbnede vi os med det anvendte programmeringssprog (se nedenunder) og slå på vejen - at gennemføre egen DSL! I overensstemmelse med de stillede opgaver var det hensigten at beskrive byggeprocessen i etaper og bestemme disse fasers afhængighed af filer. Og supplerede det egen vandhane, som gjorde DSL til det endelige mål - det samlede billede. Først var DSL i Ruby, men som skifte til Golang - Konfigurationen af ​​vores samler begyndte at blive beskrevet i YAML-filen.

Du kan nu bygge Docker-billeder i werf ved hjælp af en almindelig Dockerfil
Gammel konfig til dapp i Ruby

Du kan nu bygge Docker-billeder i werf ved hjælp af en almindelig Dockerfil
Faktisk konfiguration for werf på YAML

Opsamlerens mekanisme ændrede sig også over tid. I starten genererede vi simpelthen en midlertidig Dockerfil fra vores konfiguration i farten, og så begyndte vi at køre byggeinstruktioner i midlertidige containere og lave en commit.

NB: I øjeblikket har vores builder, som arbejder med sin egen config (i YAML) og kaldes Stapel builder, allerede udviklet sig til et ret kraftigt værktøj. Dens detaljerede beskrivelse fortjener separate artikler, og de vigtigste detaljer kan findes i dokumentation.

Bevidsthed om problemet

Men vi indså, og ikke med det samme, at vi havde begået én fejl: Vi tilføjede ikke evnen byg billeder gennem en standard Dockerfile og integrer dem i den samme end-to-end applikationsadministrationsinfrastruktur (dvs. indsaml billeder, implementer og rengør dem). Hvordan kunne du lave et implementeringsværktøj i Kubernetes og ikke implementere Dockerfile support, dvs. en standard måde at beskrive billeder på for de fleste projekter?

I stedet for at besvare et sådant spørgsmål tilbyder vi dens løsning. Hvad hvis du allerede har en Dockerfile (eller et sæt Dockerfiler) og vil bruge werf?

NB: Forresten, hvorfor vil du overhovedet bruge werf? De vigtigste funktioner koges ned til følgende:

  • fuld programstyringscyklus inklusive rensebilleder;
  • evnen til at styre samlingen af ​​flere billeder på én gang fra en enkelt konfiguration;
  • forbedret implementeringsproces for Helm-kompatible diagrammer.

En mere komplet liste kan findes på projektside.

Så hvis vi tidligere ville foreslå at omskrive Dockerfilen til vores konfiguration, er vi nu glade for at sige: "Lad werf bygge dine Dockerfiler!"

Hvordan man bruger?

Den fulde implementering af denne funktion dukkede op i udgivelsen werf v1.0.3-beta.1. Det generelle princip er enkelt: brugeren angiver stien til en eksisterende Dockerfile i werf-konfigurationen og kører derefter kommandoen werf build... og det er det - werf vil bygge billedet. Lad os overveje et abstrakt eksempel.

Lad os annoncere det næste Dockerfile kernen i projektet:

FROM ubuntu:18.04
RUN echo Building ...

Og vi vil annoncere werf.yamlsom bruger dette Dockerfile:

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

Alle! Venstre løb werf build:

Du kan nu bygge Docker-billeder i werf ved hjælp af en almindelig Dockerfil

Derudover kan du deklarere følgende werf.yaml at bygge flere billeder på én gang fra forskellige Dockerfiler:

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

Endelig er det også understøttet at videregive yderligere build-parametre - som f.eks --build-arg и --add-host - via werf config. En komplet beskrivelse af Dockerfile-billedkonfigurationen er tilgængelig på dokumentationsside.

Hvordan fungerer det?

Under byggeprocessen fungerer standardcachen for lokale lag i Docker. Men vigtigst af alt, werf også integrerer Dockerfile-konfigurationen i sin infrastruktur. Hvad betyder det?

  1. Hvert billede bygget fra en Dockerfile består af et enkelt trin kaldet dockerfile (mere om, hvilke stadier der er i werf, kan du læse her).
  2. Til scenen dockerfile werf beregner en signatur, der afhænger af indholdet af Dockerfile-konfigurationen. Ændring af Dockerfile-konfigurationen ændrer scenesignaturen dockerfile og werf vil starte en genopbygning af det trin med den nye Dockerfile-konfiguration. Hvis signaturen ikke ændres, tager werf billedet fra cachen (mere om brugen af ​​signaturer i werf blev beskrevet i denne rapport).
  3. Yderligere kan de indsamlede billeder publiceres med kommandoen werf publish (eller werf build-and-publish) og brug den til at implementere til Kubernetes. Publicerede billeder i Docker Registry vil blive renset med standard werf-oprydningsværktøjer, dvs. der vil være en automatisk oprydning af gamle billeder (ældre end N dage), billeder forbundet med ikke-eksisterende Git-grene og andre politikker.

Flere detaljer om punkterne beskrevet her kan findes i dokumentationen:

Bemærkninger og forholdsregler

1. Ekstern URL i ADD understøttes ikke

Brugen af ​​en ekstern URL i et direktiv er i øjeblikket ikke understøttet. ADD. Werf vil ikke udløse en genopbygning, når en ressource på den angivne URL ændres. Denne funktion er planlagt til at blive tilføjet snart.

2. Du kan ikke tilføje .git til et billede

Generelt, tilføjelse af en mappe .git ind i et billede er en ond, dårlig praksis, og her er grunden:

  1. Hvis .git forbliver i det endelige billede, er dette i strid med principperne 12 faktor ca: da det resulterende billede skal linkes til en enkelt commit, burde det ikke være muligt at gøre git checkout vilkårlig forpligtelse.
  2. .git øger størrelsen af ​​billedet (lageret kan være stort på grund af det faktum, at store filer engang blev tilføjet til det og derefter slettet). Størrelsen af ​​arbejdstræet, der kun er forbundet med en bestemt commit, vil ikke afhænge af historikken for operationer i Git. I dette tilfælde tilføjelse og efterfølgende fjernelse .git fra det endelige billede vil ikke virke: billedet vil stadig få et ekstra lag - det er sådan Docker fungerer.
  3. Docker kan udløse en unødvendig genopbygning, selvom den samme commit bygges fra forskellige arbejdstræer. For eksempel opretter GitLab separate klonede mapper i /home/gitlab-runner/builds/HASH/[0-N]/yourproject med parallel montering aktiveret. En ekstra ombygning vil skyldes, at mappen .git forskellige i forskellige klonede versioner af det samme lager, selvom den samme commit er bygget.

Det sidste punkt har også konsekvenser ved brug af werf. Werf kræver, at den indbyggede cache er til stede, når du kører nogle kommandoer (f.eks. werf deploy). Under udførelsen af ​​sådanne kommandoer beregner werf scenesignaturer for de billeder, der er specificeret i werf.yaml, og de skal være i build-cachen, ellers vil kommandoen ikke kunne fortsætte. Hvis underskriften af ​​etaperne afhænger af indholdet .git, så får vi en cache, der er ustabil over for ændringer i irrelevante filer, og werf vil ikke være i stand til at tilgive en sådan forglemmelse (for flere detaljer, se dokumentation).

Generelt tilføjer kun visse nødvendige filer gennem instruktioner ADD under alle omstændigheder øger effektiviteten og pålideligheden af ​​det skrevne Dockerfile, og forbedrer også stabiliteten af ​​den cache, der indsamles af dette Dockerfile, til irrelevante ændringer i Git.

Total

Vores første vej med at skrive vores egen builder til specifikke behov var hård, ærlig og ligetil: i stedet for at bruge krykker oven på standard Dockerfile, skrev vi vores egen løsning med tilpasset syntaks. Og det gav sine fordele: Stapel-samleren gør sit arbejde perfekt.

Men i processen med at skrive vores egen builder mistede vi støtten til allerede eksisterende Dockerfiler af syne. Nu er denne mangel blevet rettet, og i fremtiden planlægger vi at udvikle Dockerfile-understøttelse sammen med vores brugerdefinerede Stapel-builder til distribuerede builds og til at bygge ved hjælp af Kubernetes (dvs. at bygge på løbere inde i Kubernetes, som gjort i kaniko).

Så hvis du pludselig har et par Dockerfiler liggende... prøv det werf!

PS Liste over dokumentation om emnet

Læs også på vores blog:werf - vores værktøj til CI / CD i Kubernetes (oversigt og videorapport)'.

Kilde: www.habr.com

Tilføj en kommentar