Ora puoi creare immagini Docker in werf usando un normale Dockerfile

Meglio tardi che mai. O come abbiamo quasi commesso un grave errore non avendo il supporto per i normali Dockerfile per creare immagini di applicazioni.

Ora puoi creare immagini Docker in werf usando un normale Dockerfile

Ne parleremo werf — Utilità GitOps che si integra con qualsiasi sistema CI/CD e fornisce la gestione dell'intero ciclo di vita dell'applicazione, consentendo:

  • raccogliere e pubblicare immagini,
  • distribuire applicazioni in Kubernetes,
  • eliminare le immagini inutilizzate utilizzando criteri speciali.


La filosofia del progetto è quella di raccogliere strumenti di basso livello in un unico sistema unificato che offra agli ingegneri DevOps il controllo sulle applicazioni. Se possibile, dovrebbero essere utilizzate le utilità esistenti (come Helm e Docker). Se non esiste una soluzione al problema, possiamo creare e supportare tutto il necessario a tal fine.

Sfondo: il tuo raccoglitore di immagini

Questo è quello che è successo con il raccoglitore di immagini in werf: il solito Dockerfile non ci bastava. Se si dà una rapida occhiata alla storia del progetto, questo problema appariva già nelle prime versioni di werf (allora ancora noto come dapp).

Durante la creazione di uno strumento per creare applicazioni in immagini Docker, ci siamo subito resi conto che Dockerfile non era adatto a noi per alcune attività molto specifiche:

  1. La necessità di costruire tipiche applicazioni web di piccole dimensioni secondo il seguente schema standard:
    • installare dipendenze delle applicazioni a livello di sistema,
    • installare un pacchetto di librerie di dipendenze dell'applicazione,
    • raccogliere beni,
    • e, soprattutto, aggiorna il codice nell'immagine in modo rapido ed efficiente.
  2. Quando vengono apportate modifiche ai file di progetto, il costruttore deve creare rapidamente un nuovo livello applicando una patch ai file modificati.
  3. Se alcuni file sono cambiati, è necessario ricostruire la fase dipendente corrispondente.

Oggi il nostro collezionista ha tante altre possibilità, ma questi erano i desideri e le spinte iniziali.

In generale, senza pensarci due volte, ci siamo armati del linguaggio di programmazione che abbiamo utilizzato (vedi sotto) e mettersi in viaggio per implementarlo propria ADSL! In conformità con gli obiettivi, si intendeva descrivere il processo di assemblaggio in fasi e determinare le dipendenze di queste fasi dai file. E lo ha completato proprio collezionista, che ha trasformato la DSL nell'obiettivo finale: un'immagine assemblata. All'inizio l'DSL era in Ruby, ma come passaggio a Golang — la configurazione del nostro raccoglitore ha iniziato a essere descritta in un file YAML.

Ora puoi creare immagini Docker in werf usando un normale Dockerfile
Vecchia configurazione per dapp in Ruby

Ora puoi creare immagini Docker in werf usando un normale Dockerfile
Configurazione corrente per werf su YAML

Anche il meccanismo del raccoglitore è cambiato nel tempo. Inizialmente, abbiamo semplicemente generato al volo un Dockerfile temporaneo dalla nostra configurazione, quindi abbiamo iniziato a eseguire istruzioni di assemblaggio in contenitori temporanei ed eseguire il commit.

NB: Al momento, il nostro raccoglitore, che funziona con la propria configurazione (in YAML) e si chiama raccoglitore Stapel, è già diventato uno strumento abbastanza potente. La sua descrizione dettagliata merita articoli separati e i dettagli di base possono essere trovati in documentazione.

Consapevolezza del problema

Ma ci siamo resi conto, e non subito, di aver commesso un errore: non abbiamo aggiunto l'abilità creare immagini tramite Dockerfile standard e integrarli nella stessa infrastruttura di gestione delle applicazioni end-to-end (ovvero raccogliere immagini, distribuirle e pulirle). Come potrebbe essere possibile creare uno strumento per la distribuzione in Kubernetes e non implementare il supporto Dockerfile, ad es. modo standard per descrivere le immagini per la maggior parte dei progetti?...

Invece di rispondere a questa domanda, offriamo una soluzione. Cosa succede se hai già un Dockerfile (o un set di Dockerfile) e desideri utilizzare werf?

NB: A proposito, perché dovresti usare werf? Le caratteristiche principali si riducono a quanto segue:

  • ciclo completo di gestione dell'applicazione inclusa la pulizia delle immagini;
  • la possibilità di gestire l'assemblaggio di più immagini contemporaneamente da un'unica configurazione;
  • Processo di distribuzione migliorato per i grafici compatibili con Helm.

Un elenco più completo di essi può essere trovato su pagina del progetto.

Quindi, se prima ci saremmo offerti di riscrivere il Dockerfile nella nostra configurazione, ora diremo con gioia: "Lascia che costruiamo i tuoi Dockerfile!"

Come usare?

L'implementazione completa di questa funzionalità è apparsa nel rilascio werf v1.0.3-beta.1. Il principio generale è semplice: l'utente specifica il percorso di un Dockerfile esistente nella configurazione werf, quindi esegue il comando werf build... e questo è tutto: werf assemblerà l'immagine. Consideriamo un esempio astratto.

Annunciamo il prossimo Dockerfile nella radice del progetto:

FROM ubuntu:18.04
RUN echo Building ...

E lo annunceremo werf.yamlche usa questo Dockerfile:

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

Tutto! Sinistra corsa werf build:

Ora puoi creare immagini Docker in werf usando un normale Dockerfile

Inoltre, puoi dichiarare quanto segue werf.yaml per creare più immagini da diversi Dockerfile contemporaneamente:

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

Infine, supporta anche il passaggio di parametri di build aggiuntivi, come --build-arg и --add-host - tramite configurazione werf. Una descrizione completa della configurazione dell'immagine Dockerfile è disponibile all'indirizzo pagina della documentazione.

Come funziona?

Durante il processo di compilazione, la cache standard dei livelli locali in Docker funziona. Tuttavia, ciò che è importante è anche quello integra la configurazione Dockerfile nella sua infrastruttura. Cosa significa questo?

  1. Ogni immagine creata da un Dockerfile è composta da una fase chiamata dockerfile (puoi leggere di più su quali fasi sono presenti in werf qui).
  2. Per il palco dockerfile werf calcola una firma che dipende dal contenuto della configurazione Dockerfile. Quando la configurazione del Dockerfile cambia, la firma della fase cambia dockerfile e werf avvia una ricostruzione di questa fase con una nuova configurazione Dockerfile. Se la firma non cambia, werf prende l'immagine dalla cache (maggiori dettagli sull'uso delle firme in werf sono stati descritti in questo rapporto).
  3. Successivamente, le immagini raccolte possono essere pubblicate con il comando werf publish (o werf build-and-publish) e utilizzarlo per la distribuzione su Kubernetes. Le immagini pubblicate nel registro Docker verranno pulite utilizzando strumenti di pulizia werf standard, ad es. Le vecchie immagini (più vecchie di N giorni), le immagini associate a rami Git inesistenti e altre policy verranno automaticamente pulite.

Maggiori dettagli sui punti qui descritti possono essere trovati nella documentazione:

Note e precauzioni

1. L'URL esterno non è supportato in ADD

Attualmente non è supportato l'utilizzo di un URL esterno in una direttiva ADD. Werf non avvierà una ricostruzione quando la risorsa all'URL specificato cambia. Prevediamo di aggiungere presto questa funzionalità.

2. Non puoi aggiungere .git all'immagine

In generale, aggiungendo una directory .git nell'immagine: una cattiva pratica crudele ed ecco perché:

  1. se .git rimane nell'immagine finale, questo viola i principi 12 fattori app: Poiché l'immagine finale deve essere collegata a un singolo commit, non dovrebbe essere possibile farlo git checkout impegno arbitrario.
  2. .git aumenta la dimensione dell'immagine (il repository può essere grande a causa del fatto che una volta vi venivano aggiunti e poi cancellati file di grandi dimensioni). La dimensione di un albero di lavoro associato solo a un commit specifico non dipenderà dalla cronologia delle operazioni in Git. In questo caso, l'aggiunta e la successiva rimozione .git dall'immagine finale non funzionerà: l'immagine acquisirà comunque un livello aggiuntivo: ecco come funziona Docker.
  3. Docker può avviare una ricostruzione non necessaria, anche se viene creato lo stesso commit, ma da alberi di lavoro diversi. Ad esempio, GitLab crea directory clonate separate in /home/gitlab-runner/builds/HASH/[0-N]/yourproject quando l'assemblaggio parallelo è abilitato. Il riassemblaggio aggiuntivo sarà dovuto al fatto che la directory .git è diverso nelle diverse versioni clonate dello stesso repository, anche se viene creato lo stesso commit.

L'ultimo punto ha conseguenze anche quando si utilizza werf. Werf richiede che la cache creata sia presente durante l'esecuzione di alcuni comandi (ad es. werf deploy). Quando questi comandi vengono eseguiti, werf calcola le segnature dello stage per le immagini specificate in werf.yamle devono trovarsi nell'assembly cache, altrimenti il ​​comando non sarà in grado di continuare a funzionare. Se la firma della scena dipende dal contenuto .git, quindi otteniamo una cache che è instabile alle modifiche in file irrilevanti e werf non sarà in grado di perdonare tale svista (per maggiori dettagli, vedere documentazione).

In generale, aggiungendo solo alcuni file necessari attraverso le istruzioni ADD in ogni caso aumenta l'efficacia e l'attendibilità dello scritto Dockerfilee migliora anche la stabilità della cache raccolta per questo Dockerfile, a cambiamenti irrilevanti in Git.

risultato

Il nostro percorso iniziale per scrivere il nostro builder per esigenze specifiche è stato duro, onesto e diretto: invece di utilizzare le stampelle sul Dockerfile standard, abbiamo scritto la nostra soluzione con una sintassi personalizzata. E questo aveva i suoi vantaggi: il raccoglitore Stapel svolge perfettamente il suo compito.

Tuttavia, durante il processo di scrittura del nostro builder, abbiamo perso di vista il supporto per i Dockerfile esistenti. Questo difetto è stato ora corretto e in futuro prevediamo di sviluppare il supporto Dockerfile insieme al nostro generatore Stapel personalizzato per l'assemblaggio distribuito e per l'assemblaggio utilizzando Kubernetes (ovvero l'assemblaggio su corridori all'interno di Kubernetes, come avviene in Kaniko).

Quindi, se all'improvviso hai un paio di Dockerfile in giro... provalo werf!

PS Elenco della documentazione sull'argomento

Leggi anche nel nostro blog: “werf - il nostro strumento per CI/CD in Kubernetes (panoramica e rapporto video)'.

Fonte: habr.com

Aggiungi un commento