Docker 1.13 introduce una funzionalità tanto attesa chiamata compose-file support, che ci permette di definire i nostri container con un semplice file di configurazione invece di un singolo lungo comando. Se dai un'occhiata ai nostri precedenti post del blog "MySQL su Docker", abbiamo utilizzato più lunghe righe di comando per eseguire contenitori e servizi. Utilizzando compose-file, i contenitori possono essere facilmente specificati per la distribuzione. Ciò riduce il rischio di errore umano poiché non è necessario ricordare comandi lunghi con parametri multipli.
In questo post del blog, ti mostreremo come utilizzare compose-file utilizzando semplici esempi sulle implementazioni MySQL. Supponiamo che Docker Engine 1.13 sia installato su 3 host fisici e che la modalità Swarm sia configurata su tutti gli host.
Introduzione a Compose-File
Nel Compose-file, specifichi tutto in formato YAML invece di cercare di ricordare tutti gli argomenti che dobbiamo passare ai comandi Docker. Qui puoi definire servizi, reti e volumi. La definizione verrà ripresa da Docker ed è molto simile al passaggio dei parametri della riga di comando al comando "docker run|network|volume".
Come introduzione, implementeremo un semplice contenitore MySQL autonomo. Prima di iniziare a scrivere un file Compose, devi prima conoscere il comando di esecuzione. Tratto dalla nostra prima serie di blog MySQL su Docker, componiamo il seguente comando "docker run":
$ docker run --detach \
--name=test-mysql \
--publish 6603:3306 \
--env="MYSQL_ROOT_PASSWORD=mypassword" \
-v /storage/docker/mysql-datadir:/var/lib/mysql \
mysql
Il comando docker-compose cercherà un file predefinito chiamato "docker-compose.yml" nella directory corrente. Quindi, creiamo prima le directory richieste in anticipo:
$ mkdir -p ~/compose-files/mysql/single
$ mkdir -p /storage/docker/mysql-datadir
$ cd ~/compose-files/mysql/single
In YAML, ecco cosa dovrebbe essere scritto:
version: '2'
services:
mysql:
image: mysql
container_name: test-mysql
ports:
- 6603:3306
environment:
MYSQL_ROOT_PASSWORD: "mypassword"
volumes:
- /storage/docker/mysql-datadir:/var/lib/mysql
Salva il contenuto di cui sopra in "~/compose-files/mysql/single/docker-compose.yml". Assicurati di essere nella directory corrente ~/compose-files/mysql/single, quindi avviala eseguendo il comando seguente:
$ docker-compose up -d
WARNING: The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use `docker stack deploy`.
Creating test-mysql
Verifica se il contenitore è in esecuzione in modalità scollegata:
[[email protected] single]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
379d5c15ef44 mysql "docker-entrypoint..." 8 minutes ago Up 8 minutes 0.0.0.0:6603->3306/tcp test-mysql
Congratulazioni! Ora abbiamo un contenitore MySQL in esecuzione con un solo comando.
Distribuzione di uno stack
Compose-file semplifica le cose, ci fornisce una visione più chiara di come dovrebbe apparire l'infrastruttura. Creiamo uno stack di contenitori che consiste in un sito Web in esecuzione su Drupal, utilizzando un'istanza MySQL in una rete dedicata e collegarli insieme.
Simile a sopra, diamo un'occhiata alla versione della riga di comando nell'ordine corretto per creare questo stack:
$ docker volume create mysql_data
$ docker network create drupal_mysql_net --driver=bridge
$ docker run -d --name=mysql-drupal --restart=always -v mysql_data:/var/lib/mysql --net=drupal_mysql_net -e MYSQL_ROOT_PASSWORD="mypassword" -e MYSQL_DATABASE="drupal" mysql
$ docker run -d --name=drupal -p 8080:80 --restart=always -v /var/www/html/modules -v /var/www/html/profiles -v /var/www/html/themes -v /var/www/html/sites --link mysql:mysql --net=drupal_mysql_net drupal
Per iniziare a comporre, creiamo prima una directory per il nostro nuovo stack:
$ mkdir -p ~/compose-files/drupal-mysql
$ cd ~/compose-files/drupal-mysql
Quindi, crea il contenuto di scrittura di docker-compose.yml come di seguito:
version: '2'
services:
mysql:
image: mysql
container_name: mysql-drupal
environment:
MYSQL_ROOT_PASSWORD: "mypassword"
MYSQL_DATABASE: "drupal"
volumes:
- mysql_data:/var/lib/mysql
restart: always
networks:
- drupal_mysql_net
drupal:
depends_on:
- mysql
image: drupal
container_name: drupal
ports:
- 8080:80
volumes:
- /var/www/html/modules
- /var/www/html/profiles
- /var/www/html/themes
- /var/www/html/sites
links:
- mysql:mysql
restart: always
networks:
- drupal_mysql_net
volumes:
mysql_data:
networks:
drupal_mysql_net:
driver: bridge
Accendili:
$ docker-compose up -d
..
Creating network "drupalmysql_drupal_mysql_net" with driver "bridge"
Creating volume "drupalmysql_mysql_data" with default driver
Pulling drupal (drupal:latest)...
..
Creating mysql-drupal
Creating drupal
Docker eseguirà la distribuzione come segue:
- Crea rete
- Crea volume
- Estrarre immagini
- Crea mysql-drupal (poiché il contenitore "drupal" dipende da esso)
- Crea il contenitore drupal
A questo punto, la nostra architettura può essere illustrata come segue:
Possiamo quindi specificare "mysql" come host MySQL nella pagina della procedura guidata di installazione poiché entrambi i contenitori sono collegati tra loro. Questo è tutto. Per eliminarli, esegui semplicemente il seguente comando nella stessa directory:
$ docker-compose down
I contenitori corrispondenti verranno chiusi e rimossi di conseguenza. Tieni presente che il comando docker-compose è associato al singolo host fisico che esegue Docker. Per funzionare su più host fisici su Swarm, deve essere trattato in modo diverso utilizzando il comando "docker stack". Lo spiegheremo nella prossima sezione.
Multiplenines MySQL su Docker:come containerizzare il tuo databaseScopri tutto ciò che devi capire quando consideri di eseguire un servizio MySQL oltre alla virtualizzazione del container DockerScarica il white paperComporre una pila attraverso lo sciame
Innanzitutto, assicurati che il motore Docker sia in esecuzione su v1.13 e che la modalità Swarm sia abilitata e nello stato pronto:
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
8n8t3r4fvm8u01yhli9522xi9 * docker1.local Ready Active Reachable
o1dfbbnmhn1qayjry32bpl2by docker2.local Ready Active Reachable
tng5r9ax0ve855pih1110amv8 docker3.local Ready Active Leader
Per utilizzare la funzione stack per la modalità Docker Swarm, dobbiamo utilizzare il formato Docker Compose versione 3. Distribuiremo una configurazione simile a quella sopra, a parte una configurazione Galera a 3 nodi come backend MySQL. L'abbiamo già spiegato in dettaglio in questo post del blog.
Innanzitutto, crea una directory per il nostro nuovo stack:
$ mkdir -p ~/compose-files/drupal-galera
$ cd ~/compose-files/drupal-galera
Quindi aggiungi le seguenti righe in "docker-compose.yml":
version: '3'
services:
galera:
deploy:
replicas: 3
restart_policy:
condition: on-failure
delay: 30s
max_attempts: 3
window: 60s
update_config:
parallelism: 1
delay: 10s
max_failure_ratio: 0.3
image: severalnines/pxc56
environment:
MYSQL_ROOT_PASSWORD: "mypassword"
CLUSTER_NAME: "my_galera"
XTRABACKUP_PASSWORD: "mypassword"
DISCOVERY_SERVICE: '192.168.55.111:2379,192.168.55.112:2379,192.168.55.207:2379'
MYSQL_DATABASE: 'drupal'
networks:
- galera_net
drupal:
depends_on:
- galera
deploy:
replicas: 1
image: drupal
ports:
- 8080:80
volumes:
- drupal_modules:/var/www/html/modules
- drupal_profile:/var/www/html/profiles
- drupal_theme:/var/www/html/themes
- drupal_sites:/var/www/html/sites
networks:
- galera_net
volumes:
drupal_modules:
drupal_profile:
drupal_theme:
drupal_sites:
networks:
galera_net:
driver: overlay
Nota che l'immagine Galera che abbiamo utilizzato (diverselnines/pxc56) richiede un cluster etcd in esecuzione installato su ciascuno degli host fisici Docker. Fare riferimento a questo post del blog sui passaggi prerequisiti.
Una delle parti importanti nel nostro compose-file è il parametro max_attempts nella sezione restart_policy. Dobbiamo specificare un limite rigido al numero di riavvii in caso di guasto. Ciò renderà il processo di distribuzione più sicuro perché, per impostazione predefinita, lo scheduler di Swarm non si arrenderà mai nel tentativo di riavviare i container. Se ciò accade, il ciclo del processo riempirà lo spazio su disco dell'host fisico con contenitori inutilizzabili quando lo scheduler non è in grado di portare i contenitori allo stato desiderato. Questo è un approccio comune quando si gestiscono servizi con stato come MySQL. È meglio abbatterli del tutto piuttosto che farli funzionare in uno stato incoerente.
Per avviarli tutti, basta eseguire il seguente comando nella stessa directory in cui risiede docker-compose.yml:
$ docker stack deploy --compose-file=docker-compose.yml my_drupal
Verifica che lo stack sia stato creato con 2 servizi (drupal e galera):
$ docker stack ls
NAME SERVICES
my_drupal 2
Possiamo anche elencare le attività correnti nello stack creato. Il risultato è una versione combinata dei comandi "docker service ps my_drupal_galera" e "docker service ps my_drupal_drupal":
$ docker stack ps my_drupal
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
609jj9ji6rxt my_drupal_galera.1 severalnines/pxc56:latest docker3.local Running Running 7 minutes ago
z8mcqzf29lbq my_drupal_drupal.1 drupal:latest docker1.local Running Running 24 minutes ago
skblp9mfbbzi my_drupal_galera.2 severalnines/pxc56:latest docker1.local Running Running 10 minutes ago
cidn9kb0d62u my_drupal_galera.3 severalnines/pxc56:latest docker2.local Running Running 7 minutes ago
Una volta ottenuto lo STATO CORRENTE come RUNNING, possiamo avviare l'installazione di Drupal connettendoci a qualsiasi indirizzo IP o nome host dell'host Docker sulla porta 8080, poiché in questo caso abbiamo utilizzato docker3 (sebbene il contenitore drupal sia distribuito su docker1), http ://192.168.55.113:8080/. Procedi con l'installazione e specifica 'galera' come host MySQL e 'drupal' come nome del database (come definito nel compose-file nella variabile d'ambiente MYSQL_DATABASE):
Questo è tutto. La distribuzione dello stack è stata semplificata utilizzando Compose-file. A questo punto, la nostra architettura è simile a questa:
Infine, per rimuovere lo stack, basta eseguire il seguente comando:
$ docker stack rm my_drupal
Removing service my_drupal_galera
Removing service my_drupal_drupal
Removing network my_drupal_galera_net
L'uso di compose-file può farti risparmiare tempo e ridurre il rischio di errore umano, rispetto a quando si lavora con lunghe righe di comando. Questo è uno strumento perfetto da padroneggiare prima di lavorare con applicazioni Docker multi-container, gestire più ambienti di distribuzione (ad es. dev, test, staging, pre-prod, prod) e gestire servizi molto più complessi, proprio come MySQL Galera Cluster. Buona containerizzazione
!