본문으로 건너뛰기

VM을 이용한 MongoDB Replicaset 프로비저닝

카카오클라우드 VM서비스에서 MongoDB Replicaset을 구성하는 방법을 소개합니다.

기본 정보
  • 예상 소요 시간: 60분
  • 사용자 환경
    • 권장 운영 체제: MacOS, Ubuntu
    • Region: kr-central-1, kr-central-2
  • 사전 준비 사항

시나리오 소개

MongoDB Replicaset은 동일한 데이터 집합을 복제하고, 서비스 중단에 대비한 고가용성을 제공합니다. 이 시나리오에서는 카카오클라우드 VM 서비스와 볼륨을 활용하여 Replicaset 환경을 구축합니다.

주요 내용은 아래와 같습니다.

  • Bastion 호스트를 생성하고, NGINX Proxy Manager를 사용해 SSH 요청을 포워딩하여 MongoDB 인스턴스에 접근
  • MongoDB 인스턴스를 3개 생성하고, 각 인스턴스에 500GB 볼륨을 연결하여 데이터 저장을 위한 환경을 구성
  • Bastion 호스트에서 MongoDB 인스턴스로의 SSH 포트 포워딩 설정

시작하기 전에

사전 작업으로 VPC와 서브넷, 보안 그룹의 네트워크 환경을 설정하고, 실습에 필요한 인스턴스를 생성합니다.

1. VPC와 서브넷 생성

인스턴스를 생성하기 전, 인스턴스가 생성될 VPC 및 서브넷을 생성해야 합니다. VPC와 서브넷이 없다면, VPC 생성, 서브넷 생성 문서를 참고하여 VPC 및 서브넷을 생성합니다.

2. 보안 그룹 설정

카카오클라우드 콘솔 > VPC > 보안 그룹으로 이동합니다. 아래 정보를 참고하여 보안 그룹과 인바운드 정책을 설정합니다.

보안 그룹: sg-bastion
  1. 보안 그룹 이름과 설명을 아래와 같이 입력합니다.

    이름설명
    sg-bastionBastion 호스트용
  2. 하단의 [+ 추가하기] 버튼을 클릭 후, 인바운드 조건을 아래와 같이 설정하고 [적용] 버튼을 클릭합니다.

    나의 퍼블릭 IP 확인하기

    다음 버튼을 클릭하면 현재 사용 중인 나의 퍼블릭 IP를 확인할 수 있습니다.

    추가할 인바운드 규칙항목설정값
    bastion inbound policy 1프로토콜ICMP
    패킷 출발지{사용자 퍼블릭 IP}/32
    포트 번호ALL
    정책 설명(선택)ping-bastion
    bastion inbound policy 2프로토콜TCP
    패킷 출발지{사용자 퍼블릭 IP}/32
    포트 번호22
    정책 설명(선택)ssh-bastion
    bastion inbound policy 3프로토콜TCP
    패킷 출발지{사용자 퍼블릭 IP}/32
    포트 번호81
    정책 설명(선택)manage-bastion
    bastion inbound policy 4프로토콜TCP
    패킷 출발지{사용자 퍼블릭 IP}/32
    포트 번호10000-10010
    정책 설명(선택)fowd-bastion
보안 그룹: sg-mongodb
  1. 보안 그룹 이름과 설명을 아래와 같이 입력합니다.

    이름설명
    sg-mongodbMongoDB 노드용
  2. 하단의 [+ 추가하기] 버튼을 클릭 후, 인바운드 조건을 아래와 같이 설정하고 [적용] 버튼을 클릭합니다.

    나의 퍼블릭 IP 확인하기

    다음 버튼을 클릭하면 현재 사용 중인 나의 퍼블릭 IP를 확인할 수 있습니다.

    추가할 인바운드 규칙항목설정값
    mongodb inbound policy 1프로토콜ICMP
    패킷 출발지SUBNET_CIDR
    포트 번호ALL
    정책 설명(선택)ping-mongo
    mongodb inbound policy 2프로토콜TCP
    패킷 출발지BASTION_PRIVATE_IP/32
    포트 번호22
    정책 설명(선택)ssh-mongo
    mongodb inbound policy 3프로토콜TCP
    패킷 출발지SUBNET_CIDR
    포트 번호27017
    정책 설명(선택)conn-mongo

3. VM 인스턴스 생성 및 볼륨 추가

VM 인스턴스 생성

이 단계에서 생성하는 VM 인스턴스는 MongoDB Replicaset 구축을 위한 기본 인프라 설정으로, Bastion 호스트 역할을 하며 포트 포워딩과 네트워크 및 보안 그룹 설정을 담당합니다. 이는 후속 작업에서 MongoDB 노드를 배치하고 설정할 환경을 준비하는 과정입니다.

인스턴스 이름인스턴스 유형루트 볼륨(GB)퍼블릭 IP이미지보안 그룹
handson-bastionm2a.large  30     Y    Ubuntu 20.04    sg-bastion
handson-node-1m2a.large30NUbuntu 20.04sg-mongodb
handson-node-2m2a.large30NUbuntu 20.04sg-mongodb
handson-node-3m2a.large30NUbuntu 20.04sg-mongodb

볼륨 추가

MongoDB Replicaset 구성에서 볼륨 추가 설정은 MongoDB 데이터베이스의 데이터를 저장하기 위해 필요한 스토리지 용량을 제공합니다. 후속 작업에서 MongoDB 인스턴스에 대해 별도의 볼륨을 연결하여 안정적이고 지속적인 데이터 저장 공간을 확보할 수 있습니다.

볼륨 이름연결할 인스턴스크기(GB)
mongo-data-volume-1handson-node-1500
mongo-data-volume-2handson-node-2500
mongo-data-volume-3handson-node-3500

시작하기

Step 1. Bastion 호스트 생성

이 문서에서는 NGINX PROXY MANAGER를 이용하여 SSH 요청을 설정한 호스트에 포워딩하는 방법으로 Bastion 호스트를 구현합니다. Bastion 호스트를 생성하는 방법은 다음과 같습니다.

  1. 카카오클라우드 콘솔 > Virtual Machine에서 Bastion 호스트로 사용할 가상 머신을 생성합니다.

    구분항목설정/입력값비고
    기본 정보이름handson-bastion
    개수1
    이미지Ubuntu 20.04
    인스턴스 유형m2a.large
    볼륨루트 볼륨30GB
    키 페어{USER_KEYPAIR}⚠️ 키 페어는 최초 1회 안전하게 보관해야 합니다.
    잃어버린 키는 복구할 수 없으며, 재발급이 필요합니다.
    네트워크VPCtutorial
    서브넷main (10.0.0.0/20)
    보안 그룹sg-bastion, sg-mongodb
  2. 터미널 실행 후 다음 명령어를 실행하여 Bastion 호스트에 SSH 접근합니다.

    ssh -i ${KEYPAIR_NAME}.pem ubuntu@${BASTION_PUBLIC_IP}
  3. 터미널에 하단의 명령을 실행하여 DockerDocker compose 설치 및 NGINX PROXY MANAGER를 실행합니다.

    curl -o install-bastion.sh https://raw.githubusercontent.com/kakaoenterprise/kc-handson-config/bastion-host/install-bastion.sh
    bash install-bastion.sh
  4. 브라우저에서 http://${BASTION_HOST_PUBLIC_IP}:81 주소를 입력하여 NGINX PROXY MANAGER 관리페이지에 접속할 수 있습니다. 접속을 위한 초기 계정 정보는 다음과 같습니다.

    구분입력값
    Email addressadmin@example.com
    Passwordchangeme

Step 2. MongoDB 인스턴스 생성

카카오클라우드 콘솔 > Virtual Machine에서 MongoDB 인스턴스로 사용할 가상 머신을 생성합니다.

구분항목설정/입력값비고
기본 정보이름handson-node
개수3
이미지Ubuntu 20.04
인스턴스 유형m2a.large
볼륨루트 볼륨30GB
키 페어{USER_KEYPAIR}⚠️ 키 페어는 최초 1회 안전하게 보관해야 합니다.
잃어버린 키는 복구할 수 없으며, 재발급이 필요합니다.
네트워크VPCtutorial
서브넷main (10.0.0.0/20)
보안 그룹sg-mongodb

Step 3. MongoDB 데이터 저장용 볼륨 생성

MongoDB 데이터를 저장할 별도의 볼륨을 사용하는 것을 권장합니다. MongoDB 데이터를 저장할 볼륨을 생성하는 방법은 다음과 같습니다.

  1. 카카오클라우드 콘솔Virtual Machine 에서 볼륨을 생성합니다.

    MongoDB 호스트 정보
    볼륨 이름볼륨 유형볼륨 크기
    mongodb-data-volume-1SSD       500
    mongodb-data-volume-2SSD500
    mongodb-data-volume-3SSD500
  2. 다음을 참고하여 인스턴스의 상세 페이지의 볼륨 탭에서 MongoDB 인스턴스에 연결할 볼륨을 선택합니다. (MongoDB 인스턴스에 생성한 볼륨을 추가합니다.)

    인스턴스볼륨 연결 정보
    handson-node-1mongodb-data-volume-1
    handson-node-2mongodb-data-volume-2
    handson-node-3mongodb-data-volume-3

Step 4. 포워딩 정보 업데이트

Bastion 호스트의 특정 포트에 접속하여 MongoDB 인스턴스에 ssh 접속할 수 있습니다. 이를 위해 Bastion 호스트의 특정 포트에 ssh 접속을 시도할 경우 해당 접속을 내부 특정 MongoDB 호스트에 포워딩하도록 설정합니다. Bastion 호스트의 포워딩 정보를 업데이트하는 방법은 다음과 같습니다.

  1. 브라우저에서 http://${BASTION_HOST_PUBLIC_IP}:81 주소를 입력하여 NGINX PROXY MANAGER 관리페이지에 접속합니다.

  2. NGINX PROXY MANAGER(관리 페이지) > Streams 탭에서 [Add Stream] 버튼을 클릭하여 Streams를 추가합니다.

    • 내부 호스트를 추가 시 Bastion 호스트를 통해 내부 호스트로 접속할 수 있습니다.
    Incoming PortForward HostForward Port프로토콜
    10000     handson-node-1_PRIVATE_IP22    TCP
    10001handson-node-2_PRIVATE_IP22TCP
    10002handson-node-3_PRIVATE_IP22TCP
  3. Bastion 호스트의 포트를 통해 내부 MongoDB 인스턴스에 접근되는지 확인합니다.

    ssh -i ${KEY_FILE} ubuntu@${BASTION_PUBLIC_IP} -p ${PORT}

    예시: Bastion 호스트의 10000번 포트로 ssh 접속 시도 시 mongodb-node-1 인스턴스에 ssh 접속합니다.

    ssh -i ~/hands-on.pem ubuntu@aaa.bbb.ccc.ddd -p 10000

Step 5. MongoDB 환경 구축

MongoDB를 설치하고 환경을 구축합니다. 이때 이전 단계에서 생성한 MongoDB 인스턴스에 ssh 접속하여 진행합니다.

DNS 설정

  1. Replicaset을 관리하기 위해 인스턴스 IP 주소 대신 DNS 호스트 이름을 사용하여 도네임 이름을 정의합니다. 이때 /etc/hosts 파일을 수정하여 임의로 도메인 이름을 정의합니다.

    cat << EOF | sudo tee -a /etc/hosts

    ${HANDSON-NODE-1_PRIVATE_IP} node1.rs.in
    ${HANDSON-NODE-2_PRIVATE_IP} node2.rs.in
    ${HANDSON-NODE-3_PRIVATE_IP} node3.rs.in
    EOF
  2. ping 명령을 실행하여 정의한 도메인 이름과 호스트가 일치하는지 확인합니다.

    ping node2.rs.in
    # PING node2.rs.in (172.16.0.221) 56(84) bytes of data.
    # 64 bytes from node2.rs.in (172.16.0.221): icmp_seq=1 ttl=64 time=2.18 ms
    # 64 bytes from node2.rs.in (172.16.0.221): icmp_seq=2 ttl=64 time=0.752 ms
    # ...

볼륨 마운트

데이터 및 로그를 저장하기 위해 생성한 볼륨을 데이터 디렉터리에 마운트합니다.

  1. /dev/vdb 볼륨을 xfs 파일 시스템을 통해 /data 데이터 디렉터리에 마운트합니다.

    cat <<EOF | sudo fdisk /dev/vdb
    n
    p
    1


    w
    EOF
    sudo mkfs -t xfs /dev/vdb1
    sudo mkdir -p /data
    sudo mount /dev/vdb1 /data
  2. 볼륨이 데이터베이스의 데이터를 저장할 디렉터리에 마운트 되었는지 확인합니다.

    df -h
    # Filesystem Size Used Avail Use% Mounted on
    # ...
    # /dev/vdb1 500G 3.6G 497G 1% /data
    # ...

MongoDB 설치

  1. 인스턴스에 MongoDB를 설치합니다.

    sudo apt-get install gnupg
    wget -qO - HTTPS://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add -

    echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.com/apt/ubuntu focal/mongodb-enterprise/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-enterprise.list

    sudo apt-get update
    sudo apt-get install -y mongodb-enterprise=6.0.3
    sudo service mongod stop
  2. MongoDB의 데이터와 로그는 별도로 생성한 볼륨에 저장합니다. 데이터 및 로그를 저장할 디렉터리를 생성합니다.

    sudo mkdir -p /data/mongodb
    sudo mkdir -p /data/log/mongodb
  3. 생성된 디렉터리에서 작업할 수 있도록 권한을 설정합니다.

    sudo chown -R mongodb:mongodb /data/*
  4. MongoDB 프로세스가 생성한 디렉터리에 정보를 저장하도록 값을 수정합니다. /data/mongodb에 데이터를 저장하고 /data/log/mogodb/mongod.log 파일에 로그를 작성합니다.

    cat <<EOF | sudo tee /etc/mongod.conf
    storage:
    dbPath: /data/mongodb

    systemLog:
    destination: file
    logAppend: true
    path: /data/log/mongodb/mongod.log

    net:
    port: 27017
    bindIp: 0.0.0.0

    processManagement:
    timeZoneInfo: /usr/share/zoneinfo

    replication:
    oplogSizeMB: 2000
    replSetName: "handson-replicaset"
    EOF
  5. MongoDB 프로세스를 시작합니다.

    sudo service mongod start

Step 6. MongoDB Replicaset 배포

handson-node-1, handson-node-2, handson-node-3 인스턴스에 MongoDB 프로비저닝을 완료했다면, 인스턴스 중 한 노드에 접속하여 replicaset을 구축합니다.

  1. handson-node-1 인스턴스에 접속하여 replicaset을 구축합니다.

    Replicaset 생성 (Remote - handson-node-1)
    mongosh --eval \
    'rs.initiate( {
    _id : "handson-replicaset",
    members: [
    { _id: 0, host: "node1.rs.in:27017" },
    { _id: 1, host: "node2.rs.in:27017" },
    { _id: 2, host: "node3.rs.in:27017" }
    ]
    })'
  2. handson-node-1 인스턴스에 생성된 replicaset의 설정을 확인합니다.

    replicaset 설정 확인
    mongosh --eval \
    'rs.config()'