Подключения Mongodb, Boot2Docker и Replica Set

У меня есть докер-контейнер, который действует как единственный член набора реплик. Я могу успешно запустить три из них и запустить в них несколько сценариев оболочки, чтобы соединить их вместе как набор реплик. Я обнаружил, что могу подключиться к каждому из участников индивидуально с моего хост-компьютера, однако, когда я пытаюсь подключиться к набору реплик (в моем случае через spring-data-mongodb), перечисляя каждого члена на IP-адресе boot2docker и соответствующий порт, я обнаружил, что где-то приложение обменивается IP-адресом boot2docker для каждого IP-адреса контейнера и пытается подключиться напрямую к этому IP-адресу.

Я предполагаю, что это происходит потому, что начальная строка подключения - это просто начальный список, а затем фактическая конфигурация обеспечивается посредством связи с самими участниками. Это, конечно, проблема, потому что эти IP-адреса не существуют на хост-машине (где запущено приложение), а только внутри виртуальной машины boot2docker. Как я могу заставить участников сообщать IP-адрес boot2docker вместо своих индивидуальных недоступных IP-адресов?

Я столкнулся с чем-то похожим с elasticsearch и смог исправить это, установив переменную network.publish_host. Есть ли аналогичная настройка для mongodb? Я думал, что, возможно, bind_ip был правильным, но не смог заставить эту работу, я использую это неправильно? Я устанавливал его на IP-адрес boot2docker и при запуске получал ошибку привязки.

Кроме того, я могу подтвердить, что это проблема только с boot2docker, добавленным в микс, поскольку мои друзья, использующие ubuntu и собственный докер, могут нормально подключаться.

Вот ошибка, которую я вижу при попытке установить свой bind_ip на boot2docker vm:

Starting mongod process using command: /usr/bin/mongod --storageEngine wiredTiger --auth --dbpath /data/db/ --replSet rs0 --bind_ip 127.0.0.1,192.168.59.103 --keyFile /mongodb-keyfile
2015-04-19T16:34:41.123+0000 E NETWORK  [initandlisten] listen(): bind() failed errno:99 Cannot assign requested address for socket: 192.168.59.103:27017

Вот моя строка подключения в моем весеннем xml:

<mongo:mongo id="mongo" replica-set="192.168.59.103:27017,192.168.59.103:27018,192.168.59.103:27019"/>

Вот ошибка, которую видит мое приложение (если я просто начал что-то, не пытаясь изменить bind_ip и т. Д.)

Client view of cluster state is {type=ReplicaSet, servers=[{address=172.17.0.34:27017, type=Unknown, state=Connecting}, {address=172.17.0.35:27017, type=Unknown, state=Connecting}, {address=172.17.0.36:27017, type=Unknown, state=Connecting}]
        at com.mongodb.BaseCluster.getServer(BaseCluster.java:82) ~[mongo-java-driver-2.13.0.jar:na]

Эти IP-адреса являются IP-адресами каждого контейнера, и каждый контейнер действительно запускается на порту 27017, но затем я публикую их порты на виртуальной машине boot2docker как 27017, 27018 и 27019.


person RutledgePaulV    schedule 19.04.2015    source источник


Ответы (3)


Я нашел решение этого. По сути, для клиентов mongo (и в моем случае для данных Spring) важны адреса, сообщаемые самими членами набора реплик. Начальная строка подключения - это только начальный список, который просматривается до тех пор, пока один из указанных членов не ответит клиенту с полной информацией о конфигурации набора реплик.

Это означает, что фактические IP-адреса, которые записываются для повторных попыток, и на самом деле все будущее взаимодействие с набором реплик определяется тем, что набор реплик сообщает клиенту, когда клиент запрашивает свою конфигурацию, которая определяется содержимым конфигурации набора реплик. документ.

Поскольку набор реплик был инициирован с использованием IP-адресов контейнера докеров, это были IP-адреса, которые были записаны в документе конфигурации набора реплик и затем сообщались приложению при запуске, и поэтому, как только клиент переключился на использование этих IP-адресов, он больше не мог подключаться к контейнеры, потому что IP-адреса докеров не отображаются за пределами виртуальной машины boot2docker.

Решение (в моем случае) заключалось в том, чтобы изменить начальную конфигурацию набора реплик, чтобы вместо этого предоставить IP-адреса участников, как если бы он был инициирован с хост-машины (и на самом деле это просто разные порты, доступные на машине boot2docker). Это означало, что адреса в документе конфигурации были доступны для любых клиентов на моем хост-компьютере, а не только для тех, кто находится внутри boot2docker.

person RutledgePaulV    schedule 15.06.2015

Я столкнулся с аналогичной проблемой после того, как следовал этому руководству по настройке создать кластер mongodb через докер. Чтобы иметь возможность открыть правильное соединение с набором реплик с этим кластером, я внес следующие два изменения в инструкции:

  1. Вместо использования выделенного сетевого моста докеров я использовал размещенную сеть, запустив каждый узел с (например):

docker run -p 30001: 30001 --name mongo1 --net host mongo mongod --replSet rs1 --port 30001

("--net host" использует сеть хоста, и порты должны быть затем переназначены для использования доступных портов на хосте. Не совсем уверен, нужна ли вообще опция переадресации портов в этой настройке)

  1. Я работаю в Windows с докер-машиной, поэтому я получил IP-адрес виртуальной машины, используя:

докер-машина env

Затем подключил этот IP-адрес к конфигурации набора реплик, таким образом (в данном случае IP-адрес виртуальной машины был 192.168.99.100):

config = {
      "_id" : "rs1",
      "members" : [
        {
          "_id" : 0,
          "host" : "192.168.99.100:30001"
        },
        {
          "_id" : 1,
          "host" : "192.168.99.100:30002"
        },
        {
          "_id" : 2,
          "host" : "192.168.99.100:30003"
        }
      ]
    }

Очевидно, что вся эта установка предназначена исключительно для тестов и не предназначена для производства.

person joniba    schedule 22.09.2016

вы должны запустить свой mongod в IP-адресе вашего контейнера

Попробуйте это: / usr / bin / mongod --auth --dbpath / data / db / --replSet rs0 --bind_ip 172.17.0.34

172.17.0.34 - это адрес вашего контейнера (mongod primairy)

person user3437964    schedule 20.04.2015
comment
Процесс mongod запускается в самом контейнере докеров, так что не должен ли IP быть localhost? Проблема в том, что boot2docker направляет меня на IP-адрес контейнера, но хост-машина не может получить доступ к контейнерам по этому IP-адресу - он может получить доступ только к виртуальной машине boot2docker напрямую. - person RutledgePaulV; 20.04.2015
comment
Процесс mongod должен запускаться с IP-адреса контейнера докеров. По умолчанию хост-машина не может получить доступ к ip-адресу контейнера, поэтому вам нужно сделать это вручную: docker run -d -p host_ip: port: 27017 mongo_image, теперь вы можете получить доступ к контейнеру через host_ip: port - person user3437964; 21.04.2015