Alcune persone dicono che le distribuzioni Linux non contano più con i container. Approcci alternativi, come contenitori distroless e scratch, sembrano essere di gran moda. Sembra che stiamo prendendo in considerazione e prendendo decisioni tecnologiche basate più sul senso della moda e sulla gratificazione emotiva immediata che sul pensare agli effetti secondari delle nostre scelte. Dovremmo porre domande del tipo:in che modo queste scelte influiranno sulla manutenzione sei mesi dopo? Quali sono i compromessi ingegneristici? In che modo questo cambio di paradigma influisce sui nostri sistemi di costruzione su larga scala?
È frustrante da guardare. Se dimentichiamo che l'ingegneria è un gioco a somma zero con compromessi misurabili - vantaggi e svantaggi, con costi e benefici di approcci diversi - facciamo un disservizio a noi stessi, facciamo un disservizio ai nostri datori di lavoro e facciamo i nostri colleghi che alla fine manterranno il nostro codificare un disservizio. Infine, diamo un disservizio a tutti i manutentori (salve i manutentori!) non apprezzando il lavoro che svolgono.
Capire il problema
Per comprendere il problema, dobbiamo innanzitutto indagare sul motivo per cui abbiamo iniziato a utilizzare le distribuzioni Linux. Raggrupperei i motivi in due secchi principali:kernel e altri pacchetti. La compilazione dei kernel è in realtà abbastanza semplice. Slackware e Gentoo (ho ancora un debole nel mio cuore) ce lo hanno insegnato.
D'altra parte, l'enorme quantità di software di sviluppo e runtime che deve essere impacchettato per un sistema Linux utilizzabile può essere scoraggiante. Inoltre, l'unico modo per garantire che milioni di permutazioni di pacchetti possano essere installate e lavorare insieme è utilizzare il vecchio paradigma:compilarlo e spedirlo insieme come una cosa (ad esempio, una distribuzione Linux). Quindi, perché le distribuzioni Linux compilano i kernel e tutti i pacchetti insieme? Semplice:assicurarsi che le cose funzionino insieme.
Per prima cosa, parliamo di kernel. Il kernel è speciale. L'avvio di un sistema Linux senza un kernel compilato è un po' una sfida. È il cuore di un sistema operativo Linux ed è la prima cosa su cui facciamo affidamento all'avvio di un sistema. I kernel hanno molte opzioni di configurazione diverse durante la compilazione che possono avere un enorme effetto sul modo in cui hardware e software funzionano su uno. Un problema secondario in questo bucket è che il software di sistema, come compilatori, librerie C e interpreti, deve essere ottimizzato per le opzioni integrate nel kernel. Gentoo ci ha insegnato questo in un modo viscerale, che ha trasformato tutti in un manutentore di distribuzione in miniatura.
In modo imbarazzante (perché ho lavorato con i container negli ultimi cinque anni), devo ammettere che ho compilato i kernel abbastanza di recente. Ho dovuto far funzionare KVM nidificato su RHEL 7 in modo da poter eseguire OpenShift su macchine virtuali OpenStack, in una macchina virtuale KVM sul mio laptop, nonché sul nostro Container Development Kit (CDK). #justsayin Basti dire che all'epoca ho avviato RHEL7 su un kernel 4.X nuovo di zecca. Come ogni buon amministratore di sistema, ero un po' preoccupato di aver perso alcune importanti opzioni di configurazione e patch. E, naturalmente, io avevo perso alcune cose. La modalità sospensione ha smesso di funzionare correttamente, la mia docking station ha smesso di funzionare correttamente e si sono verificati numerosi altri piccoli errori casuali. Ma ha funzionato abbastanza bene per una demo dal vivo di OpenShift su OpenStack, in una singola macchina virtuale KVM sul mio laptop. Dai, è un po' divertente, giusto? Ma sto divagando...
Ora parliamo di tutti gli altri pacchetti. Mentre il kernel e il software di sistema associato possono essere difficili da compilare, il problema molto, molto più grande dal punto di vista del carico di lavoro è la compilazione di migliaia e migliaia di pacchetti per darci un sistema Linux utilizzabile. Ogni pacchetto richiede competenza in materia. Alcuni software richiedono l'esecuzione di soli tre comandi:./configure , crea e fai installazione . Altri richiedono molte competenze in materia che vanno dall'aggiunta di utenti alla configurazione di impostazioni predefinite specifiche in ecc all'esecuzione di script post-installazione e all'aggiunta di file di unità di sistema. L'insieme delle competenze necessarie per le migliaia di diversi software che potresti utilizzare è scoraggiante per ogni singola persona. Ma se vuoi un sistema utilizzabile con la possibilità di provare nuovi software ogni volta che vuoi, devi imparare a compilare e installare il nuovo software prima ancora di poter iniziare a usarlo. Questo è Linux senza una distribuzione Linux. Questo è il problema di ingegneria su cui sei d'accordo quando rinunci a una distribuzione Linux.
Il punto è che devi costruire tutto insieme per assicurarti che funzioni insieme a qualsiasi sano livello di affidabilità, e ci vuole un sacco di conoscenze per costruire una coorte utilizzabile di pacchetti. Questa è più conoscenza di quella che qualsiasi singolo sviluppatore o amministratore di sistema imparerà e conserverà ragionevolmente. Ogni problema che ho descritto si applica all'host del contenitore (kernel e software di sistema) e all'immagine del contenitore (software di sistema e tutti gli altri pacchetti):nota la sovrapposizione; ci sono anche compilatori, librerie C, interpreti e JVM nell'immagine del contenitore.
La soluzione
Lo sai già, ma le distribuzioni Linux sono la soluzione. Smetti di leggere e invia al manutentore del pacchetto più vicino (di nuovo, saluta i manutentori!) una e-card (aspetta, ho appena rivelato la mia età?). Seriamente, però, queste persone fanno un sacco di lavoro, ed è davvero sottovalutato. Kubernetes, Istio, Prometeo e Knative:ti guardo. Anche il tuo momento sta arrivando, quando sarai in modalità manutenzione, abusato e sottovalutato. Scriverò di nuovo lo stesso articolo, probabilmente su Kubernetes, tra circa sette o dieci anni.
Primi principi con le build di container
Ci sono dei compromessi tra costruire da zero e costruire da immagini di base.
Costruzione da immagini di base
La creazione di immagini di base ha il vantaggio che la maggior parte delle operazioni di compilazione non sono altro che l'installazione o l'aggiornamento di un pacchetto. Si basa su un sacco di lavoro svolto dai manutentori dei pacchetti in una distribuzione Linux. Ha anche il vantaggio che un evento di patch tra sei mesi, o anche 10 anni, da ora (con RHEL) è un evento di amministratore di sistema/operazioni (yum update), non un evento di sviluppatore (che richiede la selezione del codice per capire perché alcuni l'argomento della funzione non funziona più).
Facciamo doppio clic su questo un po'. Il codice dell'applicazione si basa su molte librerie che vanno dalle librerie munging JSON ai mappatori relazionali di oggetti. A differenza del kernel Linux e di Glibc, questi tipi di librerie cambiano senza tener conto della rottura della compatibilità delle API. Ciò significa che tra tre anni il tuo evento di patch probabilmente diventerà un evento di modifica del codice, non un evento di aggiornamento yum. Capito, fallo entrare. Sviluppatori, verrete contattati alle 2 del mattino se il team di sicurezza non riesce a trovare un attacco al firewall per bloccare l'exploit.
Costruire da un'immagine di base non è perfetto; ci sono degli svantaggi, come la dimensione di tutte le dipendenze che vengono trascinate dentro. Ciò renderà quasi sempre le immagini del tuo contenitore più grandi rispetto alla creazione da zero. Un altro svantaggio è che non avrai sempre accesso al codice upstream più recente. Questo può essere frustrante per gli sviluppatori, specialmente quando vuoi solo portare qualcosa fuori dalla porta, ma non così frustrante come essere impaginato per guardare una libreria a cui non pensavi da tre anni che i manutentori a monte hanno cambiato tutto il tempo .
Se sei uno sviluppatore web e alzi gli occhi al cielo, ho una parola per te:DevOps. Ciò significa che stai portando un cercapersone, amico mio.
Costruire da zero
Le build Scratch hanno il vantaggio di essere davvero piccole. Quando non ti affidi a una distribuzione Linux nel container, hai molto controllo, il che significa che puoi personalizzare tutto in base alle tue esigenze. Questo è un modello best-of-breed ed è valido in alcuni casi d'uso. Un altro vantaggio è che hai accesso ai pacchetti più recenti. Non devi aspettare che una distribuzione Linux aggiorni nulla. Hai il controllo, quindi scegli quando dedicare il lavoro di ingegneria per incorporare il nuovo software.
Ricorda, c'è un costo per controllare tutto. Spesso, l'aggiornamento a nuove librerie con nuove funzionalità trascina modifiche API indesiderate, il che significa correggere le incompatibilità nel codice (in altre parole, radere gli yak). Radersi alle 2 del mattino quando l'applicazione non funziona non è divertente. Fortunatamente, con i container, puoi tornare indietro e radere gli yak il giorno lavorativo successivo, ma ti consumerà comunque tempo per fornire nuovo valore all'azienda e nuove funzionalità alle tue applicazioni. Benvenuto nella vita di un amministratore di sistema.
OK, detto questo, ci sono volte in cui costruire da zero ha senso. Ammetterò completamente che i programmi Golang e C compilati staticamente sono due candidati decenti per build scratch/distroless. Con questi tipi di programmi, ogni build di container è un evento di compilazione. Devi ancora preoccuparti della rottura dell'API tra tre anni, ma se sei un negozio Golang, dovresti avere le competenze per aggiustare le cose nel tempo.
Conclusione
Fondamentalmente, le distribuzioni Linux fanno un sacco di lavoro per farti risparmiare tempo, su un normale sistema Linux o con container. La conoscenza che i manutentori hanno è enorme e sfruttata così tanto senza essere davvero apprezzata. L'adozione dei container ha aggravato ulteriormente il problema perché è ancora più astratto.
Con gli host container, una distribuzione Linux ti offre l'accesso a un ampio ecosistema hardware, che va dai minuscoli sistemi ARM, alle gigantesche scatole da 128 CPU x86, alle VM cloud-provider. Offrono motori di container funzionanti e tempi di autonomia dei container pronti all'uso, quindi puoi semplicemente accendere i tuoi container e lasciare che qualcun altro si preoccupi di far funzionare le cose.
Per le immagini del contenitore, le distribuzioni Linux ti offrono un facile accesso a una tonnellata di software per i tuoi progetti. Anche quando crei da zero, probabilmente guarderai come un manutentore di pacchetti ha costruito e spedito le cose (un buon artista è un buon ladro), quindi non sottovalutare questo lavoro.
Quindi, grazie a tutti i manutentori di Fedora, RHEL (Frantisek, sei il mio eroe), Debian, Gentoo e ogni altra distribuzione Linux. Apprezzo il lavoro che fai, anche se sono un "ragazzo dei container".