Byg Docker-billeder i werf kan nu også gøres med en almindelig Dockerfile

Bedre sent end aldrig. Eller hvordan vi næsten begik en alvorlig fejl ved ikke at have støtte til almindelige Dockerfiles til opbygning af applikationsbilleder.

Byg Docker-billeder i werf kan nu også gøres med en almindelig Dockerfile

Det handler om werf — GitOps-værktøjet, der integreres med ethvert CI/CD-system og sikrer styring af hele applikationens livscyklus, så det er muligt at:

  • bygge og publicere billeder,
  • implementere applikationer i Kubernetes,
  • fjerne unødvendige billeder ved hjælp af specifikke politikker.


Projektets filosofi er at samle lavniveau værktøjer i et enkelt, ensartet system, der giver DevOps-ingeniører kontrol over applikationerne. Der skal i videst muligt omfang bruges eksisterende værktøjer (som Helm og Docker). Hvis der ikke findes en løsning på et bestemt problem, kan vi skabe og vedligeholde alt, hvad der er nødvendigt for det.

Forhistorie: vores billedbygger

Det skete også med billedbyggeren i werf: Vi manglede det velkendte Dockerfile. Hvis vi hurtigt kigger tilbage på projektets historie, dukkede dette problem op allerede i de første versioner af werf (dengang stadig kendt som dapp).

Da vi skabte et værktøj til at bygge applikationer i Docker-billeder, indså vi hurtigt, at Dockerfile ikke var velegnet til nogle specifikke opgaver:

  1. Behovet for at samle typiske små webapplikationer efter følgende standardordning:
    • installere applikationens systemafhængigheder,
    • installere afhængighedsbibliotekets bundt,
    • bygge aktiver,
    • og vigtigst af alt — opdatere koden i billedet hurtigt og effektivt.
  2. Når der sker ændringer i projektfilerne, skal byggeren hurtigt skabe et nyt lag ved at påføre en patch på de ændrede filer.
  3. Hvis bestemte filer ændres, skal den relevante afhængige fase genopbygges.

I dag har vores bygger flere andre muligheder, men de oprindelige ønsker og impulser var sådan.

Kort sagt, uden at tøve besteg vi det anvendte programmeringssprog (se nedenfor) og tog afsted — for at realisere vores egen DSL! I overensstemmelse med de opstillede mål var det beregnet til at beskrive opbygningsprocessen i faser og definere afhængighederne af disse faser fra filer. Og det blev suppleret af vores egen bygger, der forvandlede DSL til det endelige mål — det samlede billede. Først var DSL skrevet i Ruby, men efterhånden som vi overgik til Golang — konfigurationen af vores samler blev beskrevet i en YAML-fil.

Byg Docker-billeder i werf kan nu også gøres med en almindelig Dockerfile
Den gamle konfiguration til dapp på Ruby

Byg Docker-billeder i werf kan nu også gøres med en almindelig Dockerfile
Den aktuelle konfiguration for werf på YAML

Hvordan samleren fungerer, har også ændret sig over tid. Først genererede vi blot en midlertidig Dockerfile ud fra vores konfiguration, og siden har vi begyndt at køre byggeinstruktioner i midlertidige containere og lave commit.

NB: På nuværende tidspunkt er vores samler, der arbejder med sin egen konfiguration (i YAML) og kaldes Stapel-samleren, allerede udviklet til et ret kraftfuldt værktøj. Dens omfattende beskrivelse fortjener separate artikler, og de vigtigste detaljer kan findes i dokumentationen.

Bevidsthed om problemet

Men vi indså, om end ikke straks, at vi havde begået én fejl: vi havde ikke tilføjet muligheden for at samle billeder gennem en standard Dockerfile og integrere dem i den samme infrastruktur til kompleks applikationsstyring (dvs. samle billeder, deployere og rydde dem op). Hvordan kunne man skabe et værktøj til deployment i Kubernetes og ikke implementere understøttelse af Dockerfile, dvs. den standard måde at beskrive billeder for de fleste projekter?..

I stedet for at svare på et sådant spørgsmål tilbyder vi dets løsning. Hvad gør man, hvis man allerede har en Dockerfile (eller sæt af Dockerfile’er) og ønsker at bruge werf?

NB: For at sige det mildt, hvorfor skulle du overhovedet ønske at bruge werf? De vigtigste funktioner kan opsummeres som følger:

  • fuld cyklus af applikationsstyring inklusive oprydning af billeder;
  • mulighed for at administrere opbygningen af flere billeder fra en enkelt konfiguration;
  • forbedret deployment-proces for diagrammer kompatible med Helm.

En mere fuldstændig liste kan findes på på projektets side.

Så hvis vi tidligere ville have foreslået at omskrive Dockerfile til vores konfiguration, så siger vi nu med glæde: "Lad werf samle dine Dockerfile'er!"

Hvordan bruger man det?

Den fulde implementering af denne mulighed kom i udgaven werf v1.0.3-beta.1. Den generelle princip er enkelt: brugeren angiver stien til den eksisterende Dockerfile i werf-konfigurationen, hvorefter der køres kommandoen werf build… og det er det — werf vil samle billedet. Lad os tage et abstrakt eksempel.

Lad os erklære følgende Dockerfile i roden af projektet:

FROM ubuntu:18.04
RUN echo Bygger ...

Og lad os erklære werf.yaml, som bruger denne Dockerfile:

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

Det er alt! Der mangler kun startes werf build:

Byg Docker-billeder i werf kan nu også gøres med en almindelig Dockerfile

Desuden kan man erklære den følgende werf.yaml til at samle flere billeder fra forskellige Dockerfile’er:

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

Endelig understøttes også overførsel af ekstra byggeparametre — såsom --build-arg og --add-host — gennem werf-konfigurationen. En fuld beskrivelse af Dockerfile-billedekonfigurationen er tilgængelig på dokumentationssiden.

Hvordan fungerer det?

Under byggeprocessen fungerer standard cachen af lokale lag i Docker. Det vigtige er, at werf også integrerer Dockerfile-konfigurationen i sin infrastruktur. Hvad betyder det?

  1. Hvert billede, der er opbygget fra Dockerfile, består af en enkelt stage kaldet dockerfile (læs mere om, hvad stages er i werf, i her).
  2. For stagen dockerfile beregner werf en signatur, der afhænger af indholdet af Dockerfile-konfigurationen. Når Dockerfile-konfigurationen ændres, ændres signaturen for stagen dockerfile og werf initierer en genopbygning af denne stage med den nye Dockerfile-konfiguration. Hvis signaturen ikke ændres, tager werf billedet fra cachen (læs mere om brugen af signaturer i werf i denne præsentation).
  3. De opbyggede billeder kan derefter offentliggøres med kommandoen werf publish (eller werf build-and-publish) og bruges til deployment til Kubernetes. De offentliggjorte billeder i Docker Registry vil blive renset med standard rengøringsredskaber fra werf, dvs. der vil ske automatisk rensning af gamle billeder (ældre end N dage), billeder relateret til ikke-eksisterende Git-grene, og efter andre politikker.

Du kan finde flere detaljer om de beskrevne emner i dokumentationen:

Bemærkninger og forbehold

1. Eksterne URL'er i ADD understøttes ikke

I øjeblikket understøttes det ikke at bruge eksterne URL'er i direktivet ADD. Werf vil ikke initierer en genopbygning, hvis ressourcen på den angivne URL ændres. Denne funktionalitet planlægges at blive tilføjet snart.

2. Det er ikke tilladt at tilføje .git til billedet

Generelt set er det en dårlig praksis at tilføje mappen .git til billedet — og her er hvorfor:

  1. Hvis .git det forbliver i det endelige billede, hvilket bryder principperne for 12 factor app: da det endelige billede skal være knyttet til et enkelt commit, bør det ikke være muligt at lave git checkout til en vilkårlig commit.
  2. .git øger størrelsen af billedet (repository kan være stort, fordi der engang blev tilføjet store filer, og derefter fjernet dem). Størrelsen på work-tree, der kun er relateret til et bestemt commit, vil ikke afhænge af historikken af operationer i Git. Samtidig vil tilføjelse og efterfølgende fjernelse .git fra det endelige billede ikke virke: billedet vil stadig få et ekstra lag — sådan fungerer Docker.
  3. Docker kan initiere unødvendig genopbygning, selv når der bygges det samme commit, men fra forskellige work-trees. For eksempel opretter GitLab separate klonede direktiver i /home/gitlab-runner/builds/HASH/[0-N]/yourproject ved aktiveret parallel bygning. Den unødvendige genopbygning vil være relateret til, at mappen .git forskellige i de forskellige klonede versioner af det samme repository, selv når det samme commit bliver bygget.

Det sidste punkt har også en konsekvens ved brugen af werf. Werf kræver, at den byggede cache er til stede, når man kører visse kommandoer (for eksempel werf deploy). Under arbejdet med sådanne kommandoer beregner werf underskrifterne for faserne for de billeder, der er angivet i werf.yaml, og de skal være i build-cachen — ellers kan kommandoen ikke fortsætte. Hvis underskriften for faserne afhænger af indholdet .git, får vi en ustabil cache over for ændringer i irrelevant filer, og werf vil ikke tilgive en sådan forsømmelse (se nærmere i dokumentationen).

Generelt tilføjelse kun af de nødvendige filer gennem instruksen ADD øger effektiviteten og pålideligheden af det skrevne Dockerfile, samt forbedrer stabiliteten af cachen, der er bygget ud fra denne Dockerfile, til urelaterede ændringer i Git.

Resultat

Vores oprindelige vej med at skrive vores samler til specifikke behov var hård, ærlig og ligetil: i stedet for at bruge krumtapper på den standard Dockerfile, skrev vi vores løsning med et tilpasset syntaks. Og det havde sine fordele: Stapel-samleren klarer sin opgave godt.

Men under skrivningen af vores egen samler glemte vi at støtte de allerede eksisterende Dockerfile's. Dette manglende element er nu rettet, og vi planlægger at udvikle understøttelsen af Dockerfile sammen med vores tilpassede Stapel-samler til distribueret bygning og bygning ved hjælp af Kubernetes (dvs. bygning på runnerne inden for Kubernetes, som det gøres i kaniko).

Så hvis du nu har et par Dockerfiles liggende... prøv werf!

P.S. Dokumentationsliste om emnet

Læs også i vores blog: «werf — vores værktøj til CI/CD i Kubernetes (oversigt og video af præsentationen)».

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster