【问题标题】:How to enable change stream in the docker image for MogoDB 3.6?如何在 MongoDB 3.6 的 docker 映像中启用更改流?
【发布时间】:2019-05-11 03:53:29
【问题描述】:

我在我的代码中使用 MongoDB 更改流,需要创建一个启用更改流的 MongoDB docker 映像。 问题是应该首先使用默认设置启动 mongod 以允许创建用户、文档等。 然后应该停止mongod。然后应该将副本集添加到 mongod.conf 以启用更改流:

# mongod.conf
replication:
  replSetName: rs0
  oplogSizeMB: 100

之后应该再次启动 mongod 并由 MongoDB shell 初始化副本集:

rs.slaveOk()
rs.initiate()
rs.initiate({_id:"rs0", members: [{"_id":1, "host":"127.0.0.1:27017"}]})

MogodDB 3.6 base image 提供了初始化功能。 你知道如何启动 mongod,初始化 DB,然后停止它并重新配置吗?

更新: 我需要初始化数据库然后添加副本集。 因此,我需要使用默认的 mongod.conf 运行 mongod,创建用户和集合,然后使用另一个启用了副本集的 mongod、conf 重新启动 mongod。我不能用官方的 MongoDB 图像来做到这一点。我已经在 Ubuntu 映像上安装了 MongoDB 3.6.12。在 bash shell 中手动运行设置命令后,我的 MongoDB 容器运行良好,但相同的指令在 Dockerfile 中不起作用 这是命令

RUN mongod --fork --config /etc/mongod.conf \
     && mongo < /opt/init_mongodb.js \
     && mongod --shutdown --dbpath /var/lib/mongodb \
     && cp /etc/mongod.conf /etc/mongod.conf.orig \
     && mongod --fork --config /opt/mongod.conf \
     && mongo -u "root" -p "root" --authenticationDatabase "admin" <  /opt/reconfig_mongodb.js \

从 Dockerfile 运行此命令时,出现以下错误

> backend@1.0.0 start /usr/src/app
> npm run babelserver

> backend@1.0.0 babelserver /usr/src/app
> babel-node --presets es2015 index.js

(node:41) UnhandledPromiseRejectionWarning: MongoError: not master and slaveOk=false
    at queryCallback (/usr/src/app/node_modules/mongodb-core/lib/cursor.js:248:25)
    at /usr/src/app/node_modules/mongodb-core/lib/connection/pool.js:532:18
    at processTicksAndRejections (internal/process/task_queues.js:82:9)
(node:41) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)

【问题讨论】:

  • 不是你提到的方式,但我的/docker-entrypoint-initdb.d' dir 解决了你的问题。见:hub.docker.com/_/mongo
  • 尝试了该图像,但看起来它不允许使用自定义 mongod.conf 重新启动 mongod
  • /docker-entrypoint-initdb.d 只会在第一个容器启动时执行(不重启)。并且来自 Docker Hub 自述文件:“mongod 默认不读取配置文件,因此需要指定带有配置文件路径的--config 选项”

标签: mongodb docker docker-compose dockerfile changestream


【解决方案1】:

我认为这不是设置副本集的干净方法。它确实应该简单得多。

无需在后台模式下运行其中一个成员,设置副本集,保存配置文件,关闭进程,最后从保存的配置文件开始,您可以只运行一个额外的“帮助”容器(也是一个mongodb 镜像),其唯一目的是设置 mongodb 副本集而不充当成员。

类似的东西可以完成这项工作:

docker-compose.yaml

version: '3'
services:
  mongodb-rs0-1:
    image: ${your_image}
    ports: [27018:27018]
    environment:
      - PORT=27018
      - MONGO_RS=rs0/mongodb-rs0-1:27018,mongodb-rs0-2:27019,mongodb-rs0-3:27020
    volumes:
    - ./db/rs0-1:/data/db
  mongodb-rs0-2:
    image: ${your_image}
    ports: [27019:27019]
    environment:
      - PORT=27019
      - MONGO_RS=rs0/mongodb-rs0-1:27018,mongodb-rs0-2:27019,mongodb-rs0-3:27020
    volumes:
    - ./db/rs0-2:/data/db
  mongodb-rs0-3:
    image: ${your_image}
    ports: [27020:27020]
    environment:
      - PORT=27020
      - MONGO_RS=rs0/mongodb-rs0-1:27018,mongodb-rs0-2:27019,mongodb-rs0-3:27020
    volumes:
    - ./db/rs0-3:/data/db
  mongodb-replicator:
    image: ${your_image}
    environment:
      - PRIMARY=mongodb-rs0-1:27018
    depends_on:
      - mongodb-rs0-1
      - mongodb-rs0-2
      - mongodb-rs0-3
networks:
  default:
    external:
      name: mongo

在 container_start.sh 中:

#!/bin/sh

if [ -z "$PRIMARY" ]; then
  # Member container 
  docker-entrypoint.sh --replSet rs0 --smallfiles --oplogSize 128 --port "${PORT-27017}"
else
  # Replicator container
  until mongo "$PRIMARY" /app/replicaset-setup.js; do
      sleep 10
  done

fi

【讨论】:

    【解决方案2】:

    即使我花了几个小时才弄清楚,实际上设置一个启用复制的 dockerized mongodb 实例非常容易(允许使用更改流。)

    将这两个放在同一个文件夹中:

    Dockerfile

    FROM mongo:4.4
    ADD ./init_replicaset.js /docker-entrypoint-initdb.d/init_replicaset.js
    CMD ["mongod", "--replSet", "rs0", "--bind_ip_all"]
    

    init_replicaset.js

    rs.initiate({'_id':'rs0', members: [{'_id':1, 'host':'127.0.0.1:27017'}]});
    

    注意:在初始化 mongo 实例时,/docker-entrypoint-initdb.d 目录中的所有 .js/.sh 文件都会自动运行,这就是它起作用的原因。

    在同一文件夹中,运行以下命令:

    docker build . -t mongo_repl

    docker run -i -p 27017:27017 mongo_repl

    就是这样!您现在应该有一个正在运行且启用复制的 mongodb 实例。

    【讨论】:

      【解决方案3】:

      通过在容器启动时初始化副本集来解决。 此脚本在 docker 文件中设置为 ENTRYPOINT

      #!/bin/sh
      # start mongod, initialize replica set
      mongod --fork --config /opt/mongod.conf
      mongo --quiet < /opt/replica.js
      # restart mongod    
      mongod --shutdown --dbpath /var/lib/mongodb
      mongod --config /opt/mongod.conf
      

      replica.js

      rs.slaveOk()
      rs.initiate()
      rs.initiate({_id:"rs0", members: [{"_id":1, "host":"127.0.0.1:27017"}]})
      

      【讨论】:

      • 你为什么要给rs.initiate()打两次电话?单节点副本集也不应该是_id: 0吗?
      猜你喜欢
      • 1970-01-01
      • 2016-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 2020-12-20
      相关资源
      最近更新 更多