簡體   English   中英

帶有副本集的 Mongo 容器,docker-compose 中只有一個節點

[英]Mongo container with a replica set with only one node in docker-compose

我想創建一個帶有 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/246889#issuecomment-3817

即使 RS 中只有一個節點,您仍然需要發出replSetInitiate

另請參見此處

這是我現在用於本地開發的 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

我必須做一些類似的事情來圍繞 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”。

如果您只需要 MongoDB 通過 docker-compose.yml 的單節點副本集,您可以簡單地使用:

mongodb:
  image: mongo:5
  restart: always
  command: ["--replSet", "rs0", "--bind_ip_all"]
  ports:
    - 27018:27017
  healthcheck:
    test: mongo --eval "rs.initiate()"
    start_period: 5s

在后來的 MongoDB 和 Docker 版本中,最佳答案對我不起作用。 特別是因為如果副本集已經啟動, rs.initiate().ok會拋出錯誤,導致整個命令失敗。 此外,從另一個容器連接失敗,因為副本集的唯一成員有一些隨機主機,不允許連接。 這是我的新docker-compose.yml

services:
  web:
    # ...
    environment:
      DATABASE_URL: mongodb://root:root@db/?authSource=admin&tls=false
  db:
    build:
      context: ./mongo/
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: root
    ports:
      - '27017:27017'
    volumes:
      - data:/data/db
    healthcheck:
      test: |
        test $$(mongosh --quiet -u root -p root --eval "try { rs.initiate({ _id: 'rs0', members: [{ _id: 0, host: 'db' }] }).ok } catch (_) { rs.status().ok }") -eq 1
      interval: 10s
      start_period: 30s
volumes:
  data:

./mongo/內,我有一個自定義Dockerfile ,如下所示:

FROM mongo:6
RUN echo "password" > /keyfile \
  && chmod 600 /keyfile \
  && chown 999 /keyfile \
  && chgrp 999 /keyfile
CMD ["--bind_ip_all", "--keyFile", "/keyfile", "--replSet", "rs0"]

這個Dockerfile適合開發,但您肯定希望在生產中安裝一個安全生成且持久的keyfile文件(因此敲擊整個RUN命令)。

這對我來說很好用:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM