Ne avrete senz’altro sentito parlare, è una delle tecnologie più in voga del momento e sta guadagnando rapido consenso tra gli addetti ai lavori: i numeri presentati a DockerConf 2017 parlano di 14 milioni di host, 900mila apps, 3300 partecipanti al progetto e 170mila membri della community e 12 miliardi di immagini scaricate.
In questa serie di articoli introdurremo i concetti base di Docker, in modo da avere delle basi solide con cui esplorare il vastissimo ecosistema ad esso collegato.
Il progetto Docker nasce come un progetto interno di dotCloud, un’azienda attiva nel settore PaaS, e basato su container LXC. Nel 2013 viene presentato con una storica demo alla convention PyCon e rilasciato in modalità open-source, e l’anno seguente cessa il supporto a LXC come motore di virtualizzazione in favore di libcontainer (poi runc), una libreria sviluppata internamente in Go che offre prestazioni migliori e un grado di isolamento tra container e sicurezza maggiore. Il seguito è un crescendo di sponsorizzazioni, investimenti e interesse generale che elevano Docker a standard de-facto in ambito sviluppo.
Fa parte della Open Container Project Foundation, la fondazione di Linux Foundation che si occupa regola gli standard aperti nel mondo dei container e che consta di importanti membri come AT&T, AWS, DELL EMC, Cisco, IBM Intel etc.
Docker è basato su architettura client-server; il client comunica con il daemon dockerd che si occupa della generazione, esecuzione e distribuzione dei container. Possono girare sullo stesso host o su sistemi diversi, e in questo caso il client comunica tramite API REST, socket UNIX o interfaccia di rete con il daemon. Il registro contiene le immagini; Docker Hub è un registro pubblico, Docker Registry invece è un esempio di registro privato.
Docker Engine è l’applicazione client-server che gestisce questi componenti.
Container vs VM
Docker si occupa di container, un concetto di virtualizzazione che ha radici lontane nel tempo (la prima implementazione, cioè i chroot di Unix, è del 1983), ma è solo dagli anni 2000 che ha conosciuto importanti sviluppi e trovato applicazioni che ne hanno decretato il successo. VM e container (CT) sono sostanzialmente diversi per struttura, pur permettendo un’esperienza d’uso per larghi tratti analoga. Una VM ricrea totalmente un sistema operativo, completo di emulazione del kernel e dello user-space. L’uso delle risorse computazionali è intensivo e lo stato esecutivo è il risultato di una combinazione di dipendenze e impostazioni del sistema difficilmente replicabile
All’opposto, un CT emula solo lo user-space e non il kernel, per il quale viene sfruttato quello dell’hypervisor. Ne consegue che, strettamente parlando, i CT possono essere solo Linux, e non Windows, macOS o *BSD come in una VM. Ciascun container contiene solo il codice, le dipendenze e le impostazioni necessarie ad eseguire l’applicazione a cui sono rivolti, mentre condivide il kernel con il sistema operativo sottostante.
I vantaggi di questo paradigma sono essenzialmente due. Il primo riguarda le risorse necessarie per la virtualizzazione: un container ha bisogno solo di ricreare lo user-space, risultando in un overhead minore rispetto ad un’emulazione completa di kernel. Dunque anche le dimensioni del CT sono contenute, visto che il kernel e gli applicativi e le librerie non usate che vengono fornite con un sistema operativo completo, tipico delle VM, non sono presenti. Il secondo riguarda la compatibilità e la portabilità dei container, esemplificata dallo slogan “Build, Ship, and Run Any App, Anywhere”.
Infatti, le immagini da cui vengono creati i container hanno bisogno solo di Docker per essere usate e dal momento che Docker è disponibile su diversi sistemi operativi ed architettura, ne consegue che i container risultano una tecnologia sostanzialmente agnostica nei confronti dell’host su cui girano. Dunque si può sviluppare del codice su Windows da utilizzare poi su Linux sfruttando la portabilità offerta da Docker, e dal momento che è facilmente replicabile lo stato effettivo del container, anche i problemi di compatibilità spariscono.
In definitiva i Container non sono solo “delle macchine virtuali che si avviano più in fretta”, ma aprono le porte al paradigma dei micro-servizi, un’idea di deployment dove i servizi monolitici sono sostituiti da tanti servizi atomici, i micro-servizi per l’appunto.
Docker ben si sposa in quest’ottica e permette, ad esempio, di creare un’istanza per il web server, una per il database e una per il linguaggio di scripting, laddove in precedenza si sarebbe inserito lo stack LAMP in una sola macchina virtuale.
I vantaggi che comporta il paradigma dei micro-servizi sono innumerevoli e richiedono una trattazione adeguata; e in ogni caso non sempre questo paradigma è quello migliore, deve essere ponderato caso per caso.
Requisiti di installazione e sistemi supportati
Docker è disponibile in due edizioni: la Community Edition (CE) e la Enterprise Edition (EE); la prima è gratuita, la seconda è a pagamento e ha due canali di aggiornamento (Stable, con release quadrimestrali, ed Edge, con release mensile). È indirizzata in particolare a contesti con applicazioni business critical. Sono incluse funzionalità avanzate come gestione avanzata di immagini e container, ecosistema certificato e scansione sicurezza immagini.
Sono supportati i sistemi operativi macOS, Windows 10 e Windows Server 2016 e Linux (diverse distribuzioni tra cui CentOS, RHEL, Suse, Ubuntu e Debian); le architetture supportate includono x86_64, ARM, ARM64 e IBM Z e ovviamente il processore deve avere la virtualizzazione abilitata.
Per le istruzioni specifiche al sistema operativo e alla piattaforma supportata, nonché alla matrice di compatibilità, rimandiamo alla documentazione ufficiale. Su Windows 7, 8 e 8.1, Docker va installato con Docker Toolbox, e non tramite installazione tipica.
Docker Cloud consente l’installazione su ambienti Cloud di partner come Amazon Web Services, Microsoft Azure e DigitalOcean.
Docker si utilizza tramite linea di comando o GUI (ad esempio, Portainer o Rancher). Gli strumenti di orchestrazione come Docker Swarm e Kubernetes costituiscono un capitolo a parte.