Du kan nå bygge Docker-bilder i werf ved å bruke en vanlig Dockerfil

Bedre sent enn aldri. Eller hvordan vi nesten gjorde en alvorlig feil ved å ikke ha støtte for vanlige Dockerfiler for å bygge applikasjonsbilder.

Du kan nå bygge Docker-bilder i werf ved å bruke en vanlig Dockerfil

Vi skal snakke om werf — GitOps-verktøy som integreres med ethvert CI/CD-system og gir administrasjon av hele applikasjonens livssyklus, slik at:

  • samle og publisere bilder,
  • distribuere applikasjoner i Kubernetes,
  • slette ubrukte bilder ved hjelp av spesielle retningslinjer.


Filosofien til prosjektet er å samle lavnivåverktøy i et enkelt enhetlig system som gir DevOps-ingeniører kontroll over applikasjoner. Hvis mulig, bør eksisterende verktøy (som Helm og Docker) brukes. Hvis det ikke finnes noen løsning på et problem, kan vi lage og støtte alt som er nødvendig for dette.

Bakgrunn: din egen bildesamler

Dette er hva som skjedde med bildesamleren i werf: den vanlige Dockerfilen var ikke nok for oss. Hvis du tar en rask titt på historien til prosjektet, dukket dette problemet opp allerede i de første versjonene av werf (da fortsatt kjent som dapp).

Mens vi laget et verktøy for å bygge applikasjoner inn i Docker-bilder, innså vi raskt at Dockerfile ikke var egnet for oss for noen veldig spesifikke oppgaver:

  1. Behovet for å bygge typiske små nettapplikasjoner i henhold til følgende standardskjema:
    • installere systemomfattende applikasjonsavhengigheter,
    • installer en pakke med programavhengighetsbiblioteker,
    • samle eiendeler,
    • og viktigst av alt, oppdater koden i bildet raskt og effektivt.
  2. Når det gjøres endringer i prosjektfiler, må byggherren raskt lage et nytt lag ved å bruke en patch til de endrede filene.
  3. Hvis visse filer har endret seg, er det nødvendig å gjenoppbygge det tilsvarende avhengige stadiet.

I dag har samleren vår mange andre muligheter, men dette var de første ønskene og trangene.

Generelt, uten å tenke to ganger, bevæpnet vi oss med programmeringsspråket vi brukte (se nedenfor) og gå på veien for å implementere egen DSL! I samsvar med målene var det ment å beskrive monteringsprosessen i etapper og bestemme avhengighetene av disse stadiene til filer. Og kompletterte det egen samler, som gjorde DSL til det endelige målet - et samlet bilde. Først var DSL i Ruby, men som overgang til Golang — konfigurasjonen til samleren vår begynte å bli beskrevet i en YAML-fil.

Du kan nå bygge Docker-bilder i werf ved å bruke en vanlig Dockerfil
Gammel konfig for dapp i Ruby

Du kan nå bygge Docker-bilder i werf ved å bruke en vanlig Dockerfil
Gjeldende konfigurasjon for werf på YAML

Mekanismen til samleren endret seg også over tid. Til å begynne med genererte vi ganske enkelt en midlertidig Dockerfile fra konfigurasjonen vår, og så begynte vi å kjøre monteringsinstruksjoner i midlertidige beholdere og forplikte.

NB: For øyeblikket har samleren vår, som jobber med sin egen konfigurasjon (i YAML) og kalles Stapel-samleren, allerede utviklet seg til et ganske kraftig verktøy. Den detaljerte beskrivelsen fortjener separate artikler, og grunnleggende detaljer finnes i dokumentasjon.

Bevissthet om problemet

Men vi innså, og ikke umiddelbart, at vi hadde gjort én feil: vi la ikke til evnen bygge bilder via standard Dockerfile og integrere dem i den samme ende-til-ende applikasjonsadministrasjonsinfrastrukturen (dvs. samle inn bilder, distribuere og rense dem). Hvordan kunne det være mulig å lage et verktøy for utrulling i Kubernetes og ikke implementere Dockerfile-støtte, dvs. standard måte å beskrive bilder for de fleste prosjekter?

I stedet for å svare på dette spørsmålet, tilbyr vi en løsning. Hva om du allerede har en Dockerfile (eller et sett med Dockerfiler) og vil bruke werf?

NB: Forresten, hvorfor vil du i det hele tatt bruke werf? Hovedtrekkene kommer ned til følgende:

  • full programadministrasjonssyklus inkludert bilderensing;
  • muligheten til å administrere sammenstillingen av flere bilder samtidig fra en enkelt konfigurasjon;
  • Forbedret distribusjonsprosess for Helm-kompatible diagrammer.

En mer fullstendig liste over dem finner du på prosjektsiden.

Så hvis vi tidligere ville ha tilbudt å omskrive Dockerfilen i konfigurasjonen vår, vil vi nå med glede si: "La werf bygge Dockerfilene dine!"

Hvordan bruker du?

Den fullstendige implementeringen av denne funksjonen dukket opp i utgivelsen werf v1.0.3-beta.1. Det generelle prinsippet er enkelt: brukeren spesifiserer banen til en eksisterende Dockerfile i werf-konfigurasjonen, og kjører deretter kommandoen werf build... og det er det - werf vil sette sammen bildet. La oss se på et abstrakt eksempel.

La oss kunngjøre den neste Dockerfile i prosjektroten:

FROM ubuntu:18.04
RUN echo Building ...

Og vi vil kunngjøre werf.yamlsom bruker dette Dockerfile:

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

Alle! Venstre løpe werf build:

Du kan nå bygge Docker-bilder i werf ved å bruke en vanlig Dockerfil

I tillegg kan du deklarere følgende werf.yaml for å bygge flere bilder fra forskjellige Dockerfiler samtidig:

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

Til slutt støtter den også overføring av ytterligere byggeparametere, som f.eks --build-arg и --add-host - via werf config. En fullstendig beskrivelse av Dockerfile-bildekonfigurasjonen er tilgjengelig på dokumentasjonsside.

Hvordan virker det?

Under byggeprosessen fungerer standardbufferen for lokale lag i Docker. Det som imidlertid er viktig er at werf også integrerer Dockerfile-konfigurasjon i sin infrastruktur. Hva betyr dette?

  1. Hvert bilde bygget fra en Dockerfile består av ett trinn kalt dockerfile (du kan lese mer om hvilke stadier som er i werf her).
  2. For scenen dockerfile werf beregner en signatur som avhenger av innholdet i Dockerfile-konfigurasjonen. Når Dockerfile-konfigurasjonen endres, endres scenesignaturen dockerfile og werf starter en gjenoppbygging av dette stadiet med en ny Dockerfile-konfig. Hvis signaturen ikke endres, tar werf bildet fra hurtigbufferen (flere detaljer om bruken av signaturer i werf ble beskrevet i denne rapporten).
  3. Deretter kan de innsamlede bildene publiseres med kommandoen werf publish (eller werf build-and-publish) og bruk den for distribusjon til Kubernetes. Publiserte bilder til Docker Registry vil bli renset ved hjelp av standard werf-oppryddingsverktøy, dvs. Gamle bilder (eldre enn N dager), bilder assosiert med ikke-eksisterende Git-grener og andre retningslinjer blir automatisk renset.

Flere detaljer om punktene beskrevet her finner du i dokumentasjonen:

Merknader og forholdsregler

1. Ekstern URL støttes ikke i ADD

Foreløpig støttes det ikke å bruke en ekstern URL i et direktiv ADD. Werf vil ikke starte en gjenoppbygging når ressursen på den angitte URL-en endres. Vi planlegger å legge til denne funksjonen snart.

2. Du kan ikke legge til .git i bildet

Generelt sett, å legge til en katalog .git på bildet - en ond, dårlig praksis, og her er grunnen:

  1. Hvis .git forblir i det endelige bildet, bryter dette med prinsippene 12 faktor app: Siden det endelige bildet må være knyttet til en enkelt commit, skal det ikke være mulig å gjøre git checkout vilkårlig forpliktelse.
  2. .git øker størrelsen på bildet (lageret kan være stort på grunn av at store filer en gang ble lagt til det og deretter slettet). Størrelsen på et arbeidstre som kun er knyttet til en spesifikk forpliktelse vil ikke avhenge av operasjonshistorikken i Git. I dette tilfellet, tillegg og påfølgende fjerning .git fra det endelige bildet vil ikke fungere: bildet vil fortsatt få et ekstra lag - dette er hvordan Docker fungerer.
  3. Docker kan sette i gang en unødvendig ombygging, selv om den samme commit bygges, men fra forskjellige arbeidstrær. For eksempel oppretter GitLab separate klonede kataloger i /home/gitlab-runner/builds/HASH/[0-N]/yourproject når parallellmontering er aktivert. Den ekstra gjenmonteringen vil være på grunn av at katalogen .git er forskjellig i forskjellige klonede versjoner av det samme depotet, selv om samme commit er bygget.

Det siste punktet får også konsekvenser ved bruk av werf. Werf krever at den innebygde cachen er tilstede når du kjører noen kommandoer (f.eks. werf deploy). Når disse kommandoene kjøres, beregner werf scenesignaturer for bildene spesifisert i werf.yaml, og de må være i assembly-cachen - ellers vil ikke kommandoen kunne fortsette å fungere. Hvis scenesignaturen avhenger av innholdet .git, så får vi en cache som er ustabil for endringer i irrelevante filer, og werf vil ikke kunne tilgi en slik forglemmelse (for mer detaljer, se dokumentasjon).

Generelt, legger bare til visse nødvendige filer gjennom instruksjonene ADD i alle fall øker effektiviteten og påliteligheten til det skrevne Dockerfile, og forbedrer også stabiliteten til cachen som samles inn for dette Dockerfile, til irrelevante endringer i Git.

Total

Vår første vei til å skrive vår egen byggherre for spesifikke behov var vanskelig, ærlig og grei: i stedet for å bruke krykker på toppen av standard Dockerfile, skrev vi løsningen vår med tilpasset syntaks. Og dette hadde sine fordeler: Stapel-samleren takler oppgaven sin perfekt.

I prosessen med å skrive vår egen byggherre mistet vi imidlertid støtten for eksisterende Dockerfiler av syne. Denne feilen er nå rettet, og i fremtiden planlegger vi å utvikle Dockerfile-støtte sammen med vår tilpassede Stapel-bygger for distribuerte bygg og for bygg som bruker Kubernetes (dvs. bygger på løpere inne i Kubernetes, slik det gjøres i kaniko).

Så hvis du plutselig har et par Dockerfiler liggende... prøve werf!

PS Liste over dokumentasjon om emnet

Les også i bloggen vår: "werf - vårt verktøy for CI/CD i Kubernetes (gjennomgang og videorapport)'.

Kilde: www.habr.com

Legg til en kommentar