1
votes

Connectez-vous à un jeu de réplicas MongoDB ancré à distance

Dans ma machine distante, j'ai configuré une machine de conteneur docker que je gère à l'aide de docker-compose. J'ai créé 3 conteneurs Docker pour chaque instance MongoDB que je souhaite dans mon jeu de réplicas

MongoDB shell version v4.0.6
connecting to: mongodb://<remote-host>:10001,<remote-host>:10002,<remote-host>:10003/<database>?gssapiServiceName=mongodb&replicaSet=rs0
2019-03-04T16:12:54.375+0000 I NETWORK  [js] Starting new replica set monitor for rs0/<remote-host>:10001,<remote-host>:10002,<remote-host>:10003
2019-03-04T16:12:54.377+0000 I NETWORK  [ReplicaSetMonitor-TaskExecutor] Successfully connected to <remote-host>:10003 (1 connections now open to <remote-host>:10003 with a 5 second timeout)
2019-03-04T16:12:54.377+0000 I NETWORK  [js] Successfully connected to <remote-host>:10001 (1 connections now open to <remote-host>:10001 with a 5 second timeout)
2019-03-04T16:12:54.378+0000 I NETWORK  [js] changing hosts to rs0/mongodb_01:27017,mongodb_02:27017,mongodb_03:27017 from rs0/<remote-host>:10001,<remote-host>:10002,<remote-host>:10003
2019-03-04T16:12:54.882+0000 W NETWORK  [js] Unable to reach primary for set rs0
2019-03-04T16:12:54.882+0000 I NETWORK  [js] Cannot reach any nodes for set rs0. Please check network connectivity and the status of the set. This has happened for 1 checks in a row.

J'ai également configuré le jeu de répliques. et ceci est un extrait:

mongo mongodb://<remote-host>:10001,<remote-host>:10002,<remote-host>:10003/<database>?replicaSet=rs0

Tout fonctionne correctement et les communications intra-réseau entre les autres images du docker et ce jeu de répliques fonctionnent correctement en utilisant la chaîne de connexion

$ docker run -it mongo:latest bash

Le problème est lorsque je dois connecter un client distant à ce jeu de répliques. Par exemple, en utilisant mangouste via un nœud sur ma machine de développement, j'obtiens:

mongodb://<remote-host>:10001,<remote-host>:10002,<remote-host>:10003/<database>?replicaSet=rs0

Parfois, il échoue sur mongodb_03.

Edit : comme indiqué, voici ma chaîne de connexion depuis une machine distante:

MongoNetworkError: failed to connect to server [mongodb_02:27017] on first connect [MongoNetworkError: getaddrinfo ENOTFOUND mongodb_02 mongodb_02:27017]

Edit 2 : en utilisant un client comme Mongodb Compass, je peux me connecter correctement aux instances uniques. Lorsque j'ajoute le réplicaset, j'obtiens l'erreur. J'ai donc essayé de créer un conteneur factice avec mongodb (en utilisant mongo: latest).

mongodb://mongodb_01:27017,mongodb_02:27017,mongodb_03:27017/<database>?replicaSet=rs0

et courir

"_id" : "rs0",
...
"members" : [
    {
        "_id" : 0,
        "host" : "mongodb_01:27017",
        ...
    },
    {
        "_id" : 1,
        "host" : "mongodb_02:27017",
        ...
    },
    {
        "_id" : 2,
        "host" : "mongodb_03:27017",
        ...
    }
],
...
}

Je reçois

mongodb_01:
    image: mvertes/alpine-mongo
    entrypoint: ['/usr/bin/mongod', '--bind_ip_all', '--replSet', 'rs0']
    restart: always
    ports:
      - 10001:27017
    volumes:
      - ./mongodb/01:/data/db

mongodb_02:
    image: mvertes/alpine-mongo
    entrypoint: ['/usr/bin/mongod', '--bind_ip_all', '--replSet', 'rs0']
    restart: always
    depends_on:
       - mongodb_01
    ports:
      - 10002:27017
    volumes:
      - ./mongodb/02:/data/db

mongodb_03:
    image: mvertes/alpine-mongo
    entrypoint: ['/usr/bin/mongod', '--bind_ip_all', '--replSet', 'rs0']
    restart: always
    depends_on:
      - mongodb_02
    ports:
      - 10003:27017
    volumes:
      - ./mongodb/03:/data/db

etc.

Merci pour toute aide et suggestion!


6 commentaires

Pouvez-vous s'il vous plaît confirmer le message d'erreur? Le message d'erreur actuel est-il ce que vous avez déjà?


De plus, les ports de la chaîne de connexion sont différents de ceux de docker-compose


@MostafaHussein oui, j'ai essayé avec une application node.js et j'ai eu la même erreur, cette fois en soulignant qu'il ne peut pas trouver mongodb_03


@MostafaHussein désolé, j'ai édité la question en modifiant les ports du docker-compose vers les bons


Pouvez-vous ajouter ceci à votre /etc/hosts ? <remote-host> mongodb_XX mongodb_XX mongodb_XX et testez-le


Ajouté à / etc / hosts comme demandé. L'erreur demeure. Semble être une mauvaise configuration sur la télécommande lors de la résolution externe


3 Réponses :


0
votes

J'ai fini par utiliser une version gratuite d'Atlas pour les tests et l'intégration. Une fois mon travail terminé, j'utiliserai mon propre jeu de répliques sur mes serveurs.

C'est un peu compliqué, et je dois tout vérifier avant la production sans le support des outils de développement et des débogueurs.


0 commentaires

6
votes

J'ai rencontré exactement le même problème avec vous, et je l'ai compris.

C'est parce que votre client distant ne connaît pas l'hôte 'mongo1: 27017'. Il est uniquement utilisé à l'intérieur du réseau docker.

Il est un peu difficile d'expliquer comment j'ai résolu ce problème. Je vais d'abord montrer mon docker-compose.yml.

config = {
  "_id": "rs0",
  "members": [{
    "_id": 0,
    "host": "address.whichCanAccess.yourServer:27017"
  }, {
    "_id": 1,
    "host": "address.whichCanAccess.yourServer:27018"
  }, {
    "_id": 2,
    "host": "address.whichCanAccess.yourServer:27019",
    arbiterOnly: true
  }]
}

rs.initiate(config)

! La partie importante est 'extra_hosts' !! Il peut permettre aux conteneurs d'accéder à l'ordinateur hôte.

"address.WhichCanAccess.yourServer" <- dans mon cas, mon routeur asus a été configuré avec asus ddns, donc ce sera XXX.asuscomm.com

"192.168.1.xx" <- Adresses IP que le routeur asus a attribué à l'ordinateur hôte

Peut-être qu'une configuration de ces fichiers de composition n'est pas requise.

Exécutez 3 conteneurs avec docker-compose.

Ensuite, entrez le shell mongo du primaire, définissez la réplique comme ci-dessous

version: "3.3"
services:
  mongo-primary:
    container_name: mongo-primary
    hostname: mongo-primary
    image: mongo:4.0.11
    volumes:
      - $HOME/.dockerMongoRepl/primary/data/db:/data/db
      - $HOME/.dockerMongoRepl/keyfile:/data/keyfile
    extra_hosts:
      - "address.whichCanAccess.yourServer:192.168.1.xx"
    networks:
      - mongo-cluster
    ports:
      - 27017:27017
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: changeme
    command: --bind_ip_all --auth --keyFile /data/keyfile/mongo-cluster-key --replSet rs0 --enableMajorityReadConcern false
  mongo-secondary:
    container_name: mongo-secondary
    hostname: mongo-secondary
    image: mongo:4.0.11
    volumes:
      - $HOME/.dockerMongoRepl/secondary/data/db:/data/db
      - $HOME/.dockerMongoRepl/keyfile:/data/keyfile
    depends_on:
      - mongo-primary
    extra_hosts:
      - ""address.whichCanAccess.yourServer:192.168.1.xx""
    networks:
      - mongo-cluster
    ports:
      - 27018:27017
    restart: always
    command: --bind_ip_all -auth --keyFile /data/keyfile/mongo-cluster-key --replSet rs0 --enableMajorityReadConcern false
  mongo-arbiter:
    container_name: mongo-arbiter
    hostname: mongo-arbiter
    image: mongo:4.0.11
    volumes:
      - $HOME/.dockerMongoRepl/arbiter/data/arb:/data/arb
      - $HOME/.dockerMongoRepl/keyfile:/data/keyfile
    depends_on:
      - mongo-primary
    extra_hosts:
      - ""address.whichCanAccess.yourServer:192.168.1.xx""
    networks:
      - mongo-cluster
    ports:
      - 27019:27017
    restart: always
    command: --bind_ip_all --auth --keyFile /data/keyfile/mongo-cluster-key --replSet rs0 --enableMajorityReadConcern false

networks:
  mongo-cluster:

De cette manière, les conteneurs mongo communiqueront entre eux via le réseau hôte de docker et sont accessibles depuis une adresse IP distante.

L'ensemble du processus peut être trouvé ici .


3 commentaires

Oui, c'est délicat, mais cela peut fonctionner. J'ai déménagé vers atlas et je prévois de passer à une plate-forme sans serveur dans un proche avenir. Mais merci de partager votre expérience


Le lien que vous avez partagé redirige vers une sorte de lien d'escroquerie maintenant.


Cela a fonctionné pour moi, mais pour une équipe, ce n'est pas une solution idéale car chaque membre de l'équipe devra mettre à jour les hôtes ... Ci-dessous, j'ai publié une solution basée sur localhost qui est essentiellement une variante de la vôtre mais ne nécessitera pas de mises à jour des hôtes .



1
votes

Vous pouvez utiliser localhost à cette fin. La composition ressemblera à peu près à:

{
    // ........
    "members" : [ 
        {
            "_id" : 0,
            "host" : "localhost:27017"
            // .........
        }
    ]
    // ...........
}

Ensuite, lors de l'initialisation du réplicaset, assurez-vous de définir votre hôte sur localhost. Exemple:

version: "3"
services:
  mongodb:
    image: mongo:4.0.11
    ports:
      - "27017:27017"
    extra_hosts:
      - "localhost:0.0.0.0"
    volumes:
      - "./lambda/docker/mongod.conf:/etc/mongod.conf"

Testé sur OSX. Sous Linux / Windows, il peut avoir un comportement différent.


0 commentaires