Un assaggio di Docker

/images/docker.thumbnail.png

Preambolo

Ho fatto i primi passi nella virtualizzazione nel lontano 1998. Mi affascinava l'idea di inscatolare un intero computer all'interno del mio PC e non dover più essere schiavo di installare, cancellare, reinstallare, avere due sistemi operativi diversi per scopi diversi contemporaneamente nella stessa macchina e avere eventuali problemi di boot all'aggiornamento di uno ei due.

Sperimentai dunque VMWare e capii subito che la virtualizzazione sarebbe stata il futuro. Nel corso degli anni la penalizzazione sulle prestazioni si è via via assottigliata e nella mia tesi di laurea, nel 2003, mi occupai proprio degli internal di vari virtualizzatori tra cui il neonato i QEMU. Il bello di qemu era proprio la possibilità di emulare piattaforme hardware diverse per lo sviluppo o l'emulazione, e in maniera sufficientemente (per l'epoca) rapida grazie alla traslazione dinamica delle chiamate di sistema, un metodo per l'epoca rivoluzionario. C'erano anche i primordi di Xen, che dava risultati assolutamente interessanti ma richiedeva modifiche al sistema operativo guest. Venne poi fuori un modulo kernel per qemu (divenuto poi KVM, la base dei principali virtualizzatori moderni) che gestiva la virtualizzazione passando direttamente le chiamate all'hardware sottostante, abbattendo l'overhead prestazionale a livelli bassissimi e consentendo di avere un buon numero di VM su un server fisico.

Da allora mi occupo di virtualizzazione ma ho sempre cercato anche altre possibilità proprio perché nell'informatica bisogna sempre avere fame di novità.

Ho lavorato (con estremo successo, ne racconterò prima o poi l'esperienza) già dal 2005 con OpenVZ, che mi ha permesso (per anni) di far girare il mio server principale sia sul VIA EPIA che su un server esterno a cui migravo il tutto in base alle necessità. I container, insomma, mi sono sempre piaciuti.

Nel 2010, ho iniziato a implementare soluzioni basate su FreeBSD proprio per avere le sue jail, ovvero degli ambienti non emulati ma separati dal sistema operativo principale. In pratica, stesso kernel ma userland completamente diversa. Nessun overhead di virtualizzazione ma semplice separazione degli ambienti. Non era un concetto nuovo, infatti Solaris utilizza i container (o zone) già dal 2004, ma di sicuro un concetto vincente: se il mio scopo non è avere sistemi operativi diversi ma solo tenere separati i servizi, perché dover lanciare n macchine virtuali con n sistemi operativi uguali in esecuzione?

Poco dopo è arrivato anche GNU/Linux, e già nel 2011 sperimentavo con lxc, pur sapendo che non c'erano ancora i requisiti di sicurezza necessari, ma avevo già degli strumenti per tenere separati vari ambienti basati su GNU/Linux.

Proprio su lxc si basa Docker, una soluzione di inscatolamento di ambienti, che ne consente la creazione e l'utilizzo su qualsiasi piattaforma compatibile e crea un ambiente standard in un solo comando.

I miei primi passi con Docker

...sono stati disastrosi, come credo quelli di tutti quelli che hanno iniziato ai suoi albori. Docker è un progetto relativamente recente e, come tale, in forte sviluppo. Uno dei problemi, infatti, è che lo sviluppo è rapido e, a volte, distruttivo. Basta un aggiornamento e cambia qualcosa nella riga di comando, nel setup della rete, nella funzionalità e ci si può trovare con un sistema malfunzionante. Il primo passo che feci non fu diverso. Installai Docker, lo misi in funzione per alcuni test, aggiornai alla nuova versione stabile e tutti i miei contenitori smisero di funzionare per variazioni di struttura. Decisi di buttare via tutto e aspettare tempi migliori.

D'altronde si sa come funziona: o una tecnologia diventa sufficientemente matura in poco tempo, oppure muore. Nel primo caso, l'attesa non è così lunga. Nel secondo, non conviene perdere tempo con qualcosa che non avrà futuro.

Alcuni mesi fa ho deciso di rimettere in piedi il discorso. Di solito imparo qualcosa per necessità, poi lo espando e lo riutilizzo. A volte la necessità è puro vezzo privato, magari per fare qualcosa di non strettamente lavorativo ma si sa, l'animo nerd non lo si tiene a freno e, anzi, guai se ciò avvenisse!

Docker su strada

Rimettere in strada Docker non è stato difficile. A oggi, infatti, le cose sono state rese più facili (sia per architetture tradizionali che per le ARM come Raspberry PI o similari) da un rapido & semplice comando:

curl -sSL get.docker.com | sh

ovviamente a patto di avere curl installato, cosa non del tutto scontata in tutte le installazioni (Debian base non ce l'ha).

In un lampo, sono stato pronto col mio eseguibile pronto da usare e libero di fare dei test.

Ho iniziato. Immediatamente mi sono trovato a mio agio sia con la sintassi (anche se, a mio avviso, va ancora un po' uniformata tra un container normale e uno Swarm sia col funzionamento generale. Il vantaggio dell'inscatolamento delle risorse è indubbiamente evidente. Ogni cosa resta nel suo mondo, con le sue dipendenze, senza andare a intaccare o modificare alcunché sul resto del sistema.

Ho subito iniziato ad aver bisogno di alcune funzionalità non ancora presenti nei container presenti nell'hub ufficiale (specialmente per quanto riguarda le architetture ARM in mio possesso) per cui ho esplorato la creazione di una immagine personalizzata. Anche qui semplicità assoluta, un Dockerfile con tutte le istruzioni necessarie e una bella procedura. In un lampo ho avuto tutto il necessario.

Gli Swarm

Uno Swarm è un gruppo di sistemi su cui Docker è installato che si uniscono in un cluster. In uno swarm, ogni worker può far partire uno dei container e metterlo a disposizione. In uno swarm, un container può essere definito come servizio singolo (farne girare sempre uno su uno dei nodi), oppure come servizio multiplo (far girare n copie, che verranno distribuite nei nodi dello swarm) e milioni di sfumature di configurazione.

In uno Swarm, per scelta progettuale, una porta esposta da un container sarà raggiungibile connettendosi all'IP di uno qualunque dei nodi. Se, ad esempio, abbiamo due nodi (nodo1 e nodo2) e un container che espone la porta 80 (un server http), una volta configurato il servizio come parte dello Swarm sarà possibile connettersi al container stesso sia sull'IP del nodo1 che su quello del nodo2.

Conclusioni

Questo articolo voleva essere solo una rapida carrellata su quella che è stata la mia recente esperienza con Docker e sul perché ho deciso non solo di utilizzarlo ma di approfondirne sempre di più le potenzialità.

Seguiranno altri articoli in merito, quando il tempo me lo consentirà, che spiegheranno come ho risolto alcune delle problematiche principali che possono occorrere nell'utilizzo quotidiano e in produzione di un sistema del genere (es: storage condiviso tra nodi, ecc.)

Suggerisco a tutti di cominciare a prendere in considerazione questo tipo di tecnologia, sia per ragioni di sicurezza che di scalabilità e praticità. Volenti o nolenti, sarà il futuro. O il presente.

Mosh, un'alternativa a SSH

SSH, delizia pura

SSH è sempre stata una pura delizia per i sistemisti. Facile da configurare, di scarso impatto sulle prestazioni, estremamente versatile, sufficientemente sicuro, è la chiave di volta per l'accesso e la gestione di server Unix-Like.

Mettendosi in condizioni di non farsi bucare facilmente (password banali, meglio una bella autenticazione a chiave pubblica), la mia filosofia è sempre datemi una shell ssh e vi farò qualsiasi cosa.

In varie occasioni, però, sbucano delle problematiche, specialmente nel mondo odierno:

  • In caso di alta latenza, diventa davvero difficile gestire la situazione vedendo ciò che si digita solo dopo qualche secondo
  • In caso di cambio di connettività (es: failover tra due differenti canali o passaggio da wifi a rete mobile), la sessione si interrompe
  • L'utilizzo del TCP, di ssh, può non essere sempre la scelta più adatta.

Mosh, un'ottima alternativa

Mosh si prefigge l'obiettivo di gestire e risolvere alcune tra queste problematiche e in maniera trasparente al normale utente.

Si pone infatti come applicazione di terminale remoto che supporta, in maniera efficace, connessione intermittente e mostra una copia locale di ciò che viene digitato. In caso di latenza della connessione, dunque, noi vedremo in tempo reale ciò che viene digitato anche se questo non è ancora stato recepito dal server di destinazione.

Vantaggi

Il vantaggio principale è che una sessione, una volta aperta, sarà snella (grazie al buffer locale) e costante (grazie all'utilizzo di UDP). Sarà dunque possibile, come sto facendo io in questo momento, scrivere del testo su un server remoto da una connessione con alta latenza e parzialmente intermittente senza minimamente avere alcun disagio, mentre con ssh ci sarebbe un palpabile disagio a causa delle situazioni che ho elencato.

Uno dei casi in cui Mosh mi ha soddisfatto di più è stato quello in cui si ha una connessione che viene chiusa, dal router o dal gestore, dopo qualche minuto di inattività. Ok, il problema è parzialmente aggirabile tenendo aperta, sul terminale remoto, una sessione di screen o tmux, ma non sempre ciò è fattibile o pratico. Inoltre, in certi casi, si ha un cambiamento di indirizzo IP e in quel caso non c'è nulla che si possa fare.

Mosh è inoltre parte di alcune applicazioni di terze parti (come Juicessh per Android) ed è ormai ben collaudato e testato.

Svantaggi

Non è tutt'oro ciò che luccica. Mosh ha degli svantaggi e non banali.

Uno di essi è la mancanza del port forwarding nativo. D'altronde non nasce per fare da tunnel di connessioni ma per essere un ottimo sistema di terminale remoto.

Un altro svantaggio è l'impossibilità di fare da tunnel per server X. Oggettivamente, nel mio caso, questo non è un gran problema (ho sempre usato poco questo tipo di soluzioni), ma per alcuni può esserlo.

Mosh necessita, inoltre, del suo server in esecuzione (non si appoggia solo a ssh) e, di default, utilizza una porta nel range 60000-61000, per cui almeno alcune di esse andrebbero aperte sul server (una porta per sessione).

Nel complesso, consiglio Mosh? Assolutamente si, prendendo però atto del fatto che non potremo, almeno in tutti i casi, fare a meno dell'ottimo e completo ssh.