Развертывание серверов replicaset mongodb с помощью Docker на разных физических серверах

Я пытаюсь развернуть репликас mongodb с помощью докеры. Мне удалось сделать это на одном сервере, выполнив следующее:

docker run -d --expose 27017 --name mongodbmycompany1 dockerfile/mongodb mongod --replSet rsmycompa
docker run -d --expose  27017 --name mongodbmycompany2 dockerfile/mongodb mongod --replSet rsacommeassure
docker run -d --expose 27017 --name mongodbmycompany3 dockerfile/mongodb mongod --replSet rsacommeassure

MONGODB1=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' mongodbmycompany1)
MONGODB2=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' mongodbmycompany2)
MONGODB3=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' mongodbmycompany3)

echo $MONGODB1
echo $MONGODB2
echo $MONGODB3

echo "Mongodb Replicaset init"
docker exec mongodbmycompany1 mongo 127.0.0.1:27017/mycompany --eval 'if(!rs.conf()) {     rs.initiate(); cfg = rs.conf(); cfg.members[0].host = "'$MONGODB1':27017"; rs.reconfig(cfg); rs.add("'$MONGODB2':27017"); rs.add("'$MONGODB3':27017"); } rs.status();'

Работает так, как ожидалось. Мой replicaset инициализирован, и моя конфигурация результатов mongodb содержит мои 3 сервера, идентифицированные их внутренним IP-адресом. Это не идеально, поскольку я предпочитаю использовать имена серверов, но мне это не удалось. Docker заполняет каждый файл /etc/hosts именами серверов, переданными при запуске изображения с параметром -link. Если я добавлю новый сервер, а другие будут запущены. Эти серверы не будут пинговать новый сервер.

Теперь у меня есть другой вопрос. В производстве возможно наличие большого количества изображений докеры Mongodb на одном физическом сервере, но это небезопасно: - если мой физический сервер падает, я теряю все реплики Mongodb, и моя служба недоступна - если мой физический сервер использует внутреннее хранилище, все мои изображения докеров используют один и тот же диск... и у меня будут проблемы с IO.

Итак, мой вопрос: Как я могу развернуть многие реплики mongodb на нескольких физических серверах? Как эти реплики mongodb могут взаимодействовать друг с другом (первичные и вторичные серверы могут меняться), когда они находятся на разных серверах или даже на разных датацентрах?

Ответ 1

Предположим:

  • у вас есть 3 разных хоста (сервера) докеры с IP-адресами 10.1.1.101, 10.1.1.102, 10.1.1.103
  • хотите развернуть один набор реплик с именем rsacommeassure
  • Dockerfile для порта экспорта mongodb 27017
  • все серверы находятся в надежной зоне и могут разговаривать друг с другом.

Сначала запустите контейнеры mongodb на каждом сервере (10.1.1.101 ~$ используется для командной строки):

10.1.1.101 ~$ docker run -d -p 27017:27017 --name mongodbmycompany1 dockerfile/mongodb mongod --replSet rsacommeassure
10.1.1.102 ~$ docker run -d -p 27017:27017 --name mongodbmycompany2 dockerfile/mongodb mongod --replSet rsacommeassure
10.1.1.103 ~$ docker run -d -p 27017:27017 --name mongodbmycompany3 dockerfile/mongodb mongod --replSet rsacommeassure

-p 27017:27017 выводит порт 27017 на IP-адрес хоста, поэтому mongo доступен на IP-адресе хоста сервера.

Затем вам нужно запустить набор реплик, поэтому просто запустите его против контейнера mongodb (здесь я заберу сервер 1):

your_laptop ~$ > mongo --host 10.1.1.101 
MongoDB shell version: 2.6.9
connecting to: test
> rs.initiate()
> cfg = rs.conf()
> cfg.members[0].host = "10.1.1.101:27017"
> rs.reconfig(cfg)
> rs.add("10.1.1.102:27017")
> rs.add("10.1.1.103:27017") 
> rs.status();

IP-адреса локальны, но работают с глобальными, а серверы могут разговаривать друг с другом (VPN, межсетевой экран, DMZ, что угодно). Кстати, вы должны внимательно рассмотреть security.

Ответ 2

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

$ docker-machine create --driver virtualbox server1
$ docker-machine create --driver virtualbox server2
$ docker-machine create --driver virtualbox server3

Откройте 3 разных терминала, в каждом

$(Terminal1) eval "$(docker-machine env server1)"
$(Terminal2) eval "$(docker-machine env server2)"
$(Terminal3) eval "$(docker-machine env server3)"

В каждом терминале:

$(Terminal1) docker run -d -p 27017:27017 --name mongoClient1 mongo mongod --replSet r1
$(Terminal2) docker run -d -p 27017:27017 --name mongoClient2 mongo mongod --replSet r1
$(Terminal3) docker run -d -p 27017:27017 --name mongoClient3 mongo mongod --replSet r1

Перейдите в VirtualBox → в каждую среду (server1, server2, server3) → Настройка → Сеть → Адаптер 1 → Переадресация портов. Создайте новое правило Protocol TCP, Host Port - 27017, Guest Port - 27017, оставьте Host Ip и Guest Ip пустым

Теперь перезагрузите все среды, вы можете сделать это из VirtualBox или с терминала, только с терминала:

$(Terminal1) docker-machine restart server1
$(Terminal2) docker-machine restart server2
$(Terminal3) docker-machine restart server3

Перезапустите контейнеры:

$(Terminal1) docker start mongoClient1
$(Terminal2) docker start mongoClient2
$(Terminal3) docker start mongoClient3

Теперь контейнеры должны быть запущены, вы можете проверить их, выполнив $ docker ps в каждом терминале

Войдите в первый контейнер (или другой) Mongo Shell

$(Terminal1) docker exec -it mongoClient1 mongo
// now we are in the Mongo Shell
$(Mongo Shell) rs.initiate()
$(Mongo Shell) cfg = rs.conf()
$(Mongo Shell) cfg.members[0].host = <server1 Ip Address>
// you should get server1 Ip Address by running $ docker-machine ls, mine was 192.168.99.100
$(Mongo Shell) rs.reconfig(cfg)
$(Mongo Shell Primary) rs.add("<server2 Ip Address>:27017")
// now we added a Secondary
$(Mongo Shell Primary) rs.add("<server3 Ip Address>:27017", true)
// now we added an Arbiter
$(Mongo Shell Primary) use planes
// now we create a new database
$(Mongo Shell Primary) db.tranporters.insert({name:'Boeing'})
// create a new collection
$(Mongo Shell Primary) db.tranporters.find()
// we obtain the inserted plane

Чтобы подключиться к вторичному, вы можете:

$(Terminal2) docker exec -it mongoClient2 mongo planes
// or
$(Mongo Shell Primary) db = connect ("<server2 Ip Address>:27017/planes")

Теперь мы находимся в Монгольской оболочке вторичного

$(Mongo Shell Secondary) rs.slaveOk()
// to allow readings from the Shell
$(Mongo Shell Secondary)db.tranporters.find()
// should return inserted plane

Ответ 3

Вы можете использовать Weave - сеть Docker", чтобы легко решить вашу проблему.

Weave создает оверлейную сеть, которая объединяет контейнеры на разных хостах даже в разных облачных провайдерах. Weave также предоставляет службу DNS, которая позволяет находить контейнеры по имени в сети Weave.

Ответ 4

#Here stop already running instances
docker stop m1 m2 m3
#Cleanup of the volumes
docker rm -f m1 m2 m3

# Start MongoDB services optimised for faster startup
docker run  -dP --name m1 mongo mongod --replSet "r1" --noprealloc --smallfiles --nojournal --syncdelay 0 
docker run  -dP --name m2 mongo mongod --replSet "r1" --noprealloc --smallfiles --nojournal --syncdelay 0 
docker run  -dP --name m3 mongo mongod --replSet "r1" --noprealloc --smallfiles --nojournal --syncdelay 0

export M1_ADDRESS=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' m1`
export M2_ADDRESS=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' m2`
export M3_ADDRESS=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' m3`

docker exec m1 mongo --eval "rs.initiate();"
docker exec m1 mongo --eval "cfg = rs.conf(); cfg.members[0].host = '$M1_ADDRESS:27017'; rs.reconfig(cfg);"
docker exec m1 mongo --eval "rs.add('$M2_ADDRESS:27017');rs.add('$M3_ADDRESS:27017')"

# Check if everything is fine.
docker exec m1 mongo --eval "rs.status();"

Ответ 5

Я выполнил сценарий докере-образа, который устанавливает набор реплик mongodb для любого количества контейнеров и автоматизирует масштабирование при добавлении большего количества контейнеров. проверьте github github repo или реестр докеров

Использовать Docker Compose

настройте свой docker-compose.yml

version: "2"
services:
  <your_service_name>:
     image: rollymaduk/mongo-replica:local
     environment:
       REPLICA_NAME: "<your_replica_name>"
     volumes:
     -  /var/config:/var/config

запустить в командной строке

docker-compose up

масштабирование до большего количества контейнеров

docker-compose scale <your_service_name>=3

Облако докеров
Чтобы развернуть mongo-db replicaSet, используя докер-облако, настройте стек файл

stack.yml: файл стека, не требующий общих томов

<service_name>:
  image: rollymaduk/mongo-replica:cloud
  deployment_strategy: high_availability
  target_num_containers: 3
  environment:
    REPLICA_NAME: <your_replica_name>
    DOCKERCLOUD_AUTH: <your_docker_auth_key>

stack.yml: файл стека, требующий общий том

<service_name>:
  image: rollymaduk/mongo-replica:local
  deployment_strategy: high_availability
  target_num_containers: 3
  volumes:
    - /var/config:/var/config
  environment:
    REPLICA_NAME: <your_replica_name>

с помощью docker-cloud cli запускается в командной строке (если файл стека не существует в облаке)

docker-cloud stack create --name <your_stack_name> -f <your_stack_file>

docker-cloud stack start <your_stack_name>

с помощью docker-cloud cli запускается в командной строке (если файл стека уже существует в облаке)

docker-cloud stack update -f <your_stack_file> <your_stack_name>

docker-cloud stack redeploy <your_stack_name>

Важно: вы должны указать общий том и подключить его к контейнеру config directory [default:/var/config] приведенный ниже пример монтирует хост каталог /var/config в том, как сконфигурировать контейнер.
Вы можете использовать любой из рекомендуемых способов докеров для совместного использования томов между контейнеры, то есть монтирование каталога хоста или контейнера тома данных), просто вы указываете правильный путь для тома конфигурации (/var/config).

_ для изменения каталога конфигурации по умолчанию используйте переменную окружения --CONFIG_DIR для настройки вашего контейнера. Обязательно обновите хост-хост путь к вашему новому --CONFIG_DIR name _