⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

Utiliser le maillage de routage du mode Swarm

Le mode Swarm de Docker Engine facilite la publication de ports pour les services afin de les rendre disponibles aux ressources extérieures au swarm. Tous les nœuds participent à un maillage de routage ingress. Le maillage de routage permet à chaque nœud du swarm d'accepter des connexions sur les ports publiés pour tout service s'exécutant dans le swarm, même s'il n'y a pas de tâche s'exécutant sur le nœud. Le maillage de routage route toutes les requêtes entrantes vers les ports publiés sur les nœuds disponibles vers un conteneur actif.

Pour utiliser le réseau ingress dans le swarm, vous devez avoir les ports suivants ouverts entre les nœuds swarm avant d'activer le mode Swarm :

  • Port 7946 TCP/UDP pour la découverte de réseau de conteneur.
  • Port 4789 UDP (configurable) pour le réseau ingress de conteneur.

Lors de la configuration du réseau dans un Swarm, un soin particulier doit être pris. Consultez le tutoriel pour un aperçu.

Vous devez également ouvrir le port publié entre les nœuds swarm et toute ressource externe, comme un équilibreur de charge externe, qui nécessite l'accès au port.

Vous pouvez également contourner le maillage de routage pour un service donné.

Publier un port pour un service

Utilisez le flag --publish pour publier un port lorsque vous créez un service. target est utilisé pour spécifier le port à l'intérieur du conteneur, et published est utilisé pour spécifier le port à lier sur le maillage de routage. Si vous omettez le port published, un port aléatoire de haut numéro est lié pour chaque tâche de service. Vous devez inspecter la tâche pour déterminer le port.

$ docker service create \
  --name <SERVICE-NAME> \
  --publish published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
  <IMAGE>
Note

La forme plus ancienne de cette syntaxe est une chaîne séparée par des deux-points, où le port publié est en premier et le port cible est en second, comme -p 8080:80. La nouvelle syntaxe est préférée car elle est plus facile à lire et permet plus de flexibilité.

Le <PUBLISHED-PORT> est le port où le swarm rend le service disponible. Si vous l'omettez, un port aléatoire de haut numéro est lié. Le <CONTAINER-PORT> est le port où le conteneur écoute. Ce paramètre est requis.

Par exemple, la commande suivante publie le port 80 dans le conteneur nginx vers le port 8080 pour tout nœud dans le swarm :

$ docker service create \
  --name my-web \
  --publish published=8080,target=80 \
  --replicas 2 \
  nginx

Lorsque vous accédez au port 8080 sur n'importe quel nœud, Docker route votre requête vers un conteneur actif. Sur les nœuds swarm eux-mêmes, le port 8080 peut ne pas être réellement lié, mais le maillage de routage sait comment router le trafic et empêche tout conflit de port de se produire.

Le maillage de routage écoute sur le port publié pour toute adresse IP assignée au nœud. Pour les adresses IP routables extérieurement, le port est disponible depuis l'extérieur de l'hôte. Pour toutes les autres adresses IP, l'accès n'est disponible que depuis l'intérieur de l'hôte.

Image ingress de service

Vous pouvez publier un port pour un service existant en utilisant la commande suivante :

$ docker service update \
  --publish-add published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
  <SERVICE>

Vous pouvez utiliser docker service inspect pour voir le port publié du service. Par exemple :

$ docker service inspect --format="{{json .Endpoint.Spec.Ports}}" my-web

[{"Protocol":"tcp","TargetPort":80,"PublishedPort":8080}]

La sortie montre le <CONTAINER-PORT> (étiqueté TargetPort) des conteneurs et le <PUBLISHED-PORT> (étiqueté PublishedPort) où les nœuds écoutent les requêtes pour le service.

Publier un port pour TCP seulement ou UDP seulement

Par défaut, lorsque vous publiez un port, c'est un port TCP. Vous pouvez spécifiquement publier un port UDP au lieu ou en plus d'un port TCP. Lorsque vous publiez des ports TCP et UDP, si vous omettez le spécificateur de protocole, le port est publié comme port TCP. Si vous utilisez la syntaxe longue (recommandée), définissez la clé protocol à soit tcp soit udp.

TCP seulement

Syntaxe longue :

$ docker service create --name dns-cache \
  --publish published=53,target=53 \
  dns-cache

Syntaxe courte :

$ docker service create --name dns-cache \
  -p 53:53 \
  dns-cache

TCP et UDP

Syntaxe longue :

$ docker service create --name dns-cache \
  --publish published=53,target=53 \
  --publish published=53,target=53,protocol=udp \
  dns-cache

Syntaxe courte :

$ docker service create --name dns-cache \
  -p 53:53 \
  -p 53:53/udp \
  dns-cache

UDP seulement

Syntaxe longue :

$ docker service create --name dns-cache \
  --publish published=53,target=53,protocol=udp \
  dns-cache

Syntaxe courte :

$ docker service create --name dns-cache \
  -p 53:53/udp \
  dns-cache

Contourner le maillage de routage

Par défaut, les services swarm qui publient des ports le font en utilisant le maillage de routage. Lorsque vous vous connectez à un port publié sur n'importe quel nœud swarm (qu'il exécute un service donné ou non), vous êtes redirigé vers un travailleur qui exécute ce service, de manière transparente. Effectivement, Docker agit comme un équilibreur de charge pour vos services swarm.

Vous pouvez contourner le maillage de routage, de sorte que lorsque vous accédez au port lié sur un nœud donné, vous accédez toujours à l'instance du service s'exécutant sur ce nœud. Ceci est appelé mode host. Il y a quelques points à garder à l'esprit.

  • Si vous accédez à un nœud qui n'exécute pas de tâche de service, le service n'écoute pas sur ce port. Il est possible que rien n'écoute, ou qu'une application complètement différente écoute.

  • Si vous vous attendez à exécuter plusieurs tâches de service sur chaque nœud (comme lorsque vous avez 5 nœuds mais exécutez 10 répliques), vous ne pouvez pas spécifier un port cible statique. Soit permettez à Docker d'assigner un port aléatoire de haut numéro (en omettant le published), soit assurez-vous qu'une seule instance du service s'exécute sur un nœud donné, en utilisant un service global plutôt qu'un service répliqué, ou en utilisant des contraintes de placement.

Pour contourner le maillage de routage, vous devez utiliser le service long --publish et définir mode à host. Si vous omettez la clé mode ou la définissez à ingress, le maillage de routage est utilisé. La commande suivante crée un service global utilisant le mode host et contournant le maillage de routage.

$ docker service create --name dns-cache \
  --publish published=53,target=53,protocol=udp,mode=host \
  --mode global \
  dns-cache

Configurer un équilibreur de charge externe

Vous pouvez configurer un équilibreur de charge externe pour les services swarm, soit en combinaison avec le maillage de routage ou sans utiliser le maillage de routage du tout.

Utiliser le maillage de routage

Vous pouvez configurer un équilibreur de charge externe pour router les requêtes à un service swarm. Par exemple, vous pourriez configurer HAProxy pour équilibrer les requêtes vers un service nginx publié sur le port 8080.

Ingress with external load balancer image

Dans ce cas, le port 8080 doit être ouvert entre le load balancer et les nœuds dans le swarm. Les nœuds swarm peuvent résider sur un réseau privé qui est accessible au serveur proxy, mais qui n'est pas accessible publiquement.

Vous pouvez configurer le load balancer pour équilibrer les requêtes entre chaque nœud dans le swarm même s'il n'y a pas de tâches planifiées sur le nœud. Par exemple, vous pourriez avoir la configuration suivante HAProxy dans /etc/haproxy/haproxy.cfg:

global
        log /dev/log    local0
        log /dev/log    local1 notice
...snip...

# Configure HAProxy to listen on port 80
frontend http_front
   bind *:80
   stats uri /haproxy?stats
   default_backend http_back

# Configure HAProxy to route requests to swarm nodes on port 8080
backend http_back
   balance roundrobin
   server node1 192.168.99.100:8080 check
   server node2 192.168.99.101:8080 check
   server node3 192.168.99.102:8080 check

Lorsque vous accédez à l'équilibreur de charge HAProxy sur le port 80, il transfère les requêtes à nœuds dans le swarm. Le maillage de routage swarm route la requête à une tâche active. Si, pour quelque raison que ce soit, le planificateur swarm déploie des tâches vers différents nœuds, vous n'avez pas besoin de reconfigurer le load balancer.

Vous pouvez configurer n'importe quel type d'équilibreur de charge pour router les requêtes à nœuds swarm. Pour en savoir plus sur HAProxy, voir la documentation HAProxy.

Sans le maillage de routage

Pour utiliser un équilibreur de charge externe sans le maillage de routage, définissez --endpoint-mode à dnsrr au lieu de la valeur par défaut de vip. Dans ce cas, il n'y a pas un seul IP virtuel. Au lieu de cela, Docker configure des entrées DNS pour le service tel que une requête DNS pour le nom du service renvoie une liste d'IP, et le client se connecte directement à un de ces.

Vous ne pouvez pas utiliser --endpoint-mode dnsrr avec --publish mode=ingress. Vous devez exécuter votre propre load balancer devant le service. Une requête DNS pour le nom du service sur le Docker host renvoie une liste d'IP pour les nœuds exécutant le service. Configurez votre load balancer pour consommer cette liste et équilibrer le trafic entre les nœuds. Voir Configurer la découverte de service.

En savoir plus