Hacker News

BuildKit: bijuteria ascunsă a lui Docker, care poate construi aproape orice

Comentarii

17 min read Via tuananh.net

Mewayz Team

Editorial Team

Hacker News

BuildKit: bijuteria ascunsă a lui Docker care poate construi aproape orice

Majoritatea dezvoltatorilor cunosc Docker drept durata de rulare a containerului care a schimbat modul în care software-ul este livrat. Mult mai puțini știu despre motorul care fredonează în liniște sub suprafața fiecărei build moderne Docker - BuildKit, sistemul de build de ultimă generație care a fost livrat cu Docker începând cu versiunea 18.09 și a devenit backend-ul implicit în Docker 23.0. În timp ce inginerii se ceartă la nesfârșit despre configurațiile Kubernetes și modelele de microservicii, BuildKit a evoluat constant într-unul dintre cele mai puternice și flexibile sisteme de construcție din ecosistemul DevOps. Dacă ați tratat-o ​​doar ca pe o construcție docker mai rapidă, lăsați o capacitate enormă pe masă. Companiile care rulează conducte CI/CD de mare capacitate au redus timpul de construcție cu 50-70% pur și simplu prin înțelegerea ce oferă de fapt BuildKit - și acesta este doar începutul.

Ce face ca BuildKit să fie fundamental diferit de Classic Builder

Motorul de compilare Docker original a executat instrucțiunile Dockerfile secvenţial, câte un strat, fără a fi conștient de ce lucru ar putea avea loc în siguranță în paralel. BuildKit înlocuiește acel model de execuție liniară cu un grafic aciclic direcționat (DAG) - un grafic de dependență care înțelege care pași de construcție se bazează unul pe celălalt și care nu. Etapele independente se execută concomitent, etapele neutilizate sunt sărite în întregime, iar întreaga construcție devine o descriere declarativă a ceea ce doriți, mai degrabă decât o secvență imperativă de pași pe care trebuie să îi recitați în ordinea corectă.

Această schimbare arhitecturală are consecințe practice care depășesc viteza. Când un Dockerfile cu mai multe etape compilează un binar Go într-o etapă, descarcă dependențele Node.js într-o altă etapă și asamblează o imagine de producție într-o a treia, BuildKit poate rula primele două etape simultan. O construcție care anterior dura patru minute pentru un alergător CI puternic se finalizează acum în mai puțin de nouăzeci de secunde. Stripe, Shopify și zeci de alte echipe de inginerie la scară mare au documentat câștiguri similare în retrospectivele lor interne de instrumente. Modelul DAG înseamnă, de asemenea, că BuildKit poate genera metadate de construcție extrem de precise – o bază pentru funcții precum atestările de proveniență și generarea de liste de materiale software (SBOM), care contează enorm pentru securitatea lanțului de aprovizionare.

Există și o schimbare conceptuală în modul în care funcționează invalidarea memoriei cache. Constructorul clasic a invalidat fiecare strat sub orice instrucțiune modificată. BuildKit urmărește hashurile de conținut la fiecare intrare, astfel încât modificarea unui comentariu într-un fișier Docker nu duce la distrugerea unei intrări în cache care reprezintă treizeci de minute de compilare. Când memoria cache de construcție este diferența dintre o buclă de feedback de cinci minute și una de patruzeci de minute pentru echipa dvs. de ingineri, această precizie contează mult mai mult decât ar părea inițial.

Compilări cu mai multe platforme: o comandă, fiecare arhitectură

Indicatorul --platform al

BuildKit și integrarea QEMU transformă ceea ce odată a fost o problemă dureroasă de coordonare a mai multor sisteme într-o singură comandă. Rularea docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 . produce trei imagini gata de producție în paralel dintr-o singură invocare a versiunii. Această capacitate a devenit critică pe măsură ce industria trece la ARM — instanțe AWS Graviton3 oferă în mod constant un preț-performanță mai bun cu 40% la sarcini de lucru precum servirea web și procesarea datelor, iar Apple Silicon a făcut din ARM mașina de dezvoltare implicită pentru milioane de ingineri.

Înainte de a se maturiza suportul pentru mai multe platforme de la BuildKit, menținerea conductelor de construcție separate pentru diferite arhitecturi era un adevărat centru de cost. Echipele fie au întreținut mai multe fișiere Dockerfile, au rulat conducte CI separate pe sisteme de rulare cu arhitectură diferită sau pur și simplu au expediat imagini x86 peste tot și au plătit penalizarea de performanță pe infrastructura ARM. Cu BuildKit, vă definiți construcția o dată și lăsați sistemul să gestioneze în mod transparent compilarea specifică arhitecturii. Proiecte Rust care necesită compilare încrucișată, proiecte Go cu dependențe CGO, pachete Python cu extensii C — BuildKit se ocupă de stratul de emulare fără a fi necesar să înțelegeți detaliile fiecărei platforme țintă.

Valoarea practică a afacerii aici este măsurabilă. O echipă care rulează 200 de containere pe instanțe AWS Graviton la 0,04 USD per oră vCPU față de instanța x86 echivalentă la 0,056 USD pe oră vCPU economisește aproximativ 11.520 USD anual pentru 100 de vCPU - pur și simplu din alegerea arhitecturii potrivite. A face această alegere accesibilă fără un efort de reproiectare este exact genul de optimizare a infrastructurii care se amortizează imediat.

Gestionare secretă fără scurgeri în straturi de imagine

Una dintre cele mai subapreciate funcții BuildKit este API-ul său secrete. Generatorul clasic Docker nu avea nicio modalitate curată de a trece acreditările într-o versiune fără ca acele acreditări să ajungă potențial într-un strat de imagine. Dezvoltatorii au rezolvat acest lucru cu versiuni în mai multe etape, instrucțiuni ARG și comandă atentă – dar riscul de a coace accidental o cheie API sau o cheie SSH privată într-o imagine livrată a rămas incomod de mare. Scanerele de securitate găsesc în mod obișnuit acreditări codificate în imaginile containerului publicate în registrele publice, iar multe dintre aceste scurgeri se regăsesc direct din manipularea neîndemânatică a secretelor în timpul build-urilor.

Marcatorul --secret al

BuildKit-ului montează datele sensibile în mediul de construcție ca o cale temporară a sistemului de fișiere care există doar pe durata instrucțiunii specifice RUN care are nevoie de el și nu atinge niciodată niciun strat de imagine. O instrucțiune Dockerfile precum RUN --mount=type=secret,id=npmrc cat /run/secrets/npmrc > ~/.npmrc && npm install oferă procesului de construire acces la acreditările private npm fără ca acele acreditări să apară vreodată în imaginea finală sau în orice strat intermediar. Același model funcționează pentru acreditările PyPI, setările Maven, cheile SSH pentru depozitele private Git și orice alt material sensibil de care procesul de compilare necesită.

Pentru echipele care creează software care atinge industriile reglementate — platforme de asistență medicală, produse fintech, software de resurse umane — diferența dintre „acreditările ar putea fi în imagine” și „acreditările care se dovedesc că nu pot fi în imagine” este diferența dintre trecerea unui audit de securitate și a petrece trei săptămâni pentru a remedia constatările. Platforme precum Mewayz, care alimentează operațiunile de afaceri pentru peste 138.000 de utilizatori din industrii precum salarizarea, resursele umane și facturarea, depind exact de acest tip de poziție de securitate demonstrabilă în conductele lor de construire și implementare pentru a menține încrederea pe care acești clienți o acordă datelor lor financiare și de personal sensibile.

Exporturi în cache: rapiditatea conductelor CI

Conductele CI sunt acolo unde performanța de construire contează cel mai mult și acolo unde experiența de construcție Docker implicită a fost din istorie cea mai dureroasă. Proaspeții care rulează CI încep de obicei cu cache-urile goale, ceea ce înseamnă că fiecare rulare pipeline recompilează totul de la zero. Pentru un serviciu Java cu sute de dependențe Maven, un proiect Rust sau o aplicație Python cu extensii native grele, aceasta înseamnă timpi de construcție măsurați în zeci de minute și nu în secunde. Costul de afaceri al CI lent este enorm – frecvența redusă de implementare, bucle de feedback mai lungi și inginerii stau inactiv în așteptarea finalizării conductelor înainte de a putea fuziona și merge mai departe.

Funcția de export cache a BuildKit rezolvă acest lucru cu manifeste cache exportabile. Folosind --cache-to type=registry,ref=myregistry/myapp:cache și --cache-from type=registry,ref=myregistry/myapp:cache, BuildKit trimite un instantaneu cache detaliat într-un registry după fiecare construcție și îl extrage la începutul următoarei. Cache-ul este adresat conținutului, așa că numai straturile modificate cu adevărat sunt preluate din nou. Echipele care folosesc acest model în GitHub Actions, GitLab CI și CircleCI reduc în mod obișnuit timpii de canalizare de la cincisprezece minute la mai puțin de trei în rulările ulterioare. Documentația proprie GitHub despre fluxurile de lucru avansate de construire Docker recomandă cu tărie acest model tocmai din acest motiv.

Cea mai rapidă versiune este cea pe care nu trebuie să o rulați din nou. Sistemul de cache stratificat, adresat conținutului, al BuildKit nu doar accelerează construcția, ci face întregul concept de „construcție” mai inteligent, transformând o compilație repetată într-o diferență incrementală a exact ceea ce s-a schimbat.

Exporturile de cache se integrează, de asemenea, curat cu fluxurile de lucru de dezvoltare bazate pe ramuri. Puteți configura conducta CI să se retragă de la un cache specific unei ramuri la cache-ul ramurilor principale atunci când nu există cache-ul ramurilor, ceea ce înseamnă că noile ramuri beneficiază imediat de cache-ul cald acumulat de linia principală de dezvoltare. Inginerii primesc feedback rapid de la prima lor angajare pe o nouă filială, mai degrabă decât să aștepte printr-o penalizare de pornire la rece.

💡 DID YOU KNOW?

Mewayz replaces 8+ business tools in one platform

CRM · Invoicing · HR · Projects · Booking · eCommerce · POS · Analytics. Free forever plan available.

Start Free →

BuildKit Frontends: Construire dincolo de fișierele Docker

Poate că cea mai puțin cunoscută capacitate a BuildKit este că Dockerfiles sunt doar un format de intrare posibil, nu singurul. BuildKit are o arhitectură frontală conectabilă, care permite limbaje și formate de definiție complet personalizate. Interfața este specificată de directiva # syntax= din partea de sus a fișierului dvs. de compilare, care îi spune BuildKit să extragă o anumită imagine frontend și să o folosească pentru a analiza și a executa restul fișierului.

Această arhitectură a permis mai multe proiecte convingătoare. Integrarea Buildpacks permite BuildKit să construiască imagini container din codul sursă al aplicației fără nici un Dockerfile - detectează limbajul, alege imaginile de bază adecvate și asamblează automat un container gata de producție. HPC și comunitățile de calcul științific au folosit interfețe personalizate pentru a descrie versiunile în limbaje specifice domeniului, care se compilează până la reprezentarea internă LLB (Low-Level Build) a BuildKit. Sintaxa docker/dockerfile:labs experimentează cu funcții precum suportul heredoc, controlul --network pe instrucțiune și indicii îmbunătățite pentru cache înainte de a ajunge în sintaxa Dockerfile stabilă.

Abilitatea de a vă defini propriul frontend înseamnă, de asemenea, că organizațiile cu cerințe de construcție neobișnuite nu trebuie să aleagă între „shoehorn everything into Dockerfile syntax” și „abandona complet containerele”. Un firmware FPGA de team building, imagini de sisteme încorporate sau containere de modele ML specializate pot descrie construcția lor în termeni care au sens pentru domeniul lor, producând în același timp imagini de containere standard, conforme cu OCI, care se implementează oriunde rulează containerele. Această extensibilitate este un avantaj arhitectural autentic față de sistemele de construcție care tratează formatul lor de intrare ca fiind fix.

Provență și SBOM: clădire pentru lumea post-SolarWinds

Securitatea lanțului de aprovizionare a software-ului a trecut de la preocuparea teoretică la prioritatea la nivel de consiliu după încălcarea SolarWinds în 2020 și vulnerabilitatea Log4Shell în 2021. Ordinul executiv 14028 al guvernului SUA privind securitatea cibernetică, emis în mai 2021, a impus contractorilor federali o listă de materiale de software. Atestările de proveniență ale BuildKit și caracteristicile de generare SBOM sunt un răspuns direct la acest peisaj de reglementare și securitate.

Cu steaguri --provenance=true și --sbom=true, BuildKit generează atestări semnate criptografic care descriu exact ce a intrat într-o imagine de container - ce imagini de bază au fost folosite, ce instrucțiuni Dockerfile au executat, ce fișiere sursă au fost prezente și ce dependențe externe au fost preluate. Aceste atestări urmează cadrul SLSA (Supply-chain Levels for Software Artefacts) și formatul de atestare în întregime, făcându-le verificabile automat de către motoarele de politici precum Cosign și OPA (Open Policy Agent) de la Sigstore.

Fluxul de lucru practic pe care îl permite acest lucru arată astfel:

  1. Dezvoltatorul introduce codul; Conducta CI declanșează o versiune BuildKit cu proveniența activată.
  2. BuildKit generează un SBOM semnat care listează toate componentele și versiunile acestora.
  3. SBOM este publicat în registrul containerului alături de manifestul imagine.
  4. Controlerii de admitere din clusterul Kubernetes verifică proveniența înainte de a permite implementarea.
  5. Scanerele de vulnerabilitate interogează SBOM pentru a identifica imaginile afectate atunci când sunt dezvăluite noi CVE.

Echipele care implementează această conductă completă pot răspunde la dezvăluirile de vulnerabilități în ore mai degrabă decât în zile, deoarece au o hartă precisă, care poate fi citită de mașină, a fiecărei componente din fiecare container care rulează. Pentru companii precum Mewayz care se integrează profund în fluxurile de lucru operaționale ale clienților — rularea salariilor, gestionarea datelor flotei, procesarea facturilor — capacitatea de a demonstra un lanț de aprovizionare riguros și auditabil este din ce în ce mai mult o condiție prealabilă pentru conversațiile de vânzări ale întreprinderii, nu doar un lucru plăcut de a avea.

Noțiuni introductive: de la versiunile implicite la conductele avansate

BuildKit rulează deja în mediul dvs. Docker dacă utilizați o versiune recentă — Docker 23.0 și mai târziu, activați-o implicit. Primul pas practic pentru majoritatea echipelor este activarea pluginului Docker Buildx, care expune setul complet de caracteristici BuildKit prin subcomandă docker buildx. Rularea docker buildx create --use setează o instanță de constructor BuildKit cu mai multe capacități decât driverul implicit. De aici, adoptarea progresivă a funcțiilor avansate are sens, mai degrabă decât încercarea de a adopta totul deodată.

O cale de adoptare rezonabilă pentru o echipă care efectuează în prezent invocări de bază docker build arată ca adăugarea mai întâi a exporturilor cache la CI - aceasta oferă îmbunătățiri imediate, măsurabile ale vitezei, cu o modificare minimă a configurației. Compilările multi-platformă devin valoroase atunci când echipa începe să vizeze infrastructura ARM. Montarea secretă merită adoptată de fiecare dată când apar registre private de pachete sau chei SSH în contextul construirii. Atestările de proveniență au sens pentru a fi activate atunci când cerințele de conformitate sau cerințele clienților întreprinderii fac necesară documentarea lanțului de aprovizionare.

Lecția mai profundă a BuildKit este despre construirea în mod deliberat. Indiferent dacă expediați un container pentru un microserviciu, un punct final de inferență de învățare automată sau o platformă complexă precum suita Mewayz de 207 module de afaceri, procesul de construire nu este o formalitate prin care vă grăbiți în drumul spre implementare - este un artefact de inginerie care reflectă calitatea, postura de securitate și maturitatea operațională a tot ceea ce este livrat din el. BuildKit vă oferă instrumentele pentru a face acel artefact excelent. Întrebarea este pur și simplu dacă îți faci timp să le folosești.

Întrebări frecvente

Ce este BuildKit și prin ce diferă de sistemul clasic de compilare Docker?

BuildKit este motorul de compilare de ultimă generație al Docker, introdus în Docker 18.09 și a devenit implicit în Docker 23.0. Spre deosebire de generatorul clasic, BuildKit acceptă execuția de straturi paralele, strategii avansate de stocare în cache, montarea secretelor și build-uri pe mai multe platforme. Acesta tratează procesul de construire ca un grafic aciclic direcționat (DAG), permițând o rezoluție mai inteligentă a dependenței și timpi de construcție dramatic mai rapidi pentru fișierele Dockerfile complexe, în mai multe etape.

Trebuie să instalez ceva suplimentar pentru a începe să folosesc BuildKit cu Docker?

Nu este necesară nicio instalare suplimentară dacă rulați Docker 23.0 sau o versiune ulterioară — BuildKit este activat în mod implicit. Pe versiunile mai vechi, îl puteți activa setând variabila de mediu DOCKER_BUILDKIT=1 înainte de a rula comenzile de compilare. Pentru cazuri de utilizare avansate, cum ar fi cache-urile de compilare de la distanță sau versiunile multiplatformă, este posibil să doriți să configurați o instanță de constructor Buildx dedicată utilizând docker buildx create.

Poate fi folosit BuildKit pentru a construi artefacte dincolo de imaginile standard ale containerelor?

Da, iar aceasta este una dintre cele mai subapreciate capabilități ale BuildKit. Folosind interfețe personalizate și marcatorul --output, BuildKit poate produce fișiere binare brute, tarball-uri, site-uri web statice și alte artefacte de fișiere arbitrare - nu doar imagini OCI. Acest lucru îl face un motor de construcție de uz general, care se potrivește în mod natural în monorepo-uri poliglote și în conducte CI complexe, în care diferite echipe au nevoie de formate diferite de ieșire dintr-un lanț de instrumente unificat.

Cum se potrivește BuildKit într-o platformă DevOps mai largă, alături de instrumente precum Mewayz?

BuildKit se ocupă de nivelul de construcție de nivel scăzut, dar echipele moderne de dezvoltare trebuie, de asemenea, să gestioneze fluxurile de lucru ale afacerii, livrarea clienților și procesele operaționale. Platforme precum Mewayz — un sistem de operare de afaceri cu 207 module, începând de la 19 USD/lună — completează instrumentele de infrastructură, acoperind partea operațională a afacerilor cu software. Asocierea conductelor de construcție eficiente, alimentate de BuildKit cu o platformă all-in-one precum Mewayz, oferă echipelor o stivă completă, de la artefactul de cod până la livrarea clienților.