【问题标题】:Running mongo replica set in docker-compose在 docker-compose 中运行 mongo 副本集
【发布时间】:2018-10-12 13:38:51
【问题描述】:

我有一个节点后端应用程序,它需要带有副本集的 MongoDB。我为我的应用程序创建了一个 docker 映像,它只是运行应用程序;还创建了一个运行 MongoDB 实例并配置其副本集的 docker-compose 文件。 这是我的docker-compose 文件:

version: '2'

services:
  mongod1:
    image: mongo
    command: mongod --replSet ${RS} --oplogSize 16 --smallfiles --noprealloc --bind_ip 0.0.0.0
    ports:
      - '27017:27017'

  mongod2:
    image: mongo
    command: mongod --replSet ${RS} --oplogSize 16 --smallfiles --noprealloc --bind_ip 0.0.0.0
    ports:
      - '27018:27017'

  mongod3:
    image: mongo
    command: mongod --replSet ${RS} --oplogSize 16 --smallfiles --noprealloc --bind_ip 0.0.0.0
    ports:
      - '27019:27017'

  mongo-config:
    image: mongo
    depends_on:
      - mongod1
      - mongod2
      - mongod3
    volumes:
      - ./scripts:/scripts
    environment:
      - MONGO1=mongod1
      - MONGO2=mongod2
      - MONGO3=mongod3
      - USER=machine
      - PWD=abc123456
      - RS=rs0
    entrypoint: ['/scripts/setup.sh']

在入口点我有如下的 bash 脚本:

#!/bin/bash

mongodb1=$(getent hosts ${MONGO1} | awk '{ print $1 }')
mongodb2=$(getent hosts ${MONGO2} | awk '{ print $1 }')
mongodb3=$(getent hosts ${MONGO3} | awk '{ print $1 }')

port=${PORT:-27017}

echo "Waiting for startup.."
until mongo --host ${mongodb1}:${port} --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)' &>/dev/null; do
  printf '.'
  sleep 1
done

echo "Started.."
echo "setup.sh; time now: $(date +"%T")"

mongo --host ${mongodb1}:${port} <<EOF
    use admin
    db.createUser(
        {
            user: ${USER},
            pwd: #{pwd},
            roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
        }
    )
EOF

mongo --host ${mongodb1}:${port} <<EOF
   var cfg = {
        "_id": "${RS}",
        "members": [
            {
                "_id": 0,
                "host": "${mongodb1}:${port}"
            },
            {
                "_id": 1,
                "host": "${mongodb2}:${port}"
            },
            {
                "_id": 2,
                "host": "${mongodb3}:${port}"
            }
        ]
    };
    rs.initiate(cfg, { force: true });
    rs.config();
EOF

mongo --host ${mongodb2}:${port} <<EOF
    db.setSlaveOk()
EOF

mongo --host ${mongodb3}:${port} <<EOF
    db.setSlaveOk()
EOF

现在在我的环境中,我可以在 localhost:27017 中连接到 mongodb,但应用程序无法连接到 0.0.0.0:27017。 我该如何解决这个问题?我应该使用 docker 网络吗?

【问题讨论】:

    标签: mongodb docker docker-compose


    【解决方案1】:

    尝试将 0.0.0.0 更改为 127.0.0.1 或仅使用 localhost。

    顺便说一句,我无法通过不断获取 Error: couldn't add user: not master 从您的方法创建身份验证,所以我四处搜索,发现在调用 rs.initiate() 之前,如果 mongod.conf 设置为 @987654323 @ 存在,您要连接的 mongo 实例将不知道谁是 master 或 Primary。 于是我把createUser和rs.initiate()的顺序调换了,加了延迟,就可以正常使用了。

    感谢骷髅。

    version: "3.3"
    
    services:
      mongo-admin:
        image: mongo-express
        container_name: "mongo-admin"
        environment:
          - ME_CONFIG_MONGODB_SERVER=db_manager,db_worker_1,db_worker_2
          - ME_CONFIG_OPTIONS_EDITORTHEME=ambiance
          - ME_CONFIG_BASICAUTH_USERNAME=$MONGOADMIN
          - ME_CONFIG_BASICAUTH_PASSWORD=$MONGOPASS
        ports:
          - 8081:8081
        restart: on-failure
        depends_on:
          - db_manager
          - db_worker_1
          - db_worker_2
          - mongo-set-setup
    
      db_manager:
        image: mongo:4.0
        container_name: db_manager
        volumes:
          - mongodb1:/data/db
          - ./mongod.conf:/etc/mongod.conf
        command: mongod --config /etc/mongod.conf
        ports:
          - "27017:27017"
        restart: always
    
      db_worker_1:
        image: mongo:4.0
        container_name: db_worker_1
        volumes:
          - mongodb2:/data/db
          - ./mongod.conf:/etc/mongod.conf
        command: mongod --config /etc/mongod.conf
        ports:
          - "27018:27017"
        restart: always
    
      db_worker_2:
        image: mongo:4.0
        container_name: db_worker_2
        volumes:
          - mongodb3:/data/db
          - ./mongod.conf:/etc/mongod.conf
        command: mongod --config /etc/mongod.conf
        ports:
          - "27019:27017"
        restart: always
    
      mongo-set-setup:
        container_name: "mongo-set-setup"
        image: mongo:4.0
        depends_on:
          - db_manager
          - db_worker_1
          - db_worker_2
        volumes:
          - ./setupmongo.sh:/scripts/setupmongo.sh
        environment:
          - MONGO1=db_manager
          - MONGO2=db_worker_1
          - MONGO3=db_worker_2
          - USER=$MONGOUSER
          - PASSWORD=$MONGOPASSWORD
          - RS=rs
        entrypoint: ["/scripts/setupmongo.sh"]
    
    #
    volumes:
      mongodb1:
      mongodb2:
      mongodb3:
    
    

    和外壳

    #!/bin/bash
    mongodb1=`getent hosts ${MONGO1} | awk '{ print $1 }'`
    mongodb2=`getent hosts ${MONGO2} | awk '{ print $1 }'`
    mongodb3=`getent hosts ${MONGO3} | awk '{ print $1 }'`
    
    port=${PORT:-27017}
    echo "Waiting for startup.."
    until mongo --host ${mongodb1}:${port} --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 2)' &>/dev/null; do
        printf '.'
        sleep 1
    done
    echo "Started.."
    
    echo ~~~~~~~~setup replic time now: `date +"%T" `
    echo ${mongodb1},  ${mongodb2},  ${mongodb3}
    mongo --host ${mongodb1}:${port} <<EOF
        var cfg = {
            "_id": "${RS}",
            "protocolVersion": 1,
            "members": [
                {
                    "_id": 0,
                    "host": "${mongodb1}:${port}",
                    "priority": 2
                },
                {
                    "_id": 1,
                    "host": "${mongodb2}:${port}",
                    "priority": 0
                },
                {
                    "_id": 2,
                    "host": "${mongodb3}:${port}",
                    "priority": 0
                }
            ]
        };
        rs.initiate(cfg, { force: true });
        rs.reconfig(cfg, { force: true });
        rs.slaveOk();
        db.getMongo().setReadPref('nearest');
        db.getMongo().setSlaveOk();
    EOF
    sleep 30
    
    echo ${USER}, ${PASSWORD}
    echo ~~~~~~~~~~setup user auth time now: `date +"%T" `
    mongo --host ${mongodb1}:${port} <<EOF
        use admin
        db.createUser(
            {
                "user": "${USER}",
                "pwd": "${PASSWORD}",
                "roles": [ "readWrite"]
            }
        )
    EOF
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      • 2020-08-12
      • 2018-03-18
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多