Docker builds mongodb master-slave structure

Time:2021-9-1

The purpose of this paper is to learn from mongodb, build a master-slave replica set with docker, and ensure that it can be successfully connected to the structure through golang driver on the host computer.
It has the following directory structure:

.
├── config
│   └── config.sh
└── docker-compose.yml

amongdocker-compose.ymlThe contents of the document are as follows:

version: "3.8"

services:

    mongo_setup:
        image: mongo:5.0.0
        hostname: mongo_setup
        container_name: mongo_setup
        volumes: 
            - ./config:/rs_config
        entrypoint: /usr/bin/bash /rs_config/config.sh
        restart: "no"
        networks:
            - mongo_net
        depends_on:
            - mongo1
            - mongo2
            - mongo3

    mongo1:
        image: mongo:5.0.0
        hostname: mongo1
        container_name: mongo1
        entrypoint: /usr/bin/mongod --port 27117 --replSet "rs0" --bind_ip_all
        ports: 
            - 27117:27117
        networks:
            - mongo_net
        restart: on-failure

    mongo2:
        image: mongo:5.0.0
        hostname: mongo2
        container_name: mongo2
        entrypoint: /usr/bin/mongod --port 27217 --replSet "rs0" --bind_ip_all
        ports: 
            - 27217:27217
        networks:
            - mongo_net
        restart: on-failure
        
    mongo3:
        image: mongo:5.0.0
        hostname: mongo3
        container_name: mongo3
        environment: 
            - RS_NAME=rs0
        entrypoint: /usr/bin/mongod --port 27317 --replSet "rs0" --bind_ip_all
        ports: 
            - 27317:27317
        networks:
            - mongo_net
        restart: on-failure


networks:
    mongo_net:

In fact, you start the mongod instance in three containers, and then use one container to initialize the cluster.

config.shThis is a script for configuring master-slave, as follows:

#/bin/bash

RS_NAME=rs0
MASTER=mongo1
REPLICA_1=mongo2
REPLICA_2=mongo3

until mongosh --host $MASTER --port 27117 --quiet <<EOF
exit
EOF
do
  sleep 5
done


mongosh --host $MASTER --port 27117 --quiet <<EOF
rs.initiate(
  {
     _id: "$RS_NAME",
     version: 1,
     members: [
        { _id: 0, host : "${MASTER}:27117", priority: 2 },
        { _id: 1, host : "${REPLICA_1}:27217", priority: 1 },
        { _id: 2, host : "${REPLICA_2}:27317", priority: 1 }
     ]
  }
)
EOF

According to the above configuration, you can usedocker-compse upStart the master-slave instance.
However, if you use the golang driver on the host to connect to this instance, an error will occur. The reason is that after connecting to the master, the master returns the information of other replicas, and then the client tries to connect to other replicas. Because the host is not in the same network as the replica, it cannot communicate successfully.
The solution is to configure the host of the host, use the hosts file to help the host resolve the addresses of other copies, and add the following lines:

# for mongodb replica
127.0.0.1  mongo1
127.0.0.1  mongo2
127.0.0.1  mongo3

OK.