Evoluzione dei mezzi di distribuzione, o riflessioni su Docker, deb, jar e altro

Evoluzione dei mezzi di distribuzione, o riflessioni su Docker, deb, jar e altro

Un momento ho deciso di scrivere un articolo sulla distribuzione tramite container Docker e pacchetti deb, ma quando ho iniziato, mi sono ritrovato a riflettere su tempi lontani dei primi computer personali e persino delle calcolatrici. In sintesi, invece di aride comparazioni tra Docker e deb, ecco alcune considerazioni sull'evoluzione che vi presento per il vostro giudizio.

Qualsiasi prodotto, qualunque esso sia, deve in qualche modo arrivare ai server produttivi, deve essere configurato e avviato. Di questo parlerà questo articolo.

Rifletterò nel contesto storico, «quello che vedo — di questo canto», ciò che ho visto quando ho iniziato a scrivere codice e ciò che osservo ora, cosa utilizziamo attualmente e perché. L'articolo non ambisce a essere una ricerca completa, alcuni aspetti sono trascurati, è il mio punto di vista personale su ciò che c'era e ciò che c'è adesso.

Quindi, nei bei tempi di una volta… il primo modo di distribuzione che ho conosciuto erano le cassette dei registratori. Avevo un computer BK-0010.01…

L'era delle calcolatrici

No, c'era un momento ancora più antico, c'era ancora la calcolatrice MK-61 e MK-52.

Evoluzione dei mezzi di distribuzione, o riflessioni su Docker, deb, jar e altro Quindi, quando avevo MK-61, il metodo per trasferire il programma era un semplice foglio di carta a quadretti, su cui era scritto il programma che, se necessario, veniva inserito manualmente nel calcolatore. Vuoi giocare (sì, anche su questo calcolatore preistorico c'erano giochi) — ti siedi e digiti il programma nel calcolatore. Naturalmente, quando il calcolatore è spento, il programma scompare. Oltre ai codici scritti a mano sul foglio, i programmi venivano pubblicati nelle riviste «Radio» e «Tecnica della gioventù», e stampati anche nei libri dell'epoca.

La modifica successiva è stata il calcolatore MK-52, che aveva già qualche forma di memoria non volatile. Ora non era più necessario inserire manualmente il gioco o il programma, ma, facendo alcuni passaggi magici con i tasti, si caricava automaticamente.

Il volume del programma più grande nel calcolatore era di 105 passi, mentre la dimensione della memoria permanente nel MK-52 era di 512 passi.

A proposito, se ci sono fan di questi calcolatori che leggono questo articolo — mentre scrivevo l'articolo ho trovato un emulatore di calcolatore per Android e programmi per esso. Avanti, verso il passato!

Piccola digressione su MK-52 (da Wikipedia)

Il MK-52 ha volato nello spazio a bordo della navetta 'Soyuz TM-7'. Era progettato per calcolare la traiettoria di atterraggio nel caso in cui il computer di bordo si guastasse.

Il MK-52, con l'unità di espansione della memoria 'Elettronica-Astro', è stato fornito a partire dal 1988 alle navi della Marina Militare come parte del kit di calcolo del navigatore.

I primi computer personali

Evoluzione dei mezzi di distribuzione, o riflessioni su Docker, deb, jar e altro Torniamo ai tempi BK-0010. È evidente che la memoria era aumentata, e inserire il codice su carta non era più un'opzione (anche se per un po' ho fatto proprio così, poiché non c'era altro supporto disponibile). Il principale mezzo di archiviazione e distribuzione del software divenne le audiocassette per registratori.





Evoluzione dei mezzi di distribuzione, o riflessioni su Docker, deb, jar e altroLo storage su cassetta era solitamente rappresentato da uno o due file binari, mentre il resto era contenuto all'interno. L'affidabilità era molto bassa, e si dovevano mantenere 2-3 copie del programma. Anche i tempi di caricamento non erano soddisfacenti, e gli appassionati sperimentavano con diverse codifiche di frequenza per affrontare questi difetti. All'epoca non mi dedicavo ancora allo sviluppo software professionale (se non per programmi semplici in Basic), quindi non posso purtroppo fornire dettagli su come tutto fosse strutturato internamente. Il fatto stesso che ci fosse solo la RAM nel computer determinava per la maggior parte la semplicità dello schema di archiviazione dei dati.

L'emergere di supporti di informazioni affidabili e di grande capacità

In seguito, arrivano i dischetti, semplificando il processo di copia e aumentando l'affidabilità.
Ma la situazione cambia radicalmente solo con l'arrivo di archiviazioni locali sufficientemente grandi sotto forma di HDD.

Cambia radicalmente il tipo di fornitura: nascono programmi di installazione che gestiscono il processo di configurazione del sistema, oltre alla pulizia dopo la disinstallazione, poiché i programmi non vengono semplicemente letti in memoria, ma copiati in uno storage locale, dal quale è necessario imparare a rimuovere ciò che non serve.

Parallelamente aumenta la complessità del software fornito.
Il numero di file nella fornitura cresce da uno a centinaia e migliaia, sorgono conflitti di versioni delle librerie e altre problematiche quando diversi programmi utilizzano gli stessi dati.

Evoluzione dei mezzi di distribuzione, o riflessioni su Docker, deb, jar e altro All'epoca non conoscevo ancora l'esistenza di Linux, vivevo nel mondo di MS DOS e, successivamente, Windows, e programmavo in Borland Pascal e Delphi, a volte dando un'occhiata al C++. Per la fornitura dei prodotti all'epoca molti utilizzavano InstallShield ru.wikipedia.org/wiki/InstallShield, che risolveva con successo tutte le sfide poste dal deployment e dalla configurazione del software.




L'era di Internet

La complessità dei sistemi software sta aumentando, passando da monoliti e applicazioni desktop a sistemi distribuiti, client leggeri e microservizi. Ora non è più necessario configurare solo un programma, ma un insieme di essi, in modo che possano funzionare insieme.

La concezione è cambiata completamente, è arrivato Internet e l'era dei servizi cloud ha avuto inizio. Era ancora nelle fasi iniziali, sotto forma di siti web, e nessuno osava sognare servizi particolari. Ma questo è stato un momento cruciale sia per lo sviluppo che per la fornitura delle applicazioni.

Ho notato che in quel periodo c'è stata una cambiamento generazionale tra i programmatori (o era solo nella mia cerchia), e sembrava che tutti i vecchi metodi di distribuzione fossero stati dimenticati all'improvviso, ricominciando da zero: tutta la distribuzione è stata effettuata tramite script fai-da-te e questo è stato definito con orgoglio "Continuous delivery". Di fatto, è iniziato un periodo di caos, durante il quale il passato è stato dimenticato e non utilizzato, mentre il nuovo era semplicemente assente.

Ricordo i tempi in cui nella società in cui lavoravo (non farò nomi), invece di creare pacchetti attraverso ant (maven all'epoca non era ancora popolare o non esisteva affatto), la gente semplicemente compilava jar nell'IDE e li committava serenamente in SVN. Di conseguenza, il deployment consisteva nel prelevare il file da SVN e copiarlo via SSH sulla macchina necessaria. Così semplice e rudimentale.

In quel periodo, la fornitura di semplici siti web in PHP avveniva in modo estremamente primitivo, semplicemente copiando il file corretto tramite FTP sulla macchina di destinazione. A volte nemmeno questo – il codice veniva modificato dal vivo sul server di produzione, ed era un vero status symbol avere dei backup da qualche parte.


Pacchetti RPM e DEB

Evoluzione dei mezzi di distribuzione, o riflessioni su Docker, deb, jar e altroD'altra parte, con lo sviluppo di Internet, i sistemi Unix-like hanno cominciato a guadagnare sempre più popolarità; in particolare, in quel periodo ho scoperto RedHat Linux 6, intorno all'anno 2000. Naturalmente, anche lì c'erano strumenti specifici per la fornitura del software; secondo Wikipedia, RPM come principale gestore di pacchetti è apparso nel 1995 con la versione 2.0 di RedHat Linux. Da allora, fino ad oggi, il sistema viene fornito sotto forma di pacchetti RPM ed esiste e si sviluppa con successo.

Le distribuzioni della famiglia Debian hanno seguito un percorso simile e hanno implementato la fornitura sotto forma di pacchetti deb, che rimane invariato fino ai giorni nostri.

I gestori di pacchetti consentono di fornire i prodotti software, configurarli durante l'installazione, gestire le dipendenze tra diversi pacchetti, eseguire la rimozione dei prodotti e liberare spazio durante la disinstallazione. In sostanza, questo è tutto ciò di cui si ha bisogno, ecco perché sono rimasti in uso per diversi decenni praticamente senza modifiche.

L'approccio cloud ha aggiunto ai gestori di pacchetti la possibilità di installare non solo da supporti fisici, ma anche da repository cloud, ma sostanzialmente poco è cambiato.

Va notato che attualmente ci sono alcuni tentativi di allontanarsi dai pacchetti deb e di passare ai pacchetti snap, ma di questo parleremo più avanti.

Ecco quindi che questa nuova generazione di sviluppatori cloud, che non conosceva né DEB né RPM, cresceva lentamente, accumulando esperienza, i prodotti diventavano più complessi e c'era bisogno di metodi di fornitura più ragionevoli rispetto a FTP, script bash e simili improvvisazioni da studenti.
E qui entra in gioco Docker, una sorta di miscela di virtualizzazione, gestione delle risorse e metodo di distribuzione. È qualcosa di trendy e giovanile, ma è davvero necessario per tutto? È una panacea?

Dalla mia esperienza, molto spesso Docker non è proposto come una scelta ragionevole, ma semplicemente perché se ne parla nella comunità, e chi lo propone ne sa solo parlare. Dall'altra parte, dei vecchi e buoni sistemi di packaging si parla ben poco — esistono e fanno il loro lavoro in silenzio e senza farsi notare. In questa situazione, non sembra esserci molta scelta — la decisione è piuttosto ovvia: Docker.

Cercherò di condividere l'esperienza di come abbiamo implementato Docker e quali risultati abbiamo ottenuto.


Script personalizzati

Inizialmente avevamo script bash che distribuivano archive jar sulle macchine necessarie. Questo processo era gestito da Jenkins. Funzionava con successo, poiché l'archive jar stesso è già un pacchetto che contiene classi, risorse e persino configurazioni. Se si uniscono il massimo di tutto — decomporlo con uno script non è la cosa più difficile da fare.

Ma gli script presentano alcuni svantaggi:

  • Gli script sono generalmente scritti in fretta e risultano così primitivi da contenere solo lo scenario più favorevole. Questo è favorito dal fatto che lo sviluppatore è interessato a una consegna rapida, mentre uno script adeguato richiede un investimento considerevole di risorse.
  • Di conseguenza, gli script non contengono procedure di disinstallazione.
  • Non c'è una procedura di aggiornamento definita.
  • Con l'arrivo di un nuovo prodotto, è necessario scrivere un nuovo script.
  • Non c'è supporto per le dipendenze.

Certo, è possibile scrivere uno script complesso, ma, come ho detto sopra, questo richiede tempo per lo sviluppo, e non è poco; e come sappiamo, il tempo è sempre limitato.

Tutto ciò limita chiaramente l'ambito di applicazione di questo metodo di distribuzione a sistemi molto semplici. È giunto il momento di cambiare.


Docker

Evoluzione dei mezzi di distribuzione, o riflessioni su Docker, deb, jar e altroA un certo punto, abbiamo iniziato a ricevere freschi sviluppatori intermedi, pieni di idee e sognanti Docker. Beh, via! Ci proviamo! Ci sono state due tentativi. Entrambi falliti — diciamo che a causa di grandi ambizioni, ma di esperienza reale insufficiente. Era necessario forzare e completare a qualsiasi costo? Probabilmente no — il team deve evolversi gradualmente al livello necessario prima di poter utilizzare gli strumenti adeguati. Inoltre, utilizzando immagini Docker pronte all'uso, ci siamo spesso imbattuti in problemi con la rete (che, probabilmente, era anche legata all'instabilità di Docker stesso) o era difficile espandere i contenitori di altri.

Quali inconvenienti abbiamo riscontrato?

  • Problemi di rete in modalità bridge
  • Difficoltà a visualizzare i log nel contenitore (se non sono stati estratti separatamente nel filesystem della macchina host)
  • Ogni tanto strani blocchi di ElasticSearch all'interno del contenitore, non siamo riusciti a identificare la causa, contenitore ufficiale
  • Scomodo utilizzare la shell all'interno del contenitore — tutto è molto ridotto, mancano strumenti familiari
  • Grande dimensione dei contenitori raccolti — costoso da mantenere
  • A causa delle grandi dimensioni dei container, è difficile mantenere più versioni.
  • Assemblaggio più lungo, a differenza di altri metodi (script o pacchetti deb).

Dall'altra parte, cosa rende meno conveniente il deployment di un servizio Spring in formato jar tramite lo stesso deb? È davvero necessaria l'isolamento delle risorse? Vale la pena rinunciare a strumenti utili del sistema operativo mettendo il servizio in un container molto ridotto?

Come dimostrato nella pratica, nella realtà non è necessario; un pacchetto deb è sufficiente nel 90% dei casi.

Quando allora il vecchio buon deb non funziona e quando abbiamo realmente bisogno di Docker?

Per noi, si è trattato di implementare servizi in Python. Molte librerie necessarie per l'apprendimento automatico mancavano nella fornitura standard del sistema operativo (e quelle che c'erano non erano le versioni corrette), hack con le impostazioni, e la necessità di diverse versioni per servizi differenti che risiedono sullo stesso sistema host hanno fatto sì che l'unico modo ragionevole per fornire questa miscela complessa risultasse essere Docker. L'impegno necessario per assemblare un contenitore Docker si è rivelato inferiore rispetto all'idea di impacchettare tutto questo in singoli pacchetti deb con le relative dipendenze, e in effetti, nessuno in sano spirito si sarebbe preso la briga di farlo.

Il secondo aspetto dove si prevede di utilizzare Docker è per l'implementazione dei servizi secondo lo schema blue-green deploy. Ma qui si desidera ottenere un aumento graduale della complessità: prima vengono creati i pacchetti deb, e poi da questi si assembla il contenitore Docker.


Pacchetti Snap

Evoluzione dei mezzi di distribuzione, o riflessioni su Docker, deb, jar e altro Torniamo ai pacchetti snap. Sono stati introdotti ufficialmente per la prima volta in Ubuntu 16.04. A differenza dei classici pacchetti deb e rpm, i pacchetti snap includono tutte le dipendenze. Da un lato, questo consente di evitare conflitti tra le librerie, dall'altro lato, comporta dimensioni più considerevoli per il pacchetto risultante. Inoltre, può influenzare la sicurezza del sistema: nel caso in cui venga fornito uno snap, il developer deve monitorare tutte le modifiche delle librerie incluse. Insomma, non è tutto così semplice e la felicità universale nel loro utilizzo non si materializza. Tuttavia, rimangono un'alternativa ragionevole, soprattutto se Docker viene utilizzato solo come strumento di imballaggio e non di virtualizzazione.



In conclusione, al momento utilizziamo una combinazione ragionevole di pacchetti deb e container Docker, che, in alcuni casi, potremmo sostituire con pacchetti snap.

Solo gli utenti registrati possono partecipare al sondaggio. Accedi, per favore.

E cosa utilizzate voi per la distribuzione?

  • Script personalizzati

  • Copiamo manualmente via FTP

  • Pacchetti deb

  • Pacchetti rpm

  • Pacchetti snap

  • Immagini Docker

  • Immagini delle macchine virtuali

  • Cloniamo interamente l'HDD

  • puppet

  • ansible

  • Altro

Hanno votato 109 utenti. 32 utenti si sono astenuti.

Fonte: habr.com

Acquista un hosting affidabile per siti con protezione DDoS, server VPS VDS 🔥 Acquista un hosting affidabile per siti con protezione DDoS, server VPS VDS | ProHoster