Meglio tardi che mai. O come abbiamo rischiato di commettere un grave errore non avendo il supporto degli standard Dockerfile per la creazione delle immagini dell'applicazione.

Si parlerà di — un'utilità GitOps che si integra con qualsiasi sistema CI/CD e fornisce gestione dell'intero ciclo di vita dell'applicazione, consentendo di:
- creare e pubblicare immagini,
- distribuire applicazioni su Kubernetes,
- rimuovere immagini non utilizzate mediante politiche specifiche.
La filosofia del progetto è raccogliere strumenti di basso livello in un'unica sistema unificato, dando agli ingegneri DevOps il controllo sulle applicazioni. Dovrebbero essere utilizzati strumenti già esistenti (come Helm e Docker) ogni volta che possibile. Se non c'è una soluzione per un certo problema, possiamo creare e mantenere tutto il necessario.
Antefatti: il nostro costruttore di immagini
Così è successo con il costruttore di immagini in werf: ci mancava il consueto Dockerfile. Se si guarda brevemente alla storia del progetto, questo problema è emerso già nelle prime versioni di werf (all'epoca ancora ).
Creando uno strumento per la costruzione di applicazioni in immagini Docker, abbiamo rapidamente capito che il Dockerfile non era adatto per alcune specifiche attività:
- La necessità di costruire tipiche piccole applicazioni web secondo il seguente schema standard:
- installare le dipendenze di sistema dell'applicazione,
- installare il bundle delle librerie di dipendenza dell'applicazione,
- creare asset,
- e cosa più importante — aggiornare il codice nell'immagine in modo rapido ed efficiente.
- Quando ci sono modifiche nei file del progetto, il costruttore deve rapidamente creare un nuovo layer sovrapponendo la patch ai file modificati.
- Se alcuni file sono cambiati, è necessario ricostruire la fase dipendente corrispondente.
Oggi il nostro costruttore ha molte altre capacità, ma i desideri e gli impulsi iniziali erano questi.
In generale, senza pensarci troppo, abbiamo afferrato il linguaggio di programmazione utilizzato (vedi sotto) e siamo partiti — per realizzare un nostro DSL! In linea con le esigenze poste, era progettato per descrivere il processo di costruzione in fasi e definire le dipendenze di queste fasi dai file. E lo completava un costruttore personale, che trasformava il DSL nell'obiettivo finale — l'immagine costruita. All'inizio, il DSL era in Ruby, e man mano che , la configurazione del nostro costruttore è stata iniziata a essere descritta in un file YAML.

La vecchia configurazione per dapp in Ruby

La configurazione attuale per werf in YAML
Il meccanismo di lavoro del costruttore è cambiato anche nel tempo. Inizialmente generavamo in tempo reale un Dockerfile temporaneo dalla nostra configurazione, e poi abbiamo iniziato a eseguire le istruzioni di costruzione in contenitori temporanei e a fare commit.
NB: Al momento il nostro costruttore, che lavora con la sua configurazione (in YAML) e si chiama costruttore Stapel, è già evoluto in uno strumento piuttosto potente. La sua descrizione dettagliata meriterebbe articoli a parte, mentre i principali dettagli possono essere appresi da .
Comprensione del problema
Ma abbiamo capito, sebbene non immediatamente, che abbiamo commesso un errore: non abbiamo aggiunto la possibilità di creare immagini tramite Dockerfile standard e integrarli nella stessa infrastruttura di gestione complessiva dell'applicazione (cioè, costruire immagini, distribuire e pulirle). Come si poteva realizzare uno strumento di distribuzione su Kubernetes senza implementare il supporto per Dockerfile, il modo standard di descrivere le immagini per la maggior parte dei progetti?..
Invece di dare una risposta a una domanda del genere, proponiamo una soluzione. Cosa fare se hai già un Dockerfile (o una serie di Dockerfile) e vuoi utilizzare werf?
NB: A proposito, perché dovresti voler utilizzare werf? Le principali caratteristiche possono essere riassunte come segue:
- ciclo di vita completo del gestionale dell'applicazione, inclusa la pulizia delle immagini;
- possibilità di gestire la costruzione di più immagini da un'unica configurazione;
- processo migliorato di distribuzione di chart compatibili con Helm.
Per un elenco più completo, puoi fare riferimento a .
Quindi, se prima avremmo suggerito di riscrivere il Dockerfile nella nostra configurazione, ora con piacere diremo: "Lascia che werf costruisca i tuoi Dockerfile!"
Come si utilizza?
La piena realizzazione di questa possibilità è stata introdotta nella release . Il principio generale è semplice: l'utente specifica il percorso fino a un Dockerfile esistente nella configurazione di werf, dopo di che avvia il comando werf build… e tutto qui — werf costruirà l'immagine. Consideriamolo in un esempio astratto.
Dichiariamo il seguente Dockerfile alla radice del progetto:
FROM ubuntu:18.04
RUN echo Building ... E dichiariamo werf.yaml, che utilizza questo Dockerfile:
configVersion: 1
project: dockerfile-example
---
image: ~
dockerfile: ./Dockerfile Tutto qui! Rimane lanciare werf build:

Inoltre, è possibile dichiarare il seguente werf.yaml per costruire immediatamente più immagini da diverse Dockerfile:
configVersion: 1
project: dockerfile-example
---
image: backend
dockerfile: ./dockerfiles/Dockerfile-backend
---
image: frontend
dockerfile: ./dockerfiles/Dockerfile-frontend Infine, è supportato anche il passaggio di parametri aggiuntivi per la costruzione - come --build-arg e --add-host — tramite la configurazione di werf. Una descrizione dettagliata della configurazione dell'immagine Dockerfile è disponibile su .
Come funziona?
Durante il processo di costruzione, funziona la cache standard dei layer locali in Docker. Tuttavia, è importante notare che werf integra anche la configurazione di Dockerfile nella sua infrastruttura. Cosa significa questo?
- Ogni immagine costruita da un Dockerfile consiste in un singolo stage chiamato
dockerfile(per ulteriori dettagli su cosa siano gli stage in werf, puoi leggere ). - Per lo stage
dockerfilewerf calcola una firma che dipende dal contenuto della configurazione del Dockerfile. Quando si modifica la configurazione del Dockerfile, la firma dello stage cambiadockerfilee werf avvia la ricostruzione di quello stage con la nuova configurazione del Dockerfile. Se invece la firma non cambia, werf prende l'immagine dalla cache (per ulteriori informazioni sull'uso delle firme in werf, è stato trattato in ). - Successivamente, le immagini costruite possono essere pubblicate con il comando
werf publish(owerf build-and-publish) e utilizzate per il deployment in Kubernetes. Le immagini pubblicate nel Docker Registry verranno pulite con gli strumenti standard di pulizia di werf, cioè avverrà una pulizia automatica delle immagini più vecchie (superiori a N giorni), delle immagini collegate a branch Git non esistenti e secondo altre politiche.
Per ulteriori dettagli su questi aspetti, puoi consultare la documentazione:
- ;
- ;
- .
Note e precauzioni
1. URL esterni in ADD non sono supportati
Attualmente l'uso di URL esterni nell'istruzione ADDnon è supportato. Werf non avvierà la ricostruzione in caso di modifica della risorsa all'URL specificato. Questa funzionalità è prevista per essere aggiunta a breve.
2. Non è possibile aggiungere .git all'immagine
In generale, aggiungere la directory .git all'immagine è una pratica sconsigliata ecco perché:
- Se
.gitrimane nell'immagine finale, violando i principi : poiché l'immagine finale deve essere legata a un singolo commit, non dovrebbe esserci la possibilità di effettuaregit checkoutcommittazioni arbitrarie. -
.gitaumenta le dimensioni dell'immagine (il repository potrebbe essere grande a causa dell'aggiunta in passato di file pesanti e successiva rimozione). La dimensione della work-tree, legata solo a un determinato commit, non dipenderà dalla storia delle operazioni in Git. In questo caso, l'aggiunta e la successiva rimozione.gitdall'immagine finale non avrà successo: l'immagine acquisterà comunque un layer aggiuntivo - questo è il funzionamento di Docker. - Docker può avviare ricostruzioni non necessarie, anche se si sta costruendo lo stesso commit, ma da diverse work-tree. Ad esempio, GitLab crea directory clonate separate in
/home/gitlab-runner/builds/HASH/[0-N]/yourprojectcon la costruzione parallela attivata. Le ricostruzioni superflue saranno correlate al fatto che la directory.gitdifferisce nelle diverse versioni clonate dello stesso repository, anche se viene costruito lo stesso commit.
L'ultimo punto ha conseguenze anche nell'utilizzo di werf. Werf richiede che la cache di costruzione sia presente durante l'esecuzione di alcuni comandi (ad esempio, werf deploy). Durante l'esecuzione di tali comandi, werf calcola le firme degli stage per le immagini specificate in werf.yaml, e devono essere nella cache di costruzione - altrimenti il comando non può continuare a funzionare. Se la firma degli stage dipende dal contenuto .git, otteniamo una cache instabile rispetto alle modifiche in file non pertinenti, e werf non potrà perdonare tale errore (per ulteriori dettagli, vedere ).
In generale l'aggiunta solo di file necessari tramite l'istruzione ADD aumenta comunque l'efficienza e l'affidabilità della scrittura di Dockerfile, oltre a migliorare la stabilità della cache costruita basata su questa Dockerfile, rispetto a modifiche irrilevanti in Git.
Risultato
Il nostro percorso iniziale nella scrittura del nostro builder per esigenze specifiche è stato difficile, onesto e diretto: invece di utilizzare delle soluzioni temporanee sopra un Dockerfile standard, abbiamo scritto la nostra soluzione con sintassi personalizzata. E questo ha portato i suoi vantaggi: il builder Stapel gestisce eccellentemente il suo compito.
Tuttavia, durante il processo di scrittura del nostro builder personalizzato, abbiamo trascurato il supporto per Dockerfile già esistenti. Ora questo difetto è stato corretto e in futuro prevediamo di sviluppare il supporto per Dockerfile insieme al nostro builder personalizzato Stapel per costruzioni distribuite e per costruzioni utilizzando Kubernetes (cioè costruzioni su runner all'interno di Kubernetes, come avviene con kaniko).
Quindi, se hai a disposizione un paio di Dockerfile... prova !
P.S. Elenco della documentazione sull'argomento
- ;
- ;
- ;
- ;
- ;
- ;
- .
Leggi anche nel nostro blog: «».
Fonte: habr.com
