2 juillet 2014

Docker - Réseau et Partage de fichiers - Commandes Docker


Nous allons voir comment paramétrer les ports réseaux et le partage de fichiers entre les conteneurs Docker et la machine hôte.

Pré-requis

Il faut avoir lu l'article suivant avant de lire celui-ci : Docker - Premiers pas

Partage de fichiers

Le montage de volumes disques permet à un conteneur d'utiliser le contenu d'un répertoire de la machine hôte : le conteneur a ainsi des fichiers lors de son premier démarrage et ces fichiers sont stockés sur la machine hôte donc ils ne seront pas effacés lors de l'arrêt du conteneur.


Le partage de fichiers nécessite de :
  • Créer le répertoire de partage sur la machine hôte
  • Spécifier le répertoire de partage au sein du conteneur
    • Ajouter la ligne suivante dans le fichier Dockerfile pour indiquer quel répertoire du conteneur sera partagé :
    • VOLUME ["[répertoire du conteneur]"]
  • Au lancement du conteneur : indiquer le mapping entre le répertoire de partage du conteneur et de la machine hôte
    • Dans la commande docker run, ajouter l'option -v [répertoire de la machine hôte]:[répertoire du conteneur] pour mapper le répertoire de la machine hôte avec celui du conteneur
    • docker run -v [host directory]:[container directory]
    • ajouter :ro à la fin pour activer la lecture seule :
    • docker run -v [host directory]:[container directory]:ro

Réseau

L'interfaçage réseau permet à un conteneur de communiquer avec l'extérieur et/ou avec les autres conteneurs.

Pour définir l'interfaçage réseau, il est nécessaire de :
  • exposer le port réseau du conteneur :
    • soit via le fichier Dockerfile de l'image
    • soit via l'option --expose de la commande docker run
  • si nous voulons que le port réseau du conteneur soit accessible à l'extérieur de la machine hôte :
    • nous devons mapper le port réseau du conteneur avec celui de la machine hôte
      via l'option -p de la commande docker run
  • si nous voulons que le conteneur communique avec un autre conteneur :
    • nous devons lier le premier conteneur avec le second conteneur
      via l'option --link de la commande docker run

Exposer le port réseau d'un conteneur

Exposer le port réseau d'un conteneur via le fichier Dockerfile

Dans le fichier Dockerfile, ajouter la ligne suivante pour exposer le port réseau des conteneurs de l'image :
EXPOSE <port conteneur]
, avec :
  • [port conteneur] : le numéro de port du conteneur exposé à Docker

Exemple

On expose le port 80 du conteneur :
EXPOSE 80

Exposer le port réseau d'un conteneur via la commande docker run

L'option --expose de la commande docker run permet d'exposer un port d'un conteneur :
    --expose [port conteneur]

Communication d'un conteneur avec la machine hôte et l'extérieur

Définir le mapping entre le port du conteneur et le port de la machine hôte

La commande docker run -p permet de définir la redirection des ports réseaux exposés :
    -p [port hôte]:[port conteneur]
  • ou
  • -p [IP]:[port hôte]:[port conteneur]
  • ou
  • -p [IP]:[port hôte]:[port conteneur]/[protocol]
, avec :
  • [IP] : Adresse IP (non obligatoire)
  • [port hôte] : Port de la machine hôte
  • [port conteneur] : Port du conteneur
  • [protocol] : Protocol réseau (non obligatoire) (exemple : tcp ou udp)
Il est possible de définir plusieurs mapping de ports à l'aide de plusieurs options -p dans la même commande docker run.

Mapper automatiquement tous les ports exposés d'un conteneur avec ceux de la machine hôte

L'option -P de docker run permet de mapper chacun des ports exposés d'un conteneur sur un des ports de la machine hôte sur une plage comprise entre 49000 et 49900.

Il faut alors lancer la commande docker ps pour voir sur quels ports de la machine hôte sont mappés les ports du conteneur.

Communication entre deux conteneurs

Pour qu'un conteneur puisse communiquer avec un autre conteneur, il est nécessaire que ce conteneur connaisse l'adresse IP de l'autre conteneur.

Pour cela, docker fournit des variables d'environnement contenant notamment l'adresse IP du conteneur lié et les numéros de ports.

Docker fournit également au deuxième conteneur les variables d'environnement qui ont été déclarés pour le premier conteneur dans le fichier Dockerfile ou via la commande docker run à l'aide des options -e.

Ces variables d'environnements sont préfixés par le nom de l'alias qui été formaté en majuscules.
Exemple : pour un alias tomcat, les variables d'environnement commencent par TOMCAT_.

Lier deux conteneurs

Nous indiquons qu'un conteneur est lié à un autre conteneur en cours d'exécution :
    --link=[nom conteneur lié]:[alias du conteneur]
, avec :
  • [nom conteneur lié] : nom du conteneur lié qui doit être en cours d'exécution
    • ce nom de conteneur doit avoir été défini lors du lancement de ce conteneur
      via l'option --name de la commande docker run
  • [alias lien] : alias du lien vers le conteneur
Le conteneur lié doit être en cours d'exécution et doit donc être dans la liste des conteneurs en cours d'exécution via la commande docker ps.
Le nom d'alias sert au nommage des variables d'environnement.

Exemple

Nous prenons l'exemple de deux conteneurs pour avoir l'organisation suivante :
Le conteneur 2 est lié au conteneur 1

Le conteneur 1 expose le port 111.

Nous démarrons le premier conteneur :
docker run -d --name conteneur1 --expose 111 demo/image1

Nous démarrons un second conteneur en la liant avec le premier conteneur :
docker run -d --name conteneur2 -P --link conteneur1:conteneur1 demo/image2

Docker ajoute dans le conteneur 2 des variables d'environnement concernant le conteneur 1 pour chaque port exposé par le conteneur 1 :

  • pour le port 111 du conteneur 1 :
    • CONTENEUR1_PORT_111_TCP_ADDR=172.17.0.2
    • CONTENEUR1_PORT_111_TCP_PORT=111
    • CONTENEUR1_PORT_111_TCP_PROTO=tcp

Nous pouvons ainsi récupérer l'adresse IP du conteneur lié pour que le conteneur 2 puisse communiquer avec le conteneur 1.

Exemple: si le conteneur 1 expose le port 22 avec un serveur SSH, le conteneur 2 pourra se connecter en SSH sur ce premier conteneur via le port 22 et en utilisant la variable d'environnement contenant l'adresse IP "CONTENEUR1_PORT_22_TCP_ADDR".

Attention: il n'est possible de communiquer qu'avec les ports exposés du premier conteneur.

Changer les paramètres spécifiés lors de l'exécution du conteneur

Il n'y a pas de commande docker pour modifier les informations spécifiées via la commande docker run du conteneur lors de l'exécution de celui-ci, que ce soit le mapping des ports réseau ou des fichiers.

Il faut alors commiter et redémarrer le conteneur en spécifiant le nouveau mapping de ports ou de fichiers. Lors du commit, il faut indiquer un nom d'image d'export temporaire qui sera utilisé pour redémarrer le conteneur à partir de cette image. Il ne faut pas utiliser le nom de l'image initial qui avait servi lors du premier démarrage du conteneur.

docker commit [identifiant] [nom image temporaire]
docker run (...) [nom image temporaire] (...)

Conclusion

Maintenant que nous connaissons les commandes Docker pour activer le partage de fichiers et définir l'interfaçage des ports réseau, nous les testerons dans la partie suivante en prenant comme exemple un conteneur contenant un serveur SSH :

Références