23 mars 2015

Docker Compose - Gérer plusieurs conteneurs en une commande


Docker Compose est l'intégration de Fig dans Docker.

L'objectif est de gérer en une commande docker compose le build, le démarrage et l'arrêt de plusieurs images et conteneurs.

Il s'agit de remplacer l'usage des commandes docker build et docker run par un fichier YAML docker-compose.yml qui décrit les images à construire, les paramètres de démarrage des conteneurs ainsi que les liens entre ces conteneurs.

Pour cela, le fichier docker-compose.yml décrit :
  • si le conteneur est issu d'une image existante ou s'il est nécessaire d'en construire une nouvelle à partir d'un fichier Dockerfile
  • les arguments qui étaient spécifiées lors du démarrage du conteneur via la commande docker run :
    • mapping des ports entre la machine hôte et le conteneur
    • le montage des volumes entre la machine hôte et le conteneur
    • les liens entre les conteneurs
La commande docker-compose up effectue ainsi la création des images et le démarrage des différents conteneurs d'après ce qui est décrit dans le fichier docker-compose.yml

Installation

Pour installer Docker Compose (documentation) :
curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
Il est possible d'avoir l'auto-complétion sur la commande docker-compose (documentation) :
 curl -L https://raw.githubusercontent.com/docker/compose/1.1.0/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose

Utilisation de Docker Compose

La commande docker-compose permet de builder les images et de démarrer tous les conteneurs en une seule fois. Elle permet également d'arrêter tous les conteneurs d'un seul coup.
  • Build des images / Démarrage des conteneurs:
  • docker-compose up
    • Par défaut le lancement des conteneurs se fait en avant-plan, c'est à dire que la commande docker-compose up ne rend pas la main et les conteneurs seront arrêtés et supprimés si on arrête cette commande.
  • Pour démarrer les conteneurs en tâche de fond:
  • docker-compose up -d
  • Arrêt des conteneurs
  • docker-compose stop
  • Démarrer les conteneurs
  • docker-compose start
  • Lister les conteneurs
  • docker-compose ps
  • Supprimer les conteneurs
  • docker-compose rm
  • Affichage des logs des conteneurs
  • docker-compose logs

Fichier : docker-compose.yml

Le fichier YAML docker-compose.yml contient une entrée par conteneur et pour chaque conteneur les propriétés qui pourraient être décrites avec la commande docker run.

Exemple

Le fichier suivant présente la déclaration pour trois conteneurs web, back et db:
web:
  ports:
    - 80:8080
  links:
    - back

back:
  expose:
    - 8080
  links:
    - db

db:
  expose:
    - 5432
  volumes:
    - /path/data:/data

Documentation

  • image: nom de l'image existante à utiliser
  • image: [nom tag image]
  • build: chemin d'accès au fichier Dockerfile pour construire l'image
  • build: [chemin Dockerfile]
    
  • command: Commande Shell lancée au démarrage du conteneur et qui surcharge celle de l'image
  • command: [commande shell]
    
  • links: lien entre le conteneur avec d'autres conteneurs
  • links:
      - [conteneur cible]
      - [conteneur cible]:[alias]
    
    • Le fichier /etc/hosts contient alors l'adresse IP du conteneur lié :
    • [ADRESSE IP] [nom conteneur ou alias]
      
    • Des variables d'environnement sont également ajoutées:
      • [alias]_PORT_[port]_[protocole]_ADDR: Adresse IP du conteneur cible
      • [alias]_PORT_[port]_[protocole]: URL complète vers le conteneur cible pour le port et le protocole indiqué et qui ont été exposés par le conteneur cible
      • [alias]_NAME: Nom du conteneur cible
      • Voir documentation: https://docs.docker.com/compose/env/
  • ports: mappings de ports entre la machine hôte et le conteneur
  • ports:
      - "[port machine hôte]":"[port conteneur]"
    
  • expose: ports exposés par le conteneur aux autres conteneurs et non pas à la machine hôte
  • expose:
      - "[port conteneur]"
    
  • volumes: volumes montés dans le conteneur sur les répertoires de la machine hôte (ro indique que les fichiers de la machine hôte sont en lecture seule dans le conteneur)
  • volumes:
      - [répertoire machine hôte]:[répertoire conteneur]
      - [répertoire machine hôte]:[répertoire conteneur]:ro
  • environment: variables d'environnement du conteneur
  • environment:
      - [VARIABLE ENVIRONNEMENT]=[valeur]
    
  • env_file: variables d'environnement du conteneur décrites dans un fichier
  • env_files:
      - [chemin vers fichier environnement]
    
    • Ce fichier d'environnement contient les variables d'environnement :
    • [VARIABLE ENVIRONNEMENT]=[valeur]
      
D'autres propriétés peuvent être définies dans le fichier docker-compose.yml.
La documentation de référence est disponible :

Scalabilité

Il est possible de faire de la scalabilité sur les conteneurs gérés par Docker Compose via la commande :
docker-compose scale [nom conteneur]=[nombre d'instances]
, avec :
  • [nom conteneur]: le nom du conteneur défini dans le fichier docker-compose.yml
  • [nombre d'instances]: le nombre d'instance de ce conteneur
Les contraintes sont les suivantes :
  • le conteneur à "scaler" doit être en cours de fonctionnement
    • c'est pourquoi il faut avoir démarrer les conteneurs via la commande docker-compose up -d avec l'option -d pour que les conteneurs soient lancés en tâche de fond
  • le port de la machine hôte ne doit pas être défini dans le mapping de ports du conteneur à scaler afin que Docker attribue un numéro de port aléatoire aux conteneurs
Exemple: pour le fichier docker-compose.yml d'exemple ci-dessus :
  • Si nous voulons avoir deux instances du conteneur front et deux instances du conteneur back:
  • docker-compose scale front=2 back=2
    
Les numéros de port sur la machine hôte pour les nouveaux conteneurs sont aléatoires. Il faut prévoir un système pour répartir les requêtes sur ces nouveaux ports.

Références