【问题标题】:Mongo container with a replica set with only one node in docker-compose具有副本集的 Mongo 容器,在 docker-compose 中只有一个节点
【发布时间】:2020-08-12 14:38:50
【问题描述】:

我想创建一个带有 Mongo 实例的 Docker 容器。特别是,我想创建一个只有一个节点的副本集(因为我对事务感兴趣并且它们仅适用于副本集)。

Dockerfile

FROM mongo
RUN echo "rs.initiate();" > /docker-entrypoint-initdb.d/replica-init.js
CMD ["--replSet", "rs0"]

docker-compose.yml

version: "3"
services:
  db:
    build:
      dockerfile: Dockerfile
      context: .
    ports:
      - "27017:27017"

如果我单独使用 Dockerfile,一切都很好,而如果我使用 docker-compose,它就不起作用:事实上,如果我登录到容器,我会收到提示为 rs0:OTHER> 而不是 rs0:PRIMARY>

我查阅了这些链接,但建议的解决方案不起作用:

https://github.com/docker-library/mongo/issues/246#issuecomment-382072843 https://github.com/docker-library/mongo/issues/249#issuecomment-381786889

【问题讨论】:

  • 有趣的事实是,如果我只使用带有docker build -t db .; docker run -p 27017:27017 -d db 的 Dockerfile 一切都很好,但使用 docker-compose 就不起作用了。
  • 可以使用您正在使用的dockerdocker-compose 的版本以及您正在运行的操作系统的详细信息来更新您的帖子吗?我在 Ubuntu 18.04 上有 docker-compose version 1.24.0, build 0aa59064docker 客户端 20.10.5 / 服务器 19.03.13 使用您的规格,这似乎不是问题。

标签: mongodb docker docker-compose replicaset


【解决方案1】:

即使 RS 中只有一个节点,您仍然需要发出 replSetInitiate

另见here

【讨论】:

  • 我在RUN 部分做。
  • 在这种情况下 1) 确保它已被执行 2) 查看服务器日志以了解节点上发生的情况。
  • Our replica set config is invalid or we are not a member of it 是我登录到数据库容器并使用rs.status() 时收到的消息。但我不明白为什么它只适用于 docker-compose 而只适用于 Dockerfile。
  • 节点能否使用 RS 配置中使用的主机名访问自身?
【解决方案2】:

这个对我来说很好用:

version: '3.4'

services:
  ludustack-db:
      container_name: ludustack-db
      command: mongod --auth
      image: mongo:latest
      hostname: mongodb
      ports:
      - '27017:27017'
      env_file:
      - .env
      environment:
      - MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
      - MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
      - MONGO_INITDB_DATABASE=${MONGO_INITDB_DATABASE}
      - MONGO_REPLICA_SET_NAME=${MONGO_REPLICA_SET_NAME}
      healthcheck:
        test: test $$(echo "rs.initiate().ok || rs.status().ok" | mongo -u $${MONGO_INITDB_ROOT_USERNAME} -p $${MONGO_INITDB_ROOT_PASSWORD} --quiet) -eq 1
        interval: 60s
        start_period: 60s

【讨论】:

  • 我试过这段代码,它只是创建了一个独立的服务器,而不是一个单节点副本集。我通过尝试在事务中运行一些命令来测试这一点,并得到了这个错误:“独立服务器不支持事务”。
  • 我还得到了一个没有副本集的独立服务器。
【解决方案3】:

这是我在本地开发中使用了一段时间的 compose 文件。如果您不需要通过 SSL 连接,您可以删除 keyfile 部分。

version: "3.8"
services:
  mongodb:
    image : mongo:4
    container_name: mongodb
    hostname: mongodb
    restart: on-failure
    environment:
      - PUID=1000
      - PGID=1000
      - MONGO_INITDB_ROOT_USERNAME=mongo
      - MONGO_INITDB_ROOT_PASSWORD=mongo
      - MONGO_INITDB_DATABASE=my-service
      - MONGO_REPLICA_SET_NAME=rs0
    volumes:
      - mongodb4_data:/data/db
      - ./:/opt/keyfile/
    ports:
      - 27017:27017
    healthcheck:
      test: test $$(echo "rs.initiate().ok || rs.status().ok" | mongo -u $${MONGO_INITDB_ROOT_USERNAME} -p $${MONGO_INITDB_ROOT_PASSWORD} --quiet) -eq 1
      interval: 10s
      start_period: 30s
    command: "--bind_ip_all --keyFile /opt/keyfile/keyfile --replSet rs0"
volumes:
  mongodb4_data:

如果它在运行后确实需要它,它会使用 Docker 的健康检查(启动延迟)潜入rs.initiate()

创建密钥文件。

苹果机:

openssl rand -base64 741 > keyfile
chmod 600 keyfile

Linux:

openssl rand -base64 756 > keyfile
chmod 600 keyfile
sudo chown 999 keyfile
sudo chgrp 999 keyfile

【讨论】:

    【解决方案4】:

    我不得不做一些类似的事情来围绕 ChangeStreams 构建测试,这些测试仅在将 mongo 作为副本集运行时可用。我不记得我从哪里得出的,所以我无法详细解释它,但它确实对我有用。这是我的设置:

    Dockerfile

    FROM mongo:5.0.3
    RUN echo "rs.initiate({'_id':'rs0', members: [{'_id':1, 'host':'127.0.0.1:27017'}]});" > "/docker-entrypoint-initdb.d/init_replicaset.js"
    RUN echo "12345678" > "/tmp/key.file"
    RUN chmod 600 /tmp/key.file
    RUN chown 999:999 /tmp/key.file
    
    CMD ["mongod", "--replSet", "rs0", "--bind_ip_all", "--keyFile", "/tmp/key.file"]
    

    docker-compose.yml

    version: '3.7'
    
    services:
      mongo:
        build: .
        restart: always
        ports: 
          - 27017:27017
        healthcheck:
          test: test $$(echo "rs.initiate().ok || rs.status().ok" | mongo -u admin -p pass --quiet) -eq 1
          interval: 10s
          start_period: 30s
        environment:
          MONGO_INITDB_ROOT_USERNAME: admin
          MONGO_INITDB_ROOT_PASSWORD: pass
          MONGO_INITDB_DATABASE: test
    

    运行docker-compose up,你应该会很好。

    连接字符串:mongodb://admin:pass@localhost:27017/test

    注意:你显然不应该在生产中使用它,如果安全是一个问题,请调整 Dockerfile 中的密钥“12345678”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-15
      • 2018-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-29
      • 1970-01-01
      • 2017-03-06
      相关资源
      最近更新 更多