Docker su MAC OS X

Docker Beta on Mac Da oggi e' disponibile la versione Beta di Docker su Mac OSX: e' quindi arrivato il momento di scrivere una paginetta su questa importante e recente tecnologia!

Introduzione

La tecnologia dei container consente di eseguire immagini di applicazioni utilizzando un'interfaccia virtuale al sistema operativo chiamata container. In questo modo l'applicazione pensa di avere un sistema operativo dedicato ma in realta' sfrutta quello della macchina ospite. Rispetto alla tradizionale tecnologia della virtualizzazione le immagini sono molto piu' ridotte in dimensioni e richiedono risorse molto piu' limitate. Il risultato e' che un'immagine docker viene avviata molto piu' velocemente, per dare un termine di paragone mezzo secondo invece che un minuto!

L'altro importante vantaggio e' che l'immagine e' dell'intera applicazione con il suo ambiente. Quindi tutte impostazioni, configurazioni, ... sono gia' state impostate da chi ha preparato l'immagine.

Vediamo un esempio: il classico Hello World!

$ docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 4276590986f6: Pull complete a3ed95caeb02: Pull complete Digest: sha256:4f32210e234b4ad5cac92efacc0a3d602b02476c754f13d517e1ada048e5a8ba Status: Downloaded newer image for hello-world:latest Hello from Docker. This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker Hub account: https://hub.docker.com For more examples and ideas, visit: https://docs.docker.com/engine/userguide/

In pratica in pochi secondi e' stata scaricata un'immagine e quindi eseguita!

Utilizzo

Ovviamente dobbiamo prima installare l'APP sul Mac come descritto nella documentazione ufficiale.

Siamo su un Mac, la prima cosa da far partire e' l'APP con la balenottera azzurra...
Qualche secondo e l'ambiente runtime viene caricato ed e' possibile richiamare i comandi Docker.
Con un click sull'icona sulla barra di stato viene visualizzato il menu. Scegliendo Preferences e' possibile modificare le impostazioni, ma al momento non ci serve, quindi proseguiamo con i comandi in linea.

I comandi di docker sono semplici e ricordano quelli unix: prima il comando docker poi l'opzione info:

$ docker info
Containers: 1
 Running: 0
 Paused: 0
 Stopped: 1
Images: 1
Server Version: 1.11.1
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 4
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins: 
 Volume: local
 Network: null host bridge
Kernel Version: 4.4.9-moby
Operating System: Alpine Linux v3.3
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 1.954 GiB
Name: moby
ID: AE65:2WZL:KJDI:43OZ:XRBA:SV56:PBRM:GDRA:LWUC:CG6Z:OKLL:JWNL
Docker Root Dir: /var/lib/docker
Debug mode (client): false
Debug mode (server): true
 File Descriptors: 22
 Goroutines: 38
 System Time: 2016-05-25T09:26:44.156916103Z
 EventsListeners: 1
Registry: https://index.docker.io/v1/

Docker: diagramma a stati semplificato La sequenza tipica di attivazione di un'immagine e' docker run IMAGE_NAME, docker stop IMAGE_NAME (per fermarla), docker start IMAGE_NAME (per farla ripartire dallo stesso punto). Un'immagine non attiva puo' essere rimossa con docker rm IMAGE_NAME; a questo punto e' possibile farla ripartire con run, ma sara' come se fosse stato effettuato un reboot.
E' anche possibile fermare un immagine con docker kill IMAGE_NAME, che effettua un abort con sigkill, ma si preferisce in genere lo stop.

Altri comandi utili sono docker system df (controllo spazio), l'opzione docker ps --all (che consente di vedere anche le immagini non attive), docker logs XXX (visualizza il log dell'applicazione), docker stats (che fa vedere l'utilizzo di risorse da parte dei container), docker rm (cancella un'immagine), docker system prune -a --volumes (che cancella tutto, ma proprio tutto, quello che non e' attivo), ...

Naturalmente con docker --help si ottiene l'elenco tutti i comandi e con docker COMMAND --help si ottiene il dettaglio delle opzioni del comando indicato.

Se lanciando un comando avete l'errore:
  Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
Semplicemente non avete lanciato l'APP Docker!

Esempi

Docker e' lo strumento ideale per provare ambienti ed architetture complesse effettuando un setup completo in pochissimo tempo. Nel seguito vedremo qualche esempio cercando di presentare ogni volta nuovi comandi o opzioni di Docker.

Microsoft SQL Server su Linux

Microsoft SQL e' stato reso disponibile su Linux, le prime Beta erano facilmente installabili con Docker:

docker pull microsoft/mssql-server-linux

docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=XXX' -p 1433:1433 -v /tmp/sqlserver:/var/opt/mssql -d microsoft/mssql-server-linux

docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                    NAMES
f73a6cd8ee7b        microsoft/mssql-server-linux   "/bin/sh -c /opt/mssq"   4 seconds ago       Up 3 seconds        0.0.0.0:1433->1433/tcp   focused_almeida

mssql -s localhost -u SA -p SqlSeverDem0
Connecting to localhost...done
sql-cli version 0.4.9
Enter ".help" for usage hints.
mssql> SELECT Name from sys.Databases;
Name  
------
master
tempdb
...

Da notare che la porta 1433 e' stata dichiarata ed e' cosi' accessibile dall'host: possiamo utilizzare un client locale per lavorare su MSSQL dal nostro MacOS. Altra nota importante e' il mapping di una directory sul sistema ospite. L'opzione -d manda in esecuzione in background e -e serve per passare variabili di ambiente.

MySQL Replication

Un altro DB... questa volta e' MySQL ma vogliamo provare la Group Replication che richiede almeno tre nodi in cluster che debbono parlare tra loro. Usando delle VM il setup sarebbe complesso e pesante, con Docker puo' essere ospitato tranquillamente anche su un Mac normale:

docker network create group1
docker run --name node1 -e MYSQL_ROOT_PASSWORD=XXX -v /myCustom/m1:/etc/mysql/conf.d --net=group1 -d mysql:latest
docker run --name node2 -e MYSQL_ROOT_PASSWORD=XXX -v /myCustom/m2:/etc/mysql/conf.d --net=group1 -d mysql:latest
docker run --name node3 -e MYSQL_ROOT_PASSWORD=XXX -v /myCustom/m3:/etc/mysql/conf.d --net=group1 -d mysql:latest

docker exec -it node1 bash
docker exec -it node2 mysql -p

Con l'exec si esegue un comando sul container... in questo caso lanciamo una shell che ci consente di lavorare direttamente sul container con una connessione terminale, in modalita' interattiva con l'opzione -it. Con la bash potremo lanciare qualsiasi comando (eg. ls, ps, dpkg, ...) naturalmente purche' sia disponibile nel container. Come immagine abbiamo scelto l'ultima ufficiale ma con :tag si puo' scegliere la versione di MySQL. Ma quale sistema operativo troveremo? Dipende da chi ha preparato l'immagine; le distribuzioni piu' utilizzate sono Alpine, Ubuntu, Debian [NdA in questo caso il sistema e' molto, molto ridotto: per fare un ps si deve usare ls /proc].
Altro elemento importante e' la creazione di una rete virtuale che consente ai container di operare come in rete locale. Il networking e' uno dei punti di forza della tecnologia dei container. Anche se e' un po' complesso per ora basti dire che utilizzando la stessa network i container si parlano!

In realta' abbiamo solo creato i tre server MySQL ora bisogna eseguire tutta la configurazione, ma e' un po' lunga e non ha elementi di interesse su Docker... Come risorse utili ecco esempi di comandi per la i configurazione della replica Master-Slave, la configurazione replica Master-Master e qualche pagina di descrizione sulla replica MySQL e sulla Group Replication.
Last but not least: MySQL Operator for Kubernetes [NdA come da documentazione ufficiale].

PostgreSQL Streaming Replication

Su PostgreSQL vogliamo provare la streaming replication:

docker network create group2
docker run --name my-postgres_m --net=group2  -v /my/datadir:/var/lib/postgresql/data -d postgres:tag
docker run --name my-postgres_s --net=group2  -v /my/datadir:/var/lib/postgresql/data -d postgres:tag

In questo caso abbiamo mappato una directory locale cosi' potremo modificare facilmente i file di configurazione di PostgreSQL... il mapping con i dischi locali e' molto utilizzato e molto comodo sia per la parte dati che per i file di configurazione.

Nell'esempio al posto di tag va utilizzata la versione scelta... questo e' l'ultimo trucco perche' mettendo assieme i vari pezzi e' davvero possibile, ed anche semplice, attivare piu' server ed impostare le repliche!

ClickHouse OLAP

Stiamo utilizzando una versione aggiornata del database colonnare ClickHouse? Meglio controllare!

$ docker images | grep click
REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
yandex/clickhouse-client               latest              238a36947ae7        2 weeks ago         464MB
yandex/clickhouse-server               latest              a0a8ddadf7d5        4 months ago        426MB
spoonest/clickhouse-tabix-web-client   latest              e869c1a905d9        11 months ago       245MB

$ docker pull yandex/clickhouse-server
Using default tag: latest
latest: Pulling from yandex/clickhouse-server
878c4669b1b1: Already exists 
...
bc8115b7afd3: Pull complete 
6406927d8c98: Pull complete 
Digest: sha256:6ddc3d058f701f5d1aa2cbf3d0648c07b9af334f940b8b169494e2071ababb0
Status: Downloaded newer image for yandex/clickhouse-server:latest

$ docker images | grep clickhouse-server
REPOSITORY                 TAG        IMAGE ID       CREATED         SIZE
yandex/clickhouse-server   latest     7b8c63278e47   9 days ago      754MB
yandex/clickhouse-server   <none>     f87e8211a5f0   2 weeks ago     754MB
yandex/clickhouse-server   20.4.2.9   46bec7d67f35   18 months ago   495MB
yandex/clickhouse-server   <none>     562b487cf2c9   21 months ago   486MB

$ docker run --name ch -d yandex/clickhouse-server:latest
$ docker exec -it ch bash
# clickhouse-client
ClickHouse client version 21.11.4.14 (official build).
...

Gli aggiornamenti delle immagini sono molto semplici: basta un pull!
Vengono controllati tutti i componenti da aggiornare e quindi vengono scaricati. Ovviamente per eseguire le immagini aggiornate si usa il run come visto prima...

Diagramma a stati

L'ho disegnato... ma questo diagramma a stati e' fatto molto meglio! Docker: diagramma a stati

[NdE l'originale e' in questa pagina molto completa]

Altro su Docker

Sono molti gli elementi di Docker che, per brevita', non sono stati riportati in questo documento... ma che comunque importante ricordare!

Un Docker repository e' dove e' possibile memorizzare le diverse versioni delle immagini Docker. Docker Hub e' il piu' noto registry che ospita repository pubblici e privati di immagini.

Un Dockerfile e' un file di testo che contiene una serie di comandi (FROM RUN ENV ARG CMD) che vengono eseguiti durante la costruzione dell'immagine.

Docker Compose e' un tool per definire applicazioni Docker multi-container. In genere si utilizza un file YAML per definire i servizi applicativi che possono poi essere attivati con un singolo comando.

Architettura su Mac OSX

Le applicazioni come immagini in un container girano su tutte le piattaforme nello stesso identico modo. Ma Docker ha implementazioni differenti su Linux rispetto a MS-Windows e Mac OSX. Su Mac OSX viene utilizzata una VM su cui a sua volta vengono eseguiti i container, cosi' dice la documentazione. Ovviamente non ci credevo... quindi ho controllato e c'e' davvero la VM hyperkit [NdA nelle prime release era utilizzata una VM VirtualBox]:

$ pstree Docker_PID -+= 69372 xxx /Applications/Docker.app/Contents/MacOS/Docker \-+= 69398 xxx /Applications/Docker.app/Contents/MacOS/com.docker.supervisor -watchdog fd:0 |--- 69399 xxx com.docker.osxfs serve --address fd:3 --connect vms/0/connect --control fd:4 --log-destination asl |-+- 69400 xxx com.docker.vpnkit --ethernet fd:3 --diagnostics fd:4 --pcap fd:5 --vsock-path vms/0/connect --gateway-forwards /Users/xxx/Library | \--- 69403 xxx (uname) |-+- 69401 xxx com.docker.driver.amd64-linux -addr fd:3 -debug | \--- 69405 xxx com.docker.hyperkit -A -u -F vms/0/hyperkit.pid -c 4 -m 4096M -s 0:0,hostbridge -s 31,lpc -s 1:0,virtio-vpnkit,path=vpnkit.eth. \--- 69402 xxx com.docker.backend -addr fd:3

Dal punto di vista tecnico Docker su MacOS non gira come su Linux in modo nativo. E' presente una VM che a sua volta contiene i container, questa implementazione genera alcune piccole differenze ma per le immagini ospitate non ci sono problemi.
Docker for Mac - Preferences E' possibile connettersi alla VM con: screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty. In realta' non funziona da un po'... quindi si usa:
  docker run -it --rm --privileged --pid=host justincormack/nsenter1

Se dall'immagine Docker si vuole accedere ad una porta sul Mac si deve utilizzare l'indirizzo host.docker.internal (in realta' vi sono diverse possibilita' di configurazione della rete... ma con l'impostazione a bridge, che e' il default, questo e' il modo piu' facile).

Docker su Mac supporta Docker Swarm, Swarm Mode e Kubernetes [NdA con funzionalita' crescenti introdotte nella 17.12 e poi 18.04].

A parte le differenze di implementazione il risultato finale non cambia: le applicazioni ospitate su Docker hanno immagini che non contengono un sistema operativo e girano in modo indipendente dall'ambiente ospite.
Il risultato finale e' quello di un'ambiente virtuale molto piu' veloce da attivare e piu' flessibile negli aggiornamenti.

Il Docker Desktop su Mac ha un'interfaccia integrata per la configurazione dell'ambiente (cfr. figura a destra).

Varie ed eventuali

Sviluppato da dotCloud Docker e' stato pubblicato come open source nel 2013-03. Dalla versione 0.9 Docker utilizza libcontainer (scritto in Go) al posto di LXC.

L'evoluzione di Docker e' stata notevole e molto veloce, le attuali versioni sono molto piu' robuste ed efficienti delle prime disponibili. Inoltre sono state introdotte funzionalita' di multi-container applications, cluster, bilanciamento e crescita on demand molto utili per gli ambienti in alta affidabilita' (eg. Compose, Swarm). Come esempio di piattaforma Kubernetes potete leggere questa paginetta su VMware Tanzu.

Anche se ho pubblicato questa paginetta quando e' stata distribuita la versione Beta di Docker su MacOS... oramai la versione di produzione e' disponibile da tempo!


Titolo: Docker su MAC OS X
Livello: Medio (2/5)
Data: 24 Maggio 2016
Versione: 1.0.2 - 1 Aprile 2022 🐟 Fools' Day Edition
Autore: mail [AT] meo.bogliolo.name

Diagramma a stati