Da diversi mesi utilizzo docker per strutturare il processo di sviluppo/consegna di progetti web. Propongo ai lettori di «Хабрахабра» la traduzione di un articolo introduttivo su docker — .
Cos'è Docker?
Docker è una piattaforma aperta per lo sviluppo, la consegna e l'esecuzione di applicazioni. Docker è progettato per rilasciare più rapidamente le vostre applicazioni. Con docker è possibile separare la vostra applicazione dalla vostra infrastruttura e trattare l'infrastruttura come un'applicazione gestita. Docker aiuta a rilasciare il codice più velocemente, a testare più velocemente, a distribuire le applicazioni e a ridurre il tempo tra la scrittura del codice e il suo avvio. Docker lo fa attraverso una piattaforma leggera di virtualizzazione dei container, utilizzando processi e strumenti che aiutano a gestire e rilasciare le vostre applicazioni.
Nel suo nucleo, docker consente di eseguire praticamente qualsiasi applicazione, isolata in modo sicuro in un container. L'isolamento sicuro consente di eseguire più container contemporaneamente su un solo host. La natura leggera del container, che viene eseguito senza il sovraccarico di un hypervisor, consente di ottenere di più dall'hardware.
La piattaforma e gli strumenti di virtualizzazione dei container possono essere utili nei seguenti casi:
- imballare la vostra applicazione (e anche i componenti utilizzati) in container docker;
- distribuire e fornire questi container ai vostri team per lo sviluppo e il testing;
- distribuire questi container nei vostri ambienti di produzione, sia nei data center che nei cloud.
A cosa posso utilizzare docker?
Distribuzione rapida delle vostre applicazioni
Docker è perfetto per organizzare il ciclo di sviluppo. Docker consente agli sviluppatori di utilizzare container locali con applicazioni e servizi. Questo consente di integrarsi nel processo di integrazione continua e distribuzione.
Ad esempio, i vostri sviluppatori scrivono codice localmente e condividono il proprio stack di sviluppo (set di immagini docker) con i colleghi. Quando sono pronti, inviano il codice e i container all'ambiente di test e avviano i test necessari. Dall'ambiente di test possono inviare il codice e le immagini in produzione.
Distribuzione e implementazione più semplici
Una piattaforma basata su container Docker consente di portare facilmente il tuo carico utile. I container Docker possono funzionare sulla tua macchina locale, sia reale che virtuale nel data center, così come nel cloud.
La portabilità e la leggerezza di Docker permettono di gestire dinamicamente il tuo carico utile con facilità. Puoi utilizzare Docker per distribuire o arrestare la tua applicazione o i tuoi servizi. La velocità di Docker consente di farlo quasi in tempo reale.
Carichi elevati e più carichi utili
Docker è leggero e veloce. Offre un'alternativa sostenibile ed economica alle macchine virtuali basate su hypervisor. È particolarmente utile in contesti di carico elevato, ad esempio, per creare il tuo cloud o una piattaforma come servizio (platform-as-service). Ma è anche utile per applicazioni piccole e medie, quando desideri ottenere di più dalle risorse disponibili.
Componenti principali di Docker
Docker è composto da due componenti principali:
- Docker: piattaforma di virtualizzazione open source;
- Docker Hub: la nostra piattaforma come servizio per distribuire e gestire container Docker.
Nota! Docker è distribuito con licenza Apache 2.0.
Architettura di Docker
Docker utilizza un'architettura client-server. Il client Docker comunica con il demone Docker, che si occupa del peso della creazione, esecuzione e distribuzione dei tuoi container. Entrambi, client e server, possono funzionare su un unico sistema, puoi connettere il client a un demone Docker remoto. Client e server comunicano tramite socket o tramite RESTful API.

Demone Docker
Come mostrato nel diagramma, il demone è avviato sulla macchina host. L'utente non interagisce direttamente con il server, ma utilizza il client per farlo.
Client Docker
Il client Docker, il programma Docker, è l'interfaccia principale per Docker. Riceve comandi dall'utente e interagisce con il demone Docker.
All'interno di Docker
Per capire di cosa è composto Docker, è necessario conoscere tre componenti:
- immagini (images)
- registri (registries)
- container
Immagini
L'immagine Docker è un template di sola lettura. Ad esempio, un'immagine può contenere il sistema operativo Ubuntu con Apache e un'applicazione. Le immagini vengono utilizzate per creare contenitori. Docker consente di creare facilmente nuove immagini, aggiornare quelle esistenti o scaricare immagini create da altre persone. Le immagini sono un componente della costruzione di Docker.
Registry
Il registro Docker memorizza le immagini. Ci sono registri pubblici e privati, da cui è possibile scaricare o caricare immagini. Il registro Docker pubblico è . Qui si trova un'enorme collezione di immagini. Come sapete, le immagini possono essere create da voi o potete utilizzare immagini create da altre persone. I registri sono un componente della distribuzione.
Contenitori
I contenitori somigliano a directory. In un contenitore c'è tutto ciò che serve per far funzionare un'applicazione. Ogni contenitore è creato a partire da un'immagine. I contenitori possono essere creati, avviati, fermati, trasferiti o eliminati. Ogni contenitore è isolato e costituisce una piattaforma sicura per l'applicazione. I contenitori sono un componente del funzionamento.
Come funziona Docker?
Fino ad ora sappiamo che:
- possiamo creare immagini che contengono le nostre applicazioni;
- possiamo creare contenitori da immagini per eseguire applicazioni;
- possiamo distribuire immagini tramite Docker Hub o un altro registro di immagini.
Vediamo come si combinano questi componenti.
Come funziona un'immagine?
Sappiamo già che l'immagine è un template di sola lettura da cui si crea un contenitore. Ogni immagine è composta da una serie di livelli. Docker utilizza per combinare questi livelli in un'unica immagine. Il file system unione consente a file e directory provenienti da diversi file system (diverse branche) di sovrapporsi in modo trasparente, creando un file system coerente.
Uno dei motivi per cui Docker è leggero è l'uso di tali livelli. Quando si modifica un'immagine, ad esempio, aggiornando un'applicazione, viene creato un nuovo livello. Così, senza sostituire l'intera immagine o ricostruirla, come si potrebbe dover fare con una macchina virtuale, viene solo aggiunto o aggiornato il livello. E non è necessario distribuire l'intera nuova immagine, viene distribuito solo l'aggiornamento, il che rende più semplice e veloce la distribuzione delle immagini.
Alla base di ogni immagine c'è un'immagine di base. Ad esempio, ubuntu, immagine di base di Ubuntu, o fedora, immagine di base della distribuzione Fedora. Puoi anche utilizzare le immagini come base per crearne di nuove. Ad esempio, se hai un'immagine apache, puoi usarla come immagine di base per le tue applicazioni web.
Nota! Docker di solito prende le immagini dal registro Docker Hub.
Le immagini Docker possono essere create da queste immagini di base, i passaggi per creare queste immagini vengono chiamati istruzioni. Ogni istruzione crea una nuova immagine o livello. Le istruzioni includeranno le seguenti azioni:
- esecuzione di un comando
- aggiunta di un file o una directory
- creazione di una variabile d'ambiente
- indicazione di cosa eseguire quando viene avviato il contenitore di questa immagine
Queste istruzioni sono memorizzate in un file Dockerfile. Docker legge questo Dockerfile, quando costruisci l'immagine, esegue queste istruzioni e restituisce l'immagine finale.
Come funziona il registro docker?
Il registro è uno storage di immagini docker. Dopo aver creato un'immagine, puoi pubblicarla su un registro pubblico Docker Hub o su un registro personale.
Con il client docker puoi cercare immagini già pubblicate e scaricarle sulla tua macchina con docker per creare contenitori.
Docker Hub fornisce repository pubblici e privati di immagini. La ricerca e il download delle immagini dai repository pubblici sono disponibili per tutti. Il contenuto dei repository privati non appare nei risultati di ricerca. Solo tu e i tuoi utenti potete ottenere queste immagini e creare contenitori da esse.
Come funziona un contenitore?
Un contenitore è composto da un sistema operativo, file utente e metadati. Come sappiamo, ogni contenitore è creato da un'immagine. Quest'immagine indica a docker cosa c'è nel contenitore, quale processo avviare quando viene avviato il contenitore e altre informazioni di configurazione. L'immagine Docker è disponibile solo in lettura. Quando docker avvia un contenitore, crea un livello di lettura/scrittura sopra l'immagine (utilizzando il sistema di file unione, come indicato in precedenza), in cui può essere eseguita un'applicazione.
Cosa succede quando viene avviato un contenitore?
O tramite il programma docker, o tramite API RESTful, il client docker dice al demone docker di avviare il contenitore.
$ sudo docker run -i -t ubuntu /bin/bash
Analizziamo questo comando. Il client viene avviato con il comando docker, con l'opzione run, che dice che verrà lanciato un nuovo contenitore. I requisiti minimi per l'avvio del contenitore sono i seguenti attributi:
- quale immagine utilizzare per creare il contenitore. Nel nostro caso
ubuntu - il comando che desideri eseguire quando il contenitore verrà avviato. Nel nostro caso
/bin/bash
Cosa succede sotto il cofano quando eseguiamo questo comando?
Docker, in ordine, fa quanto segue:
- scarica l'immagine ubuntu: docker verifica la presenza dell'immagine
ubuntusulla macchina locale, e se non è presente — la scarica da . Se l'immagine è presente, la utilizza per creare il contenitore; - crea il contenitore: quando l'immagine è stata ricevuta, docker la utilizza per creare il contenitore;
- inizializza il file system e monta il livello di sola lettura: il contenitore è stato creato nel file system e il livello di sola lettura è stato aggiunto all'immagine;
- inizializza la rete/ponte: crea un'interfaccia di rete che consente a docker di comunicare con la macchina host;
- Imposta l'indirizzo IP: trova e imposta l'indirizzo;
- Avvia il processo specificato: avvia la tua applicazione;
- Gestisce e fornisce l'output della tua applicazione: si collega e registra l'input standard, l'output e il flusso di errori della tua applicazione, in modo da poter monitorare come funziona la tua applicazione.
Ora hai un contenitore funzionante. Puoi gestire il tuo contenitore, interagire con la tua applicazione. Quando decidi di fermare l'applicazione, elimina il contenitore.
Tecnologie utilizzate
Docker è scritto in Go e utilizza alcune funzionalità del kernel Linux per implementare la funzionalità sopra descritta.
Namespace
Docker utilizza la tecnologia namespace per organizzare spazi di lavoro isolati, che chiamiamo contenitori. Quando avviamo un contenitore, docker crea un insieme di namespace per quel contenitore.
Questo crea un livello isolato, ogni aspetto del contenitore viene eseguito nel proprio namespace, e non ha accesso al sistema esterno.
Ecco un elenco di alcuni namespace utilizzati da docker:
- pid: per l'isolamento dei processi;
- net: per gestire le interfacce di rete;
- ipc: per gestire le risorse IPC. (ICP: InterProcess Communication);
- mnt: per gestire i punti di montaggio;
- utc: per isolare il kernel e controllare la generazione di versioni (UTC: Unix timesharing system).
Gruppi di controllo
Docker utilizza anche la tecnologia cgroups o gruppi di controllo. La chiave per far funzionare l'applicazione in isolamento, fornendo all'applicazione solo le risorse che desideri fornire. Questo garantisce che i container siano buoni vicini. I gruppi di controllo consentono di dividere le risorse hardware disponibili e, se necessario, impostare limiti e restrizioni. Ad esempio, limitare la quantità massima di memoria per un container.
Union File System
Il Union File System o UnionFS è un filesystem che funziona creando livelli, rendendolo molto leggero e veloce. Docker utilizza UnionFS per creare i blocchi da cui si costruisce un container. Docker può utilizzare diverse varianti di UnionFS, tra cui: AUFS, btrfs, vfs e DeviceMapper.
Formati dei container
Docker combina questi componenti in un contenitore, che chiamiamo formato del container. Il formato utilizzato per impostazione predefinita si chiama libcontainer. Docker supporta anche il formato tradizionale dei container in Linux tramite . In futuro, Docker potrebbe supportare altri formati di container. Ad esempio, integrandosi con BSD Jails o Solaris Zones.
Fonte: habr.com
