티스토리 뷰

docker-compose 로 멀티 클러스터 mongodb 구성하기

  • docker-compose를 이용하여 멀티 클러스터를 구성해 보자.
  • mongodb에서는 멀티 클러스터를 replica set이라고 부르고 있다.

docker-compose.yaml 파일 작성하기.

  • 이제는 docker-compose.yaml 파일을 생성해 보자.
version: '3.8'

services:
  mongo01:
    container_name: mongo01
    image: mongo
    volumes:
      - ./mongo/data01:/data/db
      - ./rs-init.sh:/scripts/rs-init.sh
      - ./mongodb.key:/mongodb.key
    networks:
      - mongo-network
    ports:
      - 27021:27017
    links:
      - mongo02
      - mongo03
    restart: always
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=rootpass
    command: ["--keyFile", "./mongodb.key",  "--bind_ip_all", "--replSet", "mongo-rs" ]

  mongo02:
    container_name: mongo02
    image: mongo
    volumes:
      - ./mongo/data02:/data/db
      - ./mongodb.key:/mongodb.key
    networks:
      - mongo-network
    ports:
      - 27022:27017
    restart: always
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=rootpass
    command: ["--keyFile", "./mongodb.key", "--bind_ip_all", "--replSet", "mongo-rs" ]

  mongo03:
    container_name: mongo03
    image: mongo
    volumes:
      - ./mongo/data03:/data/db
      - ./mongodb.key:/mongodb.key
    networks:
      - mongo-network
    ports:
      - 27023:27017
    restart: always
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=rootpass
    command: ["--keyFile", "./mongodb.key",  "--bind_ip_all", "--replSet", "mongo-rs" ]

volumes:
    data: {} 

networks:
  mongo-network:
    driver: bridge
  • version: docker-compose의 버젼이다.
  • services: docker-compose 내부에 서비스 목록을 기술한다.
  • services.mongo01: 첫번재 mongodb 클러스터 이름을 지정한다. 이름은 mongo01이다.
  • services.mongo01.container_name: 컨테이너 이름을 mongo01로 지정한다.
  • services.mongo01.image: mongo로 이미지를 사용한다.
  • services.mongo01.volumes: 컨테이너에 연결할 호스트 볼륨을 지정한다.
    • mongo/data01 ~ 03 : mongodb 데이터가 저장될 디렉토리
    • /rs-init.sh: mongo replica set을 연결할 스크립트 파일
    • mongodb.key: 클러스터 상호간 통신할 키 파일
  • services.mongo01.networks: mongodb 네트워크를 설정한다.
  • services.mongo01.ports: 호스트포트:컨테이너 포트를 지정한다. mongodb는 기본 포트가 27017이다.
  • services.mongo01.links: 네트워크상에서 연동할 대상 인스턴스
  • services.mongo01.restart: 재시동 정책
  • services.mongo01.environment: 환경 변수를 지정한다.
  • services.mongo01.environment.MONGO_INITDB_ROOT_USERNAME: 루트 계정
  • services.mongo01.environment.MONGO_INITDB_ROOT_PASSWORD: 루트 패스워드
  • services.mongo01.command: 명령을 수행한다. mongo의 경우 기본 엔트리포인트의 파리미터로 전달된다.
    • --keyFile: 클러스터간 통신을 위한 임호화 키를 지정한다.
    • ./mongodb.key: 암호화 키 파일
    • --bind_ip_all: 클러스터 전체 ip와 바인드한다.
    • --replSet: 리플리카셋을 지정한다.
    • mongo-rs: 리플리카셋의 이름을 지정한다.
  • mongo02~03 동일한 설정을 수행한다.
  • volumes: docker-compose의 볼륨을 지정한다. 호스트의 볼륨을 지정한다.
  • networks: 클러스터용 네트워크를 지정한다.
  • networks.mongo-network: mongodb의 네트워크이다.
  • networks.mongo-network.driver: 네트워크 드라이버를 지정하며 여기서는 bridge로 연결한다.

keyFile 생성하기.

  • 클러스터 사이에 리플리카셋을 지정하면, 이들간 통신을 위한 키 파일 생성이 필요하다.
openssl rand -base64 756 > mongodb.key
  • 소유자만 읽기 전용으로 구성한다.
chmod 400 mongodb.key

rs-init.sh 스크립트 작성하기.

  • 이제는 mongodb 클러스터가 구성되고나면, 클러스터를 묶어줄 mongo shell 커맨드를 작성한다.
#!/bin/bash

mongo -u admin -p rootpass<<EOF
var config = {
    "_id": "mongo-rs",
    "version": 1,
    "members": [
        {
            "_id": 1,
            "host": "mongo01:27017",
            "priority": 3
        },
        {
            "_id": 2,
            "host": "mongo02:27017",
            "priority": 2
        },
        {
            "_id": 3,
            "host": "mongo03:27017",
            "priority": 1
        }
    ]
};
rs.initiate(config, { force: true });
rs.status();

EOF
  • mongo -u admin -p rootpass: docker-compose 환경변수에 지정한 admin계정의 id/pwd를 구성한다.
  • <<EOF ~ EOF : 이 설정을 통해서 이후 기술된 내용을 mongo에 스트림으로 전달한다.
  • var config = {...} : 설정을 위한 JSON 을 생성한다. mongodb는 JSON을 이용하여 커맨들르 전달한다.
  • _id: 리플리카셋 아이디이다.
  • version: 복제 설정 버젼이다. 1로 지정
  • members: 리플리카셋 멤버를 지정한다.
  • members.id : 복제 멤버의 아이디
  • members.host: 복제 멤버의 host:port로 구성한다. docker-compose로 구성하였으므로 서비스 이름이 호스트이름이다.
  • members.priority: 클러스터 우선순위를 지정한다.
  • rs.initiate: 리플리카셋을 초기화 한다.
  • rs.status(): 리프리라셋의 상태를 출력한다.
  • 위 스크립트를 mongo01 서비스에 접근해서 명령을 전달하면, 클러스터가 구성이 된다.

run-mongo.sh 파일 작성하고, 실해하기

  • 이제 쉘을 만들어서 docker-compose를 실행하자.
#!/bin/bash

docker-compose up -d

sleep 10

echo "init replicaset"

docker exec  mongo01 /scripts/rs-init.sh
  • docker-compose up -d: docker-compose를 실행한다. 우리가 작성한 docker-compose.yaml 파일이 사용되어 컨테이너가 실행된다.
    • '-d' 옵션으로 detach 모드로 실행되도록 한다. (백그라운드 모드)
  • sleep 10: 컨테이너가 실행되고 약 10초간 대기한다. 이유는 컨테이너가 정상으로 실행되기를 대기하는 용도이다.
  • docker exec mongo01 /scripts/rs-init.sh : 이 명령을 통해서 mongo01 컨테이너 내부의 스크립트인 rs-init.sh 를 실행한다.

실행결과:

mongo-docker-multiple-replicas git:(main) ▶ ./run-mongo.sh                   
Creating network "mongo-docker-multiple-replicas_default" with the default driver
mongo03 is up-to-date
mongo02 is up-to-date
mongo01 is up-to-date
Recreating mongo-express ... done
init replicaset
MongoDB shell version v5.0.6
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("c49d6c2c-ca16-4a44-a3fe-dabdbd5e7722") }
MongoDB server version: 5.0.6
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
{
        "ok" : 0,
        "errmsg" : "already initialized",
        "code" : 23,
        "codeName" : "AlreadyInitialized",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1650541637, 1),
                "signature" : {
                        "hash" : BinData(0,"NHhQE9GIDVMQtgGettO1HMXKOjs="),
                        "keyId" : NumberLong("7089020504765366276")
                }
        },
        "operationTime" : Timestamp(1650541637, 1)
}
{
        "set" : "mongo-rs",
        "date" : ISODate("2022-04-21T11:47:27.656Z"),
        "myState" : 1,
        "term" : NumberLong(1),
        "syncSourceHost" : "",
        "syncSourceId" : -1,
        "heartbeatIntervalMillis" : NumberLong(2000),
        "majorityVoteCount" : 2,
        "writeMajorityCount" : 2,
        "votingMembersCount" : 3,
        "writableVotingMembersCount" : 3,
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1650541637, 1),
                        "t" : NumberLong(1)
                },
                "lastCommittedWallTime" : ISODate("2022-04-21T11:47:17.910Z"),
                "readConcernMajorityOpTime" : {
                        "ts" : Timestamp(1650541637, 1),
                        "t" : NumberLong(1)
                },
                "appliedOpTime" : {
                        "ts" : Timestamp(1650541637, 1),
                        "t" : NumberLong(1)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1650541637, 1),
                        "t" : NumberLong(1)
                },
                "lastAppliedWallTime" : ISODate("2022-04-21T11:47:17.910Z"),
                "lastDurableWallTime" : ISODate("2022-04-21T11:47:17.910Z")
        },
        "lastStableRecoveryTimestamp" : Timestamp(1650541607, 1),
        "electionCandidateMetrics" : {
                "lastElectionReason" : "electionTimeout",
                "lastElectionDate" : ISODate("2022-04-21T11:40:07.758Z"),
                "electionTerm" : NumberLong(1),
                "lastCommittedOpTimeAtElection" : {
                        "ts" : Timestamp(1650541196, 1),
                        "t" : NumberLong(-1)
                },
                "lastSeenOpTimeAtElection" : {
                        "ts" : Timestamp(1650541196, 1),
                        "t" : NumberLong(-1)
                },
                "numVotesNeeded" : 2,
                "priorityAtElection" : 3,
                "electionTimeoutMillis" : NumberLong(10000),
                "numCatchUpOps" : NumberLong(0),
                "newTermStartDate" : ISODate("2022-04-21T11:40:07.839Z"),
                "wMajorityWriteAvailabilityDate" : ISODate("2022-04-21T11:40:08.512Z")
        },
        "members" : [
                {
                        "_id" : 1,
                        "name" : "mongo01:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 501,
                        "optime" : {
                                "ts" : Timestamp(1650541637, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2022-04-21T11:47:17Z"),
                        "lastAppliedWallTime" : ISODate("2022-04-21T11:47:17.910Z"),
                        "lastDurableWallTime" : ISODate("2022-04-21T11:47:17.910Z"),
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "",
                        "electionTime" : Timestamp(1650541207, 1),
                        "electionDate" : ISODate("2022-04-21T11:40:07Z"),
                        "configVersion" : 1,
                        "configTerm" : 1,
                        "self" : true,
                        "lastHeartbeatMessage" : ""
                },
                {
                        "_id" : 2,
                        "name" : "mongo02:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 451,
                        "optime" : {
                                "ts" : Timestamp(1650541637, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1650541637, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2022-04-21T11:47:17Z"),
                        "optimeDurableDate" : ISODate("2022-04-21T11:47:17Z"),
                        "lastAppliedWallTime" : ISODate("2022-04-21T11:47:17.910Z"),
                        "lastDurableWallTime" : ISODate("2022-04-21T11:47:17.910Z"),
                        "lastHeartbeat" : ISODate("2022-04-21T11:47:26.204Z"),
                        "lastHeartbeatRecv" : ISODate("2022-04-21T11:47:27.229Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "",
                        "syncSourceHost" : "mongo01:27017",
                        "syncSourceId" : 1,
                        "infoMessage" : "",
                        "configVersion" : 1,
                        "configTerm" : 1
                },
                {
                        "_id" : 3,
                        "name" : "mongo03:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 451,
                        "optime" : {
                                "ts" : Timestamp(1650541637, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1650541637, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2022-04-21T11:47:17Z"),
                        "optimeDurableDate" : ISODate("2022-04-21T11:47:17Z"),
                        "lastAppliedWallTime" : ISODate("2022-04-21T11:47:17.910Z"),
                        "lastDurableWallTime" : ISODate("2022-04-21T11:47:17.910Z"),
                        "lastHeartbeat" : ISODate("2022-04-21T11:47:26.203Z"),
                        "lastHeartbeatRecv" : ISODate("2022-04-21T11:47:27.229Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "",
                        "syncSourceHost" : "mongo01:27017",
                        "syncSourceId" : 1,
                        "infoMessage" : "",
                        "configVersion" : 1,
                        "configTerm" : 1
                }
        ],
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1650541637, 1),
                "signature" : {
                        "hash" : BinData(0,"NHhQE9GIDVMQtgGettO1HMXKOjs="),
                        "keyId" : NumberLong("7089020504765366276")
                }
        },
        "operationTime" : Timestamp(1650541637, 1)
}
bye
  • 컨테이너가 실행되고 이후 10초후에 쉘이 수행되어 리플리카셋을 구성하게 된다.

mongodb에 접속해보기.

mongo-docker-multiple-replicas git:(main) ▶ docker exec -it mongo01 /bin/bash

root@039b21755ee1:/# 



root@039b21755ee1:/# mongo -u admin -p rootpass
MongoDB shell version v5.0.6
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("1146facf-e263-4978-8ac0-afe256c34227") }
MongoDB server version: 5.0.6
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
        https://docs.mongodb.com/
Questions? Try the MongoDB Developer Community Forums
        https://community.mongodb.com
---
        Enable MongoDB's free cloud-based monitoring service, which will then receive and display
        metrics about your deployment (disk utilization, CPU, operation statistics, etc).

        The monitoring data will be available on a MongoDB website with a unique URL accessible to you
        and anyone you share the URL with. MongoDB may use this information to make product
        improvements and to suggest MongoDB products and deployment options to you.

        To enable free monitoring, run the following command: db.enableFreeMonitoring()
        To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
mongo-rs:PRIMARY> 
  • 결과를 보면 PRIMARY 라고 메인에 접속되었음을 확인할 수 있다.
mongo-docker-multiple-replicas git:(main) ▶ docker exec -it mongo03 /bin/bash

root@e81a2446f546:/# mongo -u admin -p rootpass
MongoDB shell version v5.0.6
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("3a984bcf-c278-478b-90a6-9541e088cfc7") }
MongoDB server version: 5.0.6
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
        https://docs.mongodb.com/
Questions? Try the MongoDB Developer Community Forums
        https://community.mongodb.com
---
        Enable MongoDB's free cloud-based monitoring service, which will then receive and display
        metrics about your deployment (disk utilization, CPU, operation statistics, etc).

        The monitoring data will be available on a MongoDB website with a unique URL accessible to you
        and anyone you share the URL with. MongoDB may use this information to make product
        improvements and to suggest MongoDB products and deployment options to you.

        To enable free monitoring, run the following command: db.enableFreeMonitoring()
        To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
mongo-rs:SECONDARY> 
  • mongo03에 접속하면 SECONDARY 로 접속된것을 확인할 수 있다.
  • 이것으로 정상적인 클러스터링이 구성 되었음을 알 수 있다.
 

'MongoDB' 카테고리의 다른 글

[MongoDB] Mongo Shell Baseic  (0) 2022.04.14
[MongoDB] Install MongoDB with Docker Compose  (0) 2022.04.14
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함