Docker и mongo-go-driver "ошибка выбора сервера" - PullRequest
0 голосов
/ 31 мая 2019

Я создал набор реплик MongoDB с помощью Docker, и я могу получить доступ с помощью консоли или Robo3T и выполнить любой запрос.

Контейнеры выглядят так:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                      NAMES
efe6ae03323d        mongo               "docker-entrypoint.s…"   10 minutes ago      Up 10 minutes       0.0.0.0:30001->27017/tcp   mongo1
57d2701c8a43        mongo               "docker-entrypoint.s…"   10 minutes ago      Up 10 minutes       0.0.0.0:30002->27017/tcp   mongo2
7553966b9ff5        mongo               "docker-entrypoint.s…"   10 minutes ago      Up 10 minutes       0.0.0.0:30003->27017/tcp   mongo3

Проблема заключается в ошибке, когда я пытаюсь пропинговать с помощью mongo-go-driver (я пробовал с версией 1.0.0 и 1.0.2)

// Create MongoDB client    
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:30001"))
if err != nil {
    t.Fatalf("Exit error: %v", err)
}

ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
err = client.Connect(ctx)
if err != nil {
    t.Fatalf("Exit error: %v", err)
}

ctx, cancel = context.WithTimeout(context.Background(), time.Minute)
defer cancel()

// Ping
err = client.Ping(ctx, readpref.Primary())
if err != nil {
    t.Fatalf("Exit error Ping: %v", err)
}

ошибка, вызванная вызовом Ping, следующая:

Exit error Ping: server selection error: server selection timeout
        current topology: Type: ReplicaSetNoPrimary
        Servers:
        Addr: mongo2:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo2: no such host
        Addr: mongo3:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo3: no such host
        Addr: mongo1:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo1: no such host

Спасибо всем за поддержку!

1 Ответ

1 голос
/ 03 июня 2019

Это связано с нерешенной hostname с хоста Docker.В Docker экземпляры mongo1, mongo2 и mongo3 доступны по этим именам.Однако эти имена недоступны с хоста Docker.Это видно по этой строке:

Addr: mongo2:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo2: no such host

Драйвер MongoDB попытается server discovery из заданного члена (ей) набора реплик;он найдет все другие узлы в наборе реплик (через rs.conf ).Проблема здесь в том, что набор реплик установлен с именем mongo<N>, драйвер (запущенный на хосте Docker) не сможет разрешить эти имена.Вы можете подтвердить это, попытавшись пропинговать mongo1 с хоста Docker.

Вы можете попробовать запустить приложение из другого экземпляра Docker, совместно использующего ту же сеть Docker, что и набор реплик.Или измените сеть Docker как таковую, чтобы разрешить разрешимые имена хостов.

ОБНОВЛЕНИЕ:

Что касается вашего комментария о том, почему использование mongo shell или PyMongo работает.

Это связано с разницей в режиме подключения.При указании одного узла, например mongodb://node1:27017 в оболочке или PyMongo, обнаружение сервера не производится.Вместо этого он попытается подключиться к этому единственному узлу (а не как часть набора реплик).Подвох в том, что вам нужно подключиться к первичному узлу реплики, установленной для записи (вы должны знать, какой именно).Если вы хотите подключиться как набор реплик, вам нужно определить имя набора реплик.

В отличие от mongo-go-driver, по умолчанию он выполняет обнаружение сервера и пытается подключиться как набор реплик.Если вы хотите подключиться как один узел, вам нужно указать connect=direct в URI подключения.

...