Docker를 사용하여 MongoDB Replica Set 구축하기 🐳

Youngeui Hong·2022년 8월 21일
6
post-thumbnail
post-custom-banner

👯‍♀️ Replica Set이란?

MongoDB의 Replica Set은 동일한 데이터셋을 가지고 있는 mongod 프로세스 그룹을 의미합니다.

Replica Set은 Primary 노드와 Secondary 노드로 구성되는데, Secondary 노드는 Primary 노드 데이터의 복사본을 가지고 있습니다.

🤔 왜 Replica Set을 사용해야 할까?

🔻fault-tolerance한 시스템 구축을 위해
만약 하나의 노드에 문제가 발생하면 그 노드가 복구될 때까지 다른 노드가 작업을 수행하면 되므로 시스템 장애에 좀 더 유연하게 대처할 수 있습니다.

🔻Transaction 처리를 위해
MongoDB의 Transaction 작업은 Replica Set을 기반으로 이루어집니다. 테스트 환경이나 개발 환경에서는 Standalone mongod 인스턴스를 Replica Set으로 변환하여 사용할 수 있지만, 프로덕션 환경에서는 Replica Set 구축이 필수적입니다.

🐳 Docker로 MongoDB Replica Set 구축하기

Docker의 MongoDB 이미지에는 런타임 환경에 필요한 dependency들이 포함되어 있어서, 로컬 환경에 설치하지 않고도 MongoDB를 구동할 수 있습니다.

이 포스팅에서는 docker-compose.yml을 사용하여 MongoDB Replica Set을 구축하였습니다.

docker-copose.yml은 docker 시스템 구축과 관련된 명령어를 모아놓은 텍스트 파일로, 명령어를 일일이 입력하지 않고 한꺼번에 실행하고, 여러 서비스를 한 번에 정의할 수 있도록 합니다.


1️⃣  MongoDB Docker 이미지 다운로드

버전을 따로 명시하지 않으면 default tag로 latest가 적용되어서 가장 최신 버전이 다운로드됩니다.

docker pull mongo

2️⃣  Docker Network 생성하기

아래의 명령어로 replica set의 세 컨테이너가 작동할 docker network를 생성합니다.

docker network create mongoCluster

3️⃣  Key File 생성하기

key file은 replica set에 참여하는 mongod 인스턴스 간의 인증, 클라이언트 접속 시 access control에 사용됩니다.

key file이 없는 상태에서 컨테이너를 실행하려고 하면 아래와 같은 오류가 뜹니다.

BadValue: security.keyFile is required when authorization is enabled with replica sets
try 'mongod --help' for more information

따라서 아래와 같은 명령어로 key file을 생성하고 docker 인스턴스를 실행할 때 key file이 마운트되도록 docker-compose.yml에 작성해줍니다. (관련 내용은 4️⃣번 참조)

openssl rand -base64 756 > <path-to-keyfile>
chmod 400 <path-to-keyfile>

4️⃣  세 개의 MongoDB 인스턴스 실행하기

아래와 같이 docker-compose.yml을 작성한 뒤, 쉘에서 해당 파일이 있는 디렉토리로 이동하여 docker-compose up -d 명령어를 실행합니다.

version: '3.8'

services:

  mongo1:
    image: mongo:latest
    hostname: mongo1
    container_name: mongo1
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: root!
    ports:
      # 로컬 27017 포트로 요청이 들어오면 컨테이너의 27017 포트로 리다이렉트되도록 설정
      - 27017:27017
    volumes:
      - ./data/db/replica/mongo1:/data/db
      - ./mongodb.key:/etc/mongodb.key 
    command:
      - '--replSet'
      - 'myReplicaSet'
      - '--keyFile'
      - '/etc/mongodb.key'
      - '--bind_ip_all'
  mongo2:
    image: mongo:latest
    hostname: mongo2
    container_name: mongo2
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: root!
    depends_on:
      - mongo1
    ports:
      - 27018:27017
    volumes:
      - ./data/db/replica/mongo2:/data/db
      - ./mongodb.key:/etc/mongodb.key
    command:
      - '--replSet'
      - 'myReplicaSet'
      - '--keyFile'
      - '/etc/mongodb.key'
      - '--bind_ip_all'
  mongo3:
    image: mongo:latest
    hostname: mongo3
    container_name: mongo3
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: root!
    depends_on:
      - mongo2
    ports:
      - 27019:27017
    volumes:
      - ./data/db/replica/mongo3:/data/db
      - ./mongodb.key:/etc/mongodb.key
    command:
      - '--replSet'
      - 'myReplicaSet'
      - '--keyFile'
      - '/etc/mongodb.key'
      - '--bind_ip_all'
networks:
  default:
    name: mongoCluster

5️⃣  Replica Set 초기화하기

docker-compose.yml을 실행하고 Docker Desktop을 확인해보면 세 개의 컨테이너가 실행되고 있을 것입니다.

이 중 한 컨테이너의 open in terminal을 클릭하여 도커 터미널을 실행합니다.

그리고 터미널에서 mongo -u username -p password를 입력하여 mongosh에 접속합니다.

mongosh에서 rs.initiate() 명령어로 replica set의 이름과 멤버를 지정하여 초기화를 진행합니다.

rs.initiate({
	 _id: "myReplicaSet",
	 members: [
	   {_id: 0, host: "mongo1"},
	   {_id: 1, host: "mongo2"},
	   {_id: 2, host: "mongo3"}
	 ]
});

6️⃣  Replica Set 생성 결과 확인하기

다시 mongosh에 접속했을 때 하나의 컨테이너에는 PRIMARY, 나머지 두 개의 컨테이너에는 SECONDARY로 뜨면 Replica Set이 제대로 만들어진 것입니다.

그리고 rs.status() 명령어로도 Replica Set과 관련된 자세한 내용을 확인할 수 있습니다.


참고자료

Replication -- MongoDB Manual
Deploying a MongoDB Cluster with Docker
Deploy Replica Set With Keyfile Authentication

post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 10월 7일

감사합니다~

답글 달기