Acum puteți construi imagini Docker în werf folosind un fișier Dockerfile obișnuit

Mai bine mai tarziu decat niciodata. Sau cum aproape că am făcut o greșeală gravă nefiind suport pentru fișierele Dockerfile obișnuite pentru a construi imagini ale aplicațiilor.

Acum puteți construi imagini Docker în werf folosind un fișier Dockerfile obișnuit

Vom vorbi despre werf — Utilitar GitOps care se integrează cu orice sistem CI/CD și oferă gestionarea întregului ciclu de viață al aplicației, permițând:

  • colectează și publică imagini,
  • implementați aplicații în Kubernetes,
  • ștergeți imaginile neutilizate folosind politici speciale.


Filosofia proiectului este de a colecta instrumente de nivel scăzut într-un singur sistem unificat care oferă inginerilor DevOps controlul asupra aplicațiilor. Dacă este posibil, ar trebui utilizate utilitățile existente (cum ar fi Helm și Docker). Dacă nu există o soluție la o problemă, putem crea și sprijini tot ceea ce este necesar pentru aceasta.

Fundal: propriul tău colecționar de imagini

Iată ce s-a întâmplat cu colectorul de imagini din werf: obișnuitul Dockerfile nu ne-a fost suficient. Dacă aruncați o privire rapidă în istoria proiectului, această problemă a apărut deja în primele versiuni ale werf (atunci încă cunoscut sub numele de dapp).

În timp ce am creat un instrument pentru construirea de aplicații în imaginile Docker, am realizat rapid că Dockerfile nu era potrivit pentru noi pentru anumite sarcini foarte specifice:

  1. Necesitatea de a construi aplicații web tipice mici conform următoarei scheme standard:
    • instalați dependențe de aplicații la nivel de sistem,
    • instalați un pachet de biblioteci de dependență de aplicații,
    • colectează bunuri,
    • și cel mai important, actualizați codul din imagine rapid și eficient.
  2. Când se fac modificări la fișierele de proiect, constructorul trebuie să creeze rapid un nou strat aplicând un patch fișierelor modificate.
  3. Dacă anumite fișiere s-au schimbat, atunci este necesar să reconstruiți etapa dependentă corespunzătoare.

Astăzi colecționarul nostru are multe alte posibilități, dar acestea au fost dorințele și îndemnurile inițiale.

În general, fără să ne gândim de două ori, ne-am înarmat cu limbajul de programare pe care l-am folosit (Vezi mai jos) și pornește pe drumul de implementare propriul DSL! În conformitate cu obiectivele, s-a dorit descrierea procesului de asamblare în etape și determinarea dependențelor acestor etape de fișiere. Și l-a completat propriul colector, care a transformat DSL-ul în obiectivul final - o imagine asamblată. La început DSL-ul era în Ruby, dar ca trecerea la Golang — configurația colectorului nostru a început să fie descrisă într-un fișier YAML.

Acum puteți construi imagini Docker în werf folosind un fișier Dockerfile obișnuit
Configurație veche pentru dapp în Ruby

Acum puteți construi imagini Docker în werf folosind un fișier Dockerfile obișnuit
Configurația curentă pentru werf pe YAML

Mecanismul colectorului s-a schimbat și el în timp. La început, am generat pur și simplu un Dockerfile temporar din configurația noastră, apoi am început să rulăm instrucțiuni de asamblare în containere temporare și să comităm.

NB: În acest moment, colecționarul nostru, care funcționează cu propria sa configurație (în YAML) și se numește colectorul Stapel, s-a dezvoltat deja într-un instrument destul de puternic. Descrierea sa detaliată merită articole separate, iar detaliile de bază pot fi găsite în documentație.

Conștientizarea problemei

Dar ne-am dat seama, și nu imediat, că am făcut o singură greșeală: nu am adăugat capacitatea construiți imagini prin Dockerfile standard și să le integreze în aceeași infrastructură de gestionare a aplicațiilor end-to-end (adică colectați imagini, implementați și curățați-le). Cum ar putea fi posibil să se creeze un instrument pentru implementare în Kubernetes și să nu se implementeze suportul Dockerfile, de ex. mod standard de a descrie imaginile pentru majoritatea proiectelor?...

În loc să răspundem la această întrebare, oferim o soluție. Ce se întâmplă dacă aveți deja un Dockerfile (sau un set de Dockerfiles) și doriți să utilizați werf?

NB: Apropo, de ce ai vrea să folosești werf? Principalele caracteristici se reduc la următoarele:

  • ciclu complet de gestionare a aplicațiilor, inclusiv curățarea imaginii;
  • capacitatea de a gestiona asamblarea mai multor imagini simultan dintr-o singură configurație;
  • Proces de implementare îmbunătățit pentru diagramele compatibile cu Helm.

O listă mai completă a acestora poate fi găsită la pagina proiectului.

Deci, dacă mai devreme ne-am fi oferit să rescriem fișierul Dockerfile în configurația noastră, acum vom spune cu bucurie: „Lăsați werf să vă construiască fișierele Docker!”

Cum se utilizează?

Implementarea completă a acestei caracteristici a apărut în versiune werf v1.0.3-beta.1. Principiul general este simplu: utilizatorul specifică calea către un fișier Dockerfile existent în configurația werf și apoi rulează comanda werf build... și atât - werf va asambla imaginea. Să ne uităm la un exemplu abstract.

Hai sa il anuntam pe urmatorul Dockerfile în rădăcina proiectului:

FROM ubuntu:18.04
RUN echo Building ...

Și vom anunța werf.yamlcare foloseste aceasta Dockerfile:

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

Toate! Stânga alerga werf build:

Acum puteți construi imagini Docker în werf folosind un fișier Dockerfile obișnuit

În plus, puteți declara următoarele werf.yaml pentru a construi mai multe imagini din diferite Dockerfile simultan:

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

În cele din urmă, acceptă, de asemenea, transmiterea unor parametri de compilare suplimentari, cum ar fi --build-arg и --add-host - prin werf config. O descriere completă a configurației imaginii Dockerfile este disponibilă la pagina de documentație.

Cum funcționează?

În timpul procesului de construire, cache-ul standard al straturilor locale din Docker funcționează. Totuși, ceea ce este important este că și werf integrează configurația Dockerfile în infrastructura sa. Ce inseamna asta?

  1. Fiecare imagine construită dintr-un Dockerfile constă dintr-o etapă numită dockerfile (puteți citi mai multe despre ce etape sunt în werf aici).
  2. Pentru scena dockerfile werf calculează o semnătură care depinde de conținutul configurației Dockerfile. Când se modifică configurația Dockerfile, semnătura etapei se schimbă dockerfile iar werf inițiază o reconstrucție a acestei etape cu o nouă configurație Dockerfile. Dacă semnătura nu se schimbă, atunci werf preia imaginea din cache (mai multe detalii despre utilizarea semnăturilor în werf au fost descrise în acest raport).
  3. Apoi, imaginile colectate pot fi publicate cu comanda werf publish (Sau, werf build-and-publish) și folosiți-l pentru implementarea în Kubernetes. Imaginile publicate în Registrul Docker vor fi curățate folosind instrumente standard de curățare werf, de ex. Imaginile vechi (mai vechi de N zile), imaginile asociate cu ramuri Git inexistente și alte politici vor fi curățate automat.

Mai multe detalii despre punctele descrise aici pot fi găsite în documentație:

Note și precauții

1. Adresa URL externă nu este acceptată în ADD

În prezent, nu este acceptată utilizarea unui URL extern într-o directivă ADD. Werf nu va iniția o reconstrucție atunci când resursa de la adresa URL specificată se schimbă. Intenționăm să adăugăm această funcție în curând.

2. Nu puteți adăuga .git la imagine

În general, adăugarea unui director .git în imagine - o practică proastă și iată de ce:

  1. Dacă .git rămâne în imaginea finală, aceasta încalcă principiile Aplicație cu 12 factori: Deoarece imaginea finală trebuie să fie legată de un singur commit, nu ar trebui să fie posibil git checkout comiterea arbitrară.
  2. .git mărește dimensiunea imaginii (depozitul poate fi mare datorită faptului că odată au fost adăugate fișiere mari și apoi șterse). Mărimea unui arbore de lucru asociat doar cu un anumit commit nu va depinde de istoricul operațiunilor din Git. În acest caz, adăugarea și eliminarea ulterioară .git din imaginea finală nu va funcționa: imaginea va dobândi în continuare un strat suplimentar - așa funcționează Docker.
  3. Docker poate iniția o reconstrucție inutilă, chiar dacă se construiește același commit, dar din arbori de lucru diferiți. De exemplu, GitLab creează directoare clonate separate în /home/gitlab-runner/builds/HASH/[0-N]/yourproject când asamblarea paralelă este activată. Reasamblarea suplimentară se va datora faptului că directorul .git este diferit în diferite versiuni clonate ale aceluiași depozit, chiar dacă este construit același commit.

Ultimul punct are și consecințe atunci când se folosește werf. Werf necesită cache-ul construit să fie prezent atunci când rulează unele comenzi (de ex. werf deploy). Când rulează aceste comenzi, werf calculează semnăturile de etapă pentru imaginile specificate în werf.yaml, și trebuie să fie în memoria cache de asamblare - altfel comanda nu va putea continua să funcționeze. Dacă semnătura scenei depinde de conținut .git, apoi obținem un cache care este instabil la modificările în fișierele irelevante, iar werf nu va putea ierta o astfel de neglijare (pentru mai multe detalii, consultați documentație).

În general, adăugând doar anumite fișiere necesare prin instructiuni ADD în orice caz crește eficiența și fiabilitatea scrisului Dockerfileși, de asemenea, îmbunătățește stabilitatea cache-ului colectat pentru aceasta Dockerfile, la modificări irelevante în Git.

Total

Calea noastră inițială de a scrie propriul nostru builder pentru nevoi specifice a fost grea, sinceră și directă: în loc să folosim cârje pe deasupra fișierului Dockerfile standard, am scris soluția noastră cu sintaxă personalizată. Și aceasta a avut avantajele sale: colecționarul Stapel își face față perfect sarcinii.

Cu toate acestea, în procesul de scriere a propriului constructor, am pierdut din vedere suportul pentru fișierele Dockerfile existente. Această defecțiune a fost acum remediată și, în viitor, intenționăm să dezvoltăm suport pentru Dockerfile împreună cu generatorul nostru Stapel personalizat pentru asamblarea distribuită și pentru asamblarea utilizând Kubernetes (adică asamblarea pe rulare în interiorul Kubernetes, așa cum se face în kaniko).

Deci, dacă deodată aveți câteva Dockerfiles întins prin preajmă... încercați werf!

PS Lista de documentație pe această temă

Citește și pe blogul nostru: „werf - instrumentul nostru pentru CI / CD în Kubernetes (prezentare generală și raport video)".

Sursa: www.habr.com

Adauga un comentariu