web-dev-qa-db-fra.com

docker swarm mode plusieurs services même port

Supposons que vous ayez deux services sur votre topologie

  1. API
  2. Interface Web

Les deux supposent fonctionner sur le port 80.

Sur docker swarm lorsque vous créez un service si vous souhaitez y accéder en dehors du cluster, vous devez exposer et mapper le port du service aux nœuds (ports externes). Mais si vous mappez le port 80 au service API par exemple, vous ne pouvez pas mapper le même port pour le service d'interface Web car il sera déjà mappé.

Comment cela peut-il être résolu?

Pour autant que je vois, ce cas d'utilisation n'est pas pris en charge. Même si vous voulez avoir un gros cluster essaim et à travers, tous vos services et applications ne seront pas possibles à cause de ce comportement.

Il me manque quelque chose?

Un modèle pour résoudre ce problème?

19
bitgandtter

Vous pouvez consulter Docker Flow: Proxy à utiliser comme proxy inverse facile à configurer.

MAIS, je crois, comme d'autres commentateurs l'ont souligné, le mode Swarm Docker 1.12 a un problème fondamental avec plusieurs services exposant le même port (comme 80 ou 8080). Cela se résume (je pense) à la magie du routage de maillage - qui est une chose de niveau 4 à quatre, ce qui signifie essentiellement TCP/IP - en d'autres termes, adresse IP + port. Ainsi, les choses deviennent désordonnées lorsque plusieurs services sont répertoriés (par exemple) sur le port 8080. Le routeur maillé fournira avec plaisir le trafic allant au port 8080 à tous les services qui exposent le même port.

Vous POUVEZ isoler les choses les unes des autres en utilisant un réseau de superposition en mode essaim, MAIS le problème survient lorsque vous devez connecter des services au proxy (réseau de superposition) - à ce stade, il semble que les choses se mélangent (et c'est là que je suis) ayant maintenant des difficultés).

La solution que j'ai à ce stade est de laisser les services qui doivent être exposés aux ports Net Use uniques en ce qui concerne le réseau proxy (superposition) (ils n'ont PAS besoin d'être publiés sur l'essaim!), et ensuite utiliser quelque chose comme le Docker Flow Proxy pour gérer le trafic entrant sur le port souhaité.

Échantillon rapide pour vous aider j'ai commencé (en gros basé sur this :

    docker network create --driver overlay proxy
    docker network create --driver overlay my-app
    # App1 exposed port 8081
    docker service create --network proxy --network my-app --name app1 myApp1DockerImage
    docker service create --name proxy \
    -p 80:80 \
    -p 443:443 \
    -p 8080:8080 \
    --network proxy \
    -e MODE=swarm \
    vfarcic/docker-flow-proxy
    #App2 exposes port 8080
    docker service create --network proxy --network my-app --name app2 myApp2DockerImage

Vous configurez ensuite le reverseProxy comme c'est documentation .

REMARQUE: je vois maintenant qu'il y a une nouvelle configuration AUTO disponible - je ne l'ai pas encore essayée.

Résultat final si tout a fonctionné:

  • écoute proxy sur les ports 80, 443 (et 8080 pour ses appels de configuration, alors gardez cela hors du réseau public!)
  • le proxy transmet au service approprié, basé sur service domain ou service path (J'ai eu des problèmes avec service path)
  • les services peuvent communiquer en interne sur un réseau de superposition isolé.
  • les services ne publient pas inutilement les ports dans l'essaim

[EDIT 2016/10/20]

Ignorez tout ce qui précède sur les problèmes avec le même port exposé sur le même réseau de superposition connecté au proxy.

J'ai démoli ma configuration de trous et j'ai recommencé - tout fonctionne comme prévu maintenant: je peux accéder à plusieurs services (différents) sur le port 80, en utilisant différents domaines, via le proxy de flux docker.

En utilisant également la configuration automatique mentionnée - tout fonctionne comme un charme.

6
demaniak

Si vous devez exposer l'API et l'interface Web au public, vous avez deux options. Soit utiliser un port différent pour les services

http://my-site.com       # Web interface
http://my-site.com:8080  # API

ou utilisez un proxy qui écoute le port 80 et transmet les demandes pour corriger le service en fonction du chemin:

http://my-site.com      # Web interface
http://my-site.com/api  # API
5
ronkot

Utilisez différents ports s'ils doivent être exposés publiquement:

docker service create -p 80:80 --name web nginx

puis

docker service create -p 8080:80 --name api myapi

Dans le deuxième exemple, le port public 8080 est mappé au port de conteneur 80. Bien sûr, s'ils n'ont pas besoin d'être exposés au port public, vous pouvez voir les services entre les conteneurs sur le même réseau en utilisant le nom du conteneur et le port de conteneur.

curl http://api:80

trouverait un conteneur nommé api et se connecterait au port 80 à l'aide de la découverte DNS pour les conteneurs sur le même réseau.

3
BMitch