Docker - parte 1

Pubblicato il mar 21 maggio 2019 in tutorial • 4 min read

Docker è una sistema software di virtualizzazione open-source che opera a livello di sistema operativo. Permette di eseguire applicazioni isolate l'una dall'altra servendosi dei cosidetti containers. Ciascun container contiene l'applicazione stessa, le sue dipendenze e i files di configurazione necessari. L'utilizzo dei containers permette agli sviluppatori di generare, gestire e distribuire applicazioni software critiche senza preoccuparsi della tecnologia dell'infrastruttura sottostante. E' possibile addirittura utilizzare di sistemi di automazione, come Ansible, per creare e distribuire i containers sui sistemi remoti.

Tecnologia

Docker sfrutta una serie di caratteristiche del kernel Linux, come i control groups (cgroups), i namespaces e l'overlay filesystem (OverlayFS); e questo permette di far girare container multipli isolati sulla stessa instanza del kernel Linux. Mentre i namespaces forniscono una vista isolata sull'ambiente del sistema operativo (albero dei processi, interfacce di rete, file systems montati, User IDs), i cgroups permettono la gestione delle risorse, limitando l'uso della CPU e della memoria da parte dei singoli containers. In aggiunta a tutto questo Red Hat ha adattato SELinux all'uso di Docker permettendo di stabilire policy di sicurezza aggiuntive per proteggere il sistema host su cui girano i containers.

Mentre le prime versioni di Docker accedevano alle funzionalità del kernel tramite l'interfaccia LXC, a partire dalla versione 0.9, Docker utilizza libcontainer, un nuovo layer di astrazione che fornisce un modo standard per gestire i containers e accedere alle funzionalità del sistema. Inoltre il nuovo layer di astrazione permette anche il porting di Docker su altre piattaforme non Linux. Infatti, sebbene pensato per Linux, è possibile far girare Docker anche su Windows e MacOS servendosi di Hyper-V o VirtualBox.

+-----------------------------------------------------+
|                      *Docker*                       |
+-----------------------------------------------------+
        |             |         |           |
   libcontainer      libvirt    LXC     systemd-nspawn
        |             |         |           |
        v             v         v           v
+-----------------------------------------------------+
|                   *Linux Kernel*                    |
|                                                     |
|    cgroups                             Netlink      |
|                      namespaces                     |
|              SELinux              Netfilter         |
|                           AppAmor                   |
+-----------------------------------------------------+

Benché il concetto di base sia lo stesso di altri tipi di virtualizzazione, come ad esempio quello delle virtual machines (VMs), c'è una sostanziale differenza: mentre diverse guest VMs possono essere eseguite sul medesimo sistema host, ciascuna di esse richiede la virtualizzazione di un sistema operativo completo. I containers Docker, invece, possono girare sul sistema ospite (host) come normali processi, condividendone il kernel. Come risultato, i containers richiedono molte meno risorse in termini di spazio di archiviazione, di CPU e di memoria rispetto le VMs.

Macchine Virtuali (VMs):

+---------------+  +---------------+  +---------------+
|      VM       |  |      VM       |  |      VM       |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| |   App A   | |  | |   App B   | |  | |   App C   | |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| | Bins/Libs | |  | | Bins/Libs | |  | | Bins/Libs | |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| | Guest OS  | |  | | Guest OS  | |  | | Guest OS  | |
| +-----------+ |  | +-----------+ |  | +-----------+ |
+---------------+  +---------------+  +---------------+
+-----------------------------------------------------+
|                     Hypervisor                      |
+-----------------------------------------------------+
+-----------------------------------------------------+
|                   Infrastructure                    |
+-----------------------------------------------------+

Containers Docker:

+---------------+  +---------------+  +---------------+
|   Container   |  |   Container   |  |   Container   |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| |   App A   | |  | |   App B   | |  | |   App C   | |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| +-----------+ |  | +-----------+ |  | +-----------+ |
| | Bins/Libs | |  | | Bins/Libs | |  | | Bins/Libs | |
| +-----------+ |  | +-----------+ |  | +-----------+ |
+---------------+  +---------------+  +---------------+
+-----------------------------------------------------+
|                        Docker                       |
+-----------------------------------------------------+
+-----------------------------------------------------+
|                       Host OS                       |
+-----------------------------------------------------+
+-----------------------------------------------------+
|                   Infrastructure                    |
+-----------------------------------------------------+

Architettura e componenti

Il demone docker dockerd è un processo sempre attivo in background sul sistema ospite (host) e gestisce tutti i containers che in un dato momento sono in esecuzione sul sistema. Per interagire col demone si può utilizzare il software, con un'interfaccia a linea di comando, docker che comunica col demone dockerd per mezzo delle Docker Engine API.

Oltre a tutto ciò molte altre componenti entrano in gioco nell'ambito di Docker. In breve sono:

  • Image: Un template in sola lettura che è utilizzato per construire il container. L'image include l'applicazione stessa come anche tutto ciò che è necessario per eseguirla: l'ambiente di runtime, le librerie dinamiche, i file di configurazione, etc.
  • Container: Un'instanza in esecuzione dell'immagine. Il container viene eseguito come singolo processo sul sistema host. Container multipli della stessa immagine possono essere eseguiti contemporaneamente sullo stesso host.
  • Layer: Parte di un'immagine che consiste in un comando o in un file. Ciacuna modifica all'immagine verrà memorizzata come un layer separato permettendo di tenere traccia dei cambiamenti.
  • Dockerfile: E' un file di testo che descrive i comandi richiesti per generare l'image. Per ciascun comando eseguito viene generato un nuovo layer.
  • Repository: E' l'insieme delle diverse versioni della stessa immagine con differenti tags.
  • Registry: E' un repository per immagini Docker. Gestisce immagini differenti e le rende disponibili agli utenti. Docker Hub è uno dei registry più popolari.
  • Docker Compose: Uno strumento per definire ed eseguire molteplici containers allo stesso tempo. La configurazione dei diversi containers interdipendenti è fatta servendosi di file di configurazione in YAML.
  • Docker Swarm: Una funzionalità che permette il clustering dei container Docker. In parole povere permette di gestire un gruppo di docker engines come fossero un singolo docker engine.

Installazione

Per installare la versione corrente di Docker su Debian, è consigliato usare la versione per Debian presente sui repository ufficiali Docker.

Prima di tutti bisogna assicurarsi che alcuni strumenti richiesti siano presenti sul sistema e in caso contrario bisogna installarli con il seguente comando:

$ sudo apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common

A questo punto si deve scaricare la chiave pubblica, usata da Docker per firmare i paccheti, ed aggiungerla al sistema:

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -

In seguito bisogna aggiungere i repositories Docker al sistema:

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"

Adesso si potrà procedere all'installazione di Docker Community Edition (CE):

apt-get update
apt-get install docker-ce

Il demone docker verrà avviato automaticamente dopo l'installazione.

Per assicurarsi che tutto funzioni a dovere eseguite il segente comando:

$ docker info

Per testare che tutto funzioni, avviamo l'immagine di prova hello-world:

docker run hello-world

Questo comando provvederà a scaricare l'immagine dai server del registry predefinito, Docker Hub, e ad eseguirne una sua instanza.

L'instanza hello-world dovrebbe comparire nella lista delle immagini in esecuzione. Per mostrarle base eseguire:

docker container ls --all

Continua su Docker - parte 2.