2
votes

Comment communiquer entre deux conteneurs à l'aide de docker

Je rencontre un problème pour accéder à une route de conteneur dans un autre conteneur. Par exemple, j'ai deux micro-services appelés service utilisateur et api-gateway . J'essaie d'accéder à la route service utilisateur dans api-gateway .

Mon fichier api-gateway pourrait être comme ci-dessous

 version: '3'
 services:
   api-gateway:
     container_name: api-gateway
     build: './api-gateway'
     ports:
       - "8080:8080"
     links:
       - user-service
   user-service:
     build: ./user-service
     container_name: user-service
     ports:
     - "8093:8093"

api-gateway fonctionne sur le port 8080

Mon fichier service utilisateur pourrait être comme ci-dessous

 app.post('/admin/register', function (req, res) {
  res.send('POST request')
 })

lorsque j'accède à la route via api-gateway strong> avec le port 8080 je n'ai pas pu appeler la route mais quand j'ai essayé d'accéder avec le port 8093 je peux voir le résultat.

Mon docker-compose strong > le fichier pourrait être comme ci-dessous

  const userServiceProxy = httpProxy(http://localhost:8093);
  this.app.post('/admin/register', async(req, res) => {

      userServiceProxy(req, res);

  });

Toute aide serait grandement appréciée, merci d'avance!


2 commentaires

Qu'est-ce que l'objet httpProxy ?


lorsque l'utilisateur a tenté d'accéder à la route avec le port 8080 , qui redirige généralement vers la route vers le service utilisateur qui s'exécute sur le port 8093 . Au fait, j'ai utilisé express-http-proxy


4 Réponses :


5
votes

localhost fait référence à l'hôte local à l'intérieur du conteneur, pas au système hôte.

Utilisez Docker Networks et remplacez localhost par le nom du service tel que api-gateway .

Si les conteneurs sont dans le même réseau, l'adresse http: // api-gateway: 8093 devrait fonctionner.

Une autre méthode consiste à exécuter le conteneur sur le mode réseau host . C'est moins d'isolement mais alors l'adresse localhost fonctionne car le conteneur est maintenant en cours d'exécution sur l'interface du docker deamon


2 commentaires

Merci pour votre réponse @Wie! Pouvez-vous me suggérer comment utiliser Docker Networks ?


désolé j'étais parti à quelques jours, @shaped a raison avec son exemple.



0
votes

Il existe également une option moins connue pour connecter deux conteneurs ou plus ensemble:

➜  docker-pod-test docker-compose up
Creating docker-pod-test_test1_1 ... done
Creating docker-pod-test_test2_1 ... done
Attaching to docker-pod-test_test1_1, docker-pod-test_test2_1
test2_1  | nc: bind: Address in use
docker-pod-test_test2_1 exited with code 1

Ceci est similaire à la mise en réseau interne des pods Kubernetes - les conteneurs liés de cette manière partagent la même adresse interne (le les ports publiés sont visibles sur localhost et peuvent entrer en collision). En conséquence, la configuration ci-dessus ne fonctionnera pas car il y aura une collision de port:

version: '3'

services:
  test1:
    image: alpine
    command: nc -lp 1337
  test2:
    image: alpine
    command: nc -lp 1337
    network_mode: service:test1


0 commentaires

2
votes

ajoutez simplement une spécification de réseau à votre fichier docker-compose pour utiliser un réseau de pont personnalisé.

quelque chose comme ça pourrait fonctionner pour vous

const userServiceProxy = httpProxy(http://user-service:8093);
  this.app.post('/admin/register', async(req, res) => {
      userServiceProxy(req, res);
  });

selon votre spécification ports et services dans votre docker-compose les connexions suivantes sont désormais possibles:

  • conteneur api-gateway: user-service: 8093
  • conteneur de service utilisateur: api-gateway:8080

si je fais les choses correctement, votre passerelle api serait maintenant:

version: '3'
services:
  api-gateway:
    container_name: api-gateway
    build: './api-gateway'
    ports:
    - "8080:8080"
    networks:
    - mynet
  user-service:
    build: ./user-service
    container_name: user-service
    ports:
    - "8093:8093"
    networks:
    - mynet

networks:
  mynet:
    driver: bridge
    ipam:
      driver: default

à l'intérieur d'un réseau docker, vous pouvez accéder directement aux ports d'autres conteneurs ( pas besoin de spécifier un mappage de port vers votre hôte). probablement un de vos mappages de port est donc inutile. si vous accédez au service utilisateur uniquement via api-gateway et non directement, vous pouvez supprimer la spécification de port dans vos fichiers docker-compose (bloc de service utilisateur). votre service utilisateur ne serait alors accessible qu'en utilisant la passerelle api. ce qui est probablement ce que vous voulez.


1 commentaires

Beaucoup d'autres grâce à vous @shaped! C'est ce que je cherchais, cela a fonctionné comme un champion.



0
votes

Le moyen le plus simple serait d'utiliser l'indicateur docker --net = host de cette façon votre conteneur docker utiliserait le réseau de votre machine hôte au lieu de ses propres réseaux d'espacement de noms. par exemple

docker run -d --network host -p 80:80 nginx

et vous pouvez vérifier sur http: // localhost la page d'accueil de nginx.


0 commentaires