Questo articolo è un estratto del libro Drive your boat like a Captain
Docker dalla release 1.12 fornisce un sistema di orchestration built-in che permette di unire e gestire più Docker Engine in un cluster. Questa nuova feature ci permette di distribuire container su più nodi e quindi prepararsi a gestire un ambiente di produzione con Docker.
Ci sono altri framework di Orchestration che usano Docker come container runtime, Kubernetes, Swarm (inteso come docker/swarm un progetto sempre di docker ma non built-in), Mesos e molto altri.
Questa nuova funzionalità si basa su un progetto chiamato SwarmKit: una serie di primitive che permettono di gestire applicazioni distribuite come node discovery, una implementazione di raft basata su coreos/raft e altro ancora.
Qui dalla versione Docker 1.12 in poi possiamo notare alcuni nuovi comandi:
docker swarm
docker node
docker service
Il primo comando ci permette di inizializzare e gestire il nosto cluster, il secondo di ispezionare i nostri nodi ed il terzo ad avviare, gestire e scalare le nostre applicazioni.
Possiamo partire subito con un esempio pratico utilizzando docker-machine per accendere 3 nuovi server nella nostra macchina locale utilizzando VirtualBox, per questo motivo occorre verificare di avere installato dia VitualBox, sia docker-machine, oppure l'intero stack che si può installare facilmente seguendo le indicazioni sul sito Docker Toolbox.
Per accendere i 3 nodi utilizziamo i comandi:
docker-machine create -d virtualbox sw1
docker-machine create -d virtualbox sw2
docker-machine create -d virtualbox sw3
A questo punto possiamo entrare nella prima macchina sw1
master
master e gli workers
nodi master
Raft
docker-machine ssh sw1
Una volta all'interno possiamo inizializzare il nostro cluster con il comando:
docker swarm init --advertise-addr 192.168.99.100
--advertise-addr
ifconfig
L'output di questo comando contiene un'informazione essenziale per aggiungere nodi all'interno del cluster, nell'esempio:
docker swarm join
--token SWMTKN-1-4bl65z15zd6nt4y0xc0mf639z4hhwphqn5l523bo6ws0yp230v-b96hecfns0k8ey3pasvwcp7gt
192.168.99.100:2377
Questo è il comando da utilizzare all'interno dei nostri futuri nodi per poterli aggiungere al cluster swarm.
Procediamo quindi uscendo dalla macchina e entrando in sw2
e sw3
eseguendo appunto il comando che docker ci ha suggerito. Poi verifichiamo che il nostro cluster sia composto da 3 nodi. Per farlo usciamo dalla nostra macchina, torniamo al nostro terminale, utilizziamo docker-machine per comunicare al docker client locale l'indirizzo del nostro master, servendoci del comando:
eval $(docker-machine env sw1)
A questo punto il nostro client sta comunicando con il nostro master e possiamo eseguire:
docker node ls
L'output ci dovrebbe mostrare i nostri 3 nodi, pronti per essere utilizzati. Procediamo ora con il deploy di una nostra applicazione.
Per il nostro esempio utilizziamo gianarb/micro:1.0.0 un'applicazione scritta in go presa su GitHub. Si tratta di un semplice server HTTP che espone la porta 8000, ha una homepage alla rotta /
the mostra l'ip del container in cui l'applicazione è eseguita. Questo piccolo servizio è molto utile perché quello che ci aspettiamo di vedere è la stessa applicazione distribuita in più container, su diversi nodi, quindi con ip diversi in base al container.
Prima di tutto creiamo un network:
docker network create -d overlay micro-net
Tutti i containers deployati all'interno di questa rete potranno comunicare tra di loro, in questo specifico esempio non abbiamo la necessità di far comunicare due container, perché la nostra applicazione non ha una dipendenza. Se invece utilizzassimo per esempio un databae mysql, dovremmo poi associare questa rete al container che ospita mysql.
Docker supporta diversi driver, perciò sentiamoci liberi di creare plugin per estendere le funzionalità del network, nel nostro caso overley è il driver di default ed permette ai nostri container di comunicare anche se non si trovano nello stesso nodo.
Creare un servizio
A questo punto creiamo il nostro primo servizio:
docker service create --name micro -p 8000 --replicas 1 --network micro-net gianarb/micro:1.0.0
Parametro | Descrizione |
---|---|
--name
|
È il nome del servizio |
-p
|
È la porta che espone il nostro HTTP server |
--replicas
|
È il numero di tasks da avviare, nel nostro caso 1 |
--network
|
Prende il nome del network creato in precedenza e il nome dell'immagine gianarb/micro:1.0.0
|