virli/tutorial/2/compose.md
2017-09-22 10:27:49 +02:00

6.1 KiB

\newpage

Compose

Avec notre conteneur utilisant supervisor, nous ne respectons pas cette dernière bonne pratique d'un seul processus par conteneur :-(

L'intérêt est de permettre à chaque conteneur d'effectuer une tâche simple et générique, de manière à pouvoir être réutilisé pour d'autres projets dans le futur. Par exemple, notre conteneur InfluxDB pourra être utilisé pour stocker des relevés de métriques d'autres systèmes ou des logs. Chronograf peut être connecté à d'autres serveurs afin de corréler les métriques, ...

Séparer le Dockerfile

Commençons par séparer notre Dockerfile en deux : dans une partie nous allons garder la partie InfluxDB, de l'autre la partie Chronograf.

Il va vous falloir créer deux dossiers distincts, il en faut un par Dockerfile : réutilisez l'image influxdb créée précédemment et créez le dossier pour l'image chronograf.

\vspace{1em}

Pour tester la bonne marche de vos conteneurs, vous pouvez le lancer votre conteneur chronograf avec la commande suivante (en considérant que votre conteneur influxdb de la première partie est toujours lancé).

docker run --rm --link YOUR_INFLUX_CNTR_NAME:influxdb chronograf

Remplacez YOUR_INFLUX_CNTR_NAME par le nom du conteneur qui fait tourner votre influxdb. En créant ce lien, chronograf sera capable de contacter une machine nommée influxdb (indiqué par la partie du lien après les :).

Visualiser les données dans chronograf

Avant d'arrêter telegraf et nos conteneurs pour passer à une nouvelle étape, prenez le temps d'afficher les données que vous avez collecté depuis le début du TP.

Après avoir ajouté le serveur (en remplaçant localhost proposé par défaut par influxdb issue du link), ajouter deux visualisations avec les requêtes suivantes :

SELECT used, available, cached FROM mem WHERE tmpltime()
SELECT mean(usage_idle) FROM cpu WHERE tmpltime() GROUP BY time(20s), cpu

Automatiser la construction et le lancement

Commencez par lancer tous vos conteneurs à la main pour voir les étapes que vous allez devoir automatiser.

Au lieu de faire un script pour construire et lancer tous vos conteneurs, définissez à la racine de votre projet un fichier docker-compose.yml qui contiendra les méthodes de construction et les paramètres d'exécution.

version: '2'
services:
  influxdb:
    ...
  chronograf:
    build: grafana/
    image: nginx
    ports:
      - "3000:3000"
    volumes:
      - ./:/tmp/toto
    links:
     - influxdb

Ce fichier est un condensé des options que vous passez habituellement au docker run.

version

Notez toutefois la présence d'une ligne version ; il ne s'agit pas de la version de vos conteneurs, mais de la version du format de fichier docker-compose qui sera utilisé. Sans indication de version, la version originale sera utilisée.

services

Cette section énumère la liste des services (ou conteneurs) qui seront gérés par docker-compose.

Il peuvent dépendre d'une image à construire localement, dans ce cas ils auront un fils build. Ou ils peuvent utiliser une image déjà existante, dans ce cas ils auront un fils image.

Les autres fils sont les paramètres classiques que l'on va passer à docker run.

volumes

Cette section est le pendant de la commandes docker volume.

L'idée est d'éviter de créer des Data Volume Container qui ont une partie de système de fichiers inutile, et de ne garder que l'idée d'emplacement servant pour du stockage persistant.

On les déclare simplement en leur donnant un nom et un driver comme suit :

volumes:
  mysql-data:
    driver: local

Leur utilisation est identique à un Data Volume Container : on référence le nom ainsi que l'emplacement à partager :

[...]
  mysql:
    [...]
    volumes:
	  - mysql-data:/var/lib/mysql

network

Cette section est le pendant de la commandes docker network.

Par défaut, Docker relie tous les conteneurs sur un bridge et fait du NAT pour que les conteneur puisse accéder à l'Internet. Mais ce n'est pas le seul mode possible !

De la même manière que pour les volumes, cette section déclare les réseaux qui pourront être utilisés par les services. On pourrait donc avoir :

networks:
  knotdns-slave-net:
    driver: bridge

Driver host

Le driver host réutilise la pile réseau de la machine hôte. Le conteneur pourra donc directement accéder au réseau, sans NAT et sans redirection de port. Les ports alloués par le conteneur ne devront pas entrer en conflits avec les ports ouverts par la machine hôte.

Driver null

Avec le driver null, la pile réseau est recréée et aucune interface (autre que l'interface de loopback) n'est présente. Le conteneur ne peut donc pas accéder à Internet, ni aux autres conteneur, ...

Lorsque l'on exécute un conteneur qui n'a pas besoin d'accéder au réseau, c'est le driver à utiliser. Par exemple pour un conteneur dont le but est de vérifier un backup de base de données.

Driver bridge

Le driver bridge crée un nouveau bridge qui sera partagée entre tous les conteneurs qui la référencent.

Avec cette configuration, les conteneurs ont accès à une résolution DNS des noms de conteneurs qui partagent leur bridge. Ainsi, sans avoir à utiliser la fonctionnalité de link au moment du run, il est possible de se retrouvé lié, même après que l'on ait démarré. La résolution se fera dynamiquement.

Utiliser le docker-compose.yml

Consultez http://docs.docker.com/compose/compose-file/ pour une liste exhaustive des options que vous pouvez utiliser.

Une fois que votre docker-compose.yml est prêt, lancez tout d'abord docker-compose build pour commencer la phase de build de tous les conteneurs listés dans le fichier.

Une fois le build terminé, vous pouvez lancer la commande suivante et admirer le résultat :

docker-compose up

Encore une fois, testez la bonne connexion entre chronograf (accessible sur http://localhost:10000) et influxdb.

Rendu

Pour cette partie, vous devrez rendre la dernière itération de votre docker-compose.yml.