Du kan nu bygga Docker-bilder i werf med en vanlig Dockerfil

Bättre sent än aldrig. Eller hur vi nästan gjorde ett allvarligt misstag genom att inte ha stöd för vanliga Dockerfiler för att bygga applikationsbilder.

Du kan nu bygga Docker-bilder i werf med en vanlig Dockerfil

Vi ska prata om werf — GitOps-verktyg som integreras med alla CI/CD-system och ger hantering av hela applikationens livscykel, vilket tillåter:

  • samla in och publicera bilder,
  • distribuera applikationer i Kubernetes,
  • radera oanvända bilder med särskilda policyer.


Projektets filosofi är att samla verktyg på låg nivå i ett enda enhetligt system som ger DevOps-ingenjörer kontroll över applikationer. Om möjligt bör befintliga verktyg (som Helm och Docker) användas. Om det inte finns någon lösning på ett problem kan vi skapa och stödja allt som behövs för detta.

Bakgrund: din egen bildsamlare

Detta är vad som hände med bildsamlaren i werf: den vanliga Dockerfilen räckte inte för oss. Om du tar en snabb titt på projektets historia dök detta problem upp redan i de första versionerna av werf (då fortfarande känd som dapp).

När vi skapade ett verktyg för att bygga in applikationer i Docker-bilder insåg vi snabbt att Dockerfile inte var lämpligt för oss för vissa mycket specifika uppgifter:

  1. Behovet av att bygga typiska små webbapplikationer enligt följande standardschema:
    • installera systemomfattande applikationsberoenden,
    • installera ett paket med programberoendebibliotek,
    • samla in tillgångar,
    • och viktigast av allt, uppdatera koden i bilden snabbt och effektivt.
  2. När ändringar görs i projektfiler måste byggaren snabbt skapa ett nytt lager genom att applicera en patch på de ändrade filerna.
  3. Om vissa filer har ändrats, är det nödvändigt att bygga om motsvarande beroende steg.

Idag har vår samlare många andra möjligheter, men dessa var de första önskemålen och drifterna.

I allmänhet, utan att tänka två gånger, beväpnade vi oss med det programmeringsspråk vi använde (se nedan) och ge sig ut på vägen för att genomföra egen DSL! I enlighet med målen var det tänkt att beskriva monteringsprocessen i etapper och bestämma dessa stegs beroende av filer. Och kompletterade den egen samlare, som förvandlade DSL till det slutliga målet - en samlad bild. Först var DSL i Ruby, men som övergång till Golang — konfigurationen av vår samlare började beskrivas i en YAML-fil.

Du kan nu bygga Docker-bilder i werf med en vanlig Dockerfil
Gammal konfiguration för dapp i Ruby

Du kan nu bygga Docker-bilder i werf med en vanlig Dockerfil
Aktuell konfiguration för werf på YAML

Samlarens mekanism förändrades också över tiden. Till en början genererade vi helt enkelt en tillfällig Dockerfil i farten från vår konfiguration, och sedan började vi köra monteringsinstruktioner i tillfälliga behållare och commit.

NB: För tillfället har vår samlare, som arbetar med sin egen konfiguration (i YAML) och kallas Stapel-samlaren, redan utvecklats till ett ganska kraftfullt verktyg. Dess detaljerade beskrivning förtjänar separata artiklar, och grundläggande detaljer finns i dokumentation.

Medvetenhet om problemet

Men vi insåg, och inte direkt, att vi hade gjort ett misstag: vi lade inte till förmågan bygga bilder via standard Dockerfile och integrera dem i samma end-to-end-applikationshanteringsinfrastruktur (dvs. samla in bilder, distribuera och rensa dem). Hur skulle det kunna vara möjligt att göra ett verktyg för utplacering i Kubernetes och inte implementera Dockerfile-stöd, d.v.s. standardsätt att beskriva bilder för de flesta projekt?

Istället för att svara på denna fråga erbjuder vi en lösning. Vad händer om du redan har en Dockerfile (eller en uppsättning Dockerfiler) och vill använda werf?

NB: Förresten, varför skulle du ens vilja använda werf? Huvuddragen kokar ner till följande:

  • fullständig programhanteringscykel inklusive bildrengöring;
  • förmågan att hantera sammansättningen av flera bilder samtidigt från en enda konfiguration;
  • Förbättrad distributionsprocess för Helm-kompatibla sjökort.

En mer komplett lista över dem finns på projektsida.

Så om vi tidigare skulle ha erbjudit oss att skriva om Dockerfilen i vår konfiguration, säger vi nu glatt: "Låt werf bygga dina Dockerfiler!"

Hur man använder

Den fullständiga implementeringen av denna funktion dök upp i releasen werf v1.0.3-beta.1. Den allmänna principen är enkel: användaren anger sökvägen till en befintlig Dockerfil i werf-konfigurationen och kör sedan kommandot werf build... och det är allt - werf kommer att montera bilden. Låt oss titta på ett abstrakt exempel.

Låt oss meddela nästa Dockerfile i projektroten:

FROM ubuntu:18.04
RUN echo Building ...

Och vi kommer att meddela werf.yamlsom använder detta Dockerfile:

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

Allt! Vänster springa werf build:

Du kan nu bygga Docker-bilder i werf med en vanlig Dockerfil

Dessutom kan du deklarera följande werf.yaml för att bygga flera bilder från olika Dockerfiler samtidigt:

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

Slutligen stöder den också att skicka ytterligare byggparametrar, som t.ex --build-arg и --add-host - via werf config. En fullständig beskrivning av Dockerfile-bildkonfigurationen finns tillgänglig på dokumentationssida.

Hur fungerar det?

Under byggprocessen fungerar standardcachen för lokala lager i Docker. Men det som är viktigt är att werf också integrerar Dockerfile-konfiguration i sin infrastruktur. Vad betyder det här?

  1. Varje bild byggd från en Dockerfil består av ett steg som kallas dockerfile (du kan läsa mer om vilka stadier som finns i werf här).
  2. För scen dockerfile werf beräknar en signatur som beror på innehållet i Dockerfile-konfigurationen. När Dockerfile-konfigurationen ändras ändras scensignaturen dockerfile och werf initierar en ombyggnad av detta steg med en ny Dockerfile-konfiguration. Om signaturen inte ändras, tar werf bilden från cachen (mer information om användningen av signaturer i werf beskrevs i denna rapport).
  3. Därefter kan de insamlade bilderna publiceras med kommandot werf publish (eller werf build-and-publish) och använd den för distribution till Kubernetes. Publicerade bilder till Docker Registry kommer att rengöras med vanliga werf-rensningsverktyg, dvs. Gamla bilder (äldre än N dagar), bilder associerade med icke-existerande Git-grenar och andra policyer kommer att rensas automatiskt.

Mer information om punkterna som beskrivs här finns i dokumentationen:

Anmärkningar och försiktighetsåtgärder

1. Extern URL stöds inte i ADD

För närvarande stöds det inte att använda en extern URL i ett direktiv ADD. Werf kommer inte att initiera en ombyggnad när resursen på den angivna webbadressen ändras. Vi planerar att lägga till den här funktionen snart.

2. Du kan inte lägga till .git till bilden

Generellt sett, att lägga till en katalog .git på bilden - en ondsint dålig praxis och här är varför:

  1. Om .git förblir i den slutliga bilden bryter detta mot principerna 12 faktor app: Eftersom den slutliga bilden måste kopplas till en enstaka commit bör det inte vara möjligt att göra git checkout godtyckligt åtagande.
  2. .git ökar storleken på bilden (förvaret kan vara stort på grund av att stora filer en gång lades till och sedan raderades). Storleken på ett arbetsträd som endast är associerat med en specifik commit kommer inte att bero på historiken för operationer i Git. I det här fallet, tillägget och efterföljande borttagning .git från den slutliga bilden kommer inte att fungera: bilden kommer fortfarande att få ett extra lager - så här fungerar Docker.
  3. Docker kan initiera en onödig ombyggnad, även om samma commit byggs, men från olika arbetsträd. Till exempel skapar GitLab separata klonade kataloger i /home/gitlab-runner/builds/HASH/[0-N]/yourproject när parallell montering är aktiverad. Den extra återmonteringen kommer att bero på att katalogen .git är olika i olika klonade versioner av samma arkiv, även om samma commit är byggd.

Den sista punkten får också konsekvenser vid användning av werf. Werf kräver att den inbyggda cachen finns när du kör vissa kommandon (t.ex. werf deploy). När dessa kommandon körs, beräknar werf scensignaturer för bilderna som anges i werf.yaml, och de måste finnas i monteringscachen - annars kommer kommandot inte att kunna fortsätta att fungera. Om scensignaturen beror på innehållet .git, då får vi en cache som är instabil för ändringar i irrelevanta filer, och werf kommer inte att kunna förlåta ett sådant förbiseende (för mer information, se dokumentation).

övergripande lägger bara till vissa nödvändiga filer genom instruktionerna ADD i alla fall ökar effektiviteten och tillförlitligheten i det skrivna Dockerfile, och förbättrar även stabiliteten för cachen som samlas in för detta Dockerfile, till irrelevanta ändringar i Git.

Totalt

Vår första väg att skriva vår egen byggare för specifika behov var svår, ärlig och okomplicerad: istället för att använda kryckor ovanpå standard Dockerfile skrev vi vår lösning med anpassad syntax. Och detta hade sina fördelar: Stapel-samlaren klarar sin uppgift perfekt.

Men i processen att skriva vår egen byggare förlorade vi stödet för befintliga Dockerfiler ur sikte. Det här felet har nu åtgärdats, och i framtiden planerar vi att utveckla Dockerfile-stöd tillsammans med vår anpassade Stapel-byggare för distribuerade builds och för builds med Kubernetes (dvs bygger på löpare inuti Kubernetes, som görs i kaniko).

Så, om du plötsligt har ett par Dockerfiler liggande... prova werf!

PS Lista över dokumentation om ämnet

Läs även i vår blogg: "werf - vårt verktyg för CI / CD i Kubernetes (översikt och videorapport)".

Källa: will.com

Lägg en kommentar