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>
NoteLa 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.


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.


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.