MongoDB 레플리카셋을 Docker+Django 환경에서 제대로 굴려보자! 🚀 공식 문서만 보면 머리 아프고, 실제로 해보면 온갖 에러가 튀어나오는데, 실전 경험을 바탕으로 진짜 되는 방법만 정리했다.
🤔 왜 이 글을 썼을까?
- [MongoDB 레플리카셋, 왜 이렇게 어려워?]: 사실 MongoDB 레플리카셋 자체는 그렇게 복잡하지 않아요. 문제는 Docker 네트워크 + 방화벽 + DNS + 인증 + 포트매핑이 한꺼번에 얽혀있다 보니까 뭔가 하나만 삐끗해도 전체가 안 돌아가는 거죠 😅.
- [실무에서 정말 필요한 가이드]: 공식 문서는 "이상적인 환경"에서의 얘기고, 실제로는 "왜 안 되지?", "Host not found가 뭐야?", "왜 PRIMARY가 안 뜨지?" 이런 상황들의 연속이거든요. 그래서 삽질 경험을 바탕으로 진짜 실무에서 쓸 수 있는 가이드를 만들었어요.
🧠 MongoDB 레플리카셋 핵심 개념 (쉽게 설명!)
- [레플리카셋이 뭔가요?]: 간단히 말하면 "똑같은 데이터를 가진 MongoDB 서버들의 팀"이에요. 한 대가 죽어도 다른 팀원이 바로 일을 이어받죠. PRIMARY(대장) 1명과 SECONDARY(팀원들) 여러 명으로 구성돼요.
- 왜 중요해요?: 서버 한 대 죽으면 서비스 전체가 멈추는 거, 정말 무서우잖아요? 레플리카셋이 있으면 그런 걱정 없이 잠들 수 있어요 😴.
- [Write/Read Concern (이게 좀 헷갈려요)]: WriteConcern은 "데이터 저장할 때 몇 개 서버에서 OK 사인 받을래?", ReadConcern은 "데이터 읽을 때 얼마나 확실한 걸 읽을래?" 하는 설정이에요.
- 자주 실수하는 부분: 서버 2대만 켜놓고 majority 읽기 하려고 하면 "ReadConcernMajorityNotAvailableYet" 에러가 뜨죠. 과반수가 안 되니까요!.
- [oplog와 복제 (내부 동작 원리)]: PRIMARY가 "이런 데이터 변경했어!" 하고 oplog에 기록하면, SECONDARY들이 "알겠어, 나도 똑같이 할게!" 하면서 따라해요. 근데 초기 설정이 잘못되면 "Collection local.oplog.rs not found" 같은 에러를 볼 수 있어요.
- 실무 팁: 최소 3대(홀수), 안정적인 네트워크, keyFile 인증 설정을 꼭 지켜주세요. 이거 하나라도 빠지면 멘붕이 시작됩니다 🤯.
📋 공식 가이드라인 (핵심만 쏙쏙!)
- [믿을 만한 자료들]: MongoDB 공식 문서, Severalnines 블로그, DigitalOcean 튜토리얼 정도가 제일 정확해요. Stack Overflow도 좋지만 버전별로 다를 수 있으니 주의!.
- [꼭 지켜야 할 원칙들]
- 홀수 개수로 구성하기: 3대, 5대, 7대... 이렇게 홀수로 해야 선거할 때 동점이 안 나와요
- keyFile 인증은 필수: 서버끼리 "너 진짜 우리 팀 맞아?" 확인하는 거예요. 이거 없으면 아무나 들어올 수 있어요 😱
- 안전 제일: 한 번에 여러 대 건드리지 말고, 하나씩 차근차근 상태 확인하면서 진행하세요
- 네트워크는 기본: 서버들이 서로 대화할 수 있어야 하는 건 당연하죠? 포트 열고, 방화벽 설정하고, Docker 네트워크도 연결해주세요
🛠️ 실전 구축 가이드 (따라만 하면 됩니다!)
전체 플랜: Docker로 3대 서버 띄우기 → keyFile 만들어서 배포 → Docker Compose 설정 → 레플리카셋 초기화 → 문제 해결 → Django 연결 테스트
1. 🌐 네트워크 설정 (제일 중요!)
뭘 하는 거죠?: 서버들이 서로 대화할 수 있게 길을 뚫어주는 거예요.
# 방화벽 열기 (포트 번호는 본인 설정에 맞게) sudo ufw allow 1234/tcp sudo ufw allow 1235/tcp sudo ufw allow 1236/tcp # 연결 테스트해보기 nc -zv <다른서버IP> 1234 # "Connected"가 뜨면 성공! # Docker 네트워크 만들기 docker network create mongo-cluster
✅ 잘 됐는지 확인: nc -zv 명령어로 "Connected" 메시지가 나오면 OK!
💡 실수 방지 팁: DNS가 불안정하면 나중에 "Host not found" 에러 지옥을 경험하게 돼요. 처음엔 IP 주소로 설정하는 게 안전해요.
2. 🔐 keyFile 만들기 (보안은 필수!)
뭘 하는 거죠?: 서버들끼리만 아는 암호를 만드는 거예요.
# 키 파일 생성 openssl rand -base64 756 > mongodb.key chmod 400 mongodb.key # 각 컨테이너에 복사 (경로는 본인 설정에 맞게) docker cp mongodb.key mongo1:/data/mongodb.key docker cp mongodb.key mongo2:/data/mongodb.key docker cp mongodb.key mongo3:/data/mongodb.key
✅ 잘 됐는지 확인: 파일 권한이 400이고, 모든 서버에 똑같은 파일이 들어갔으면 OK!
💡 실수 방지 팁: 권한 설정 잘못하면 MongoDB가 아예 안 켜져요. 반드시 400 또는 600으로 설정하세요!
3. 🐳 Docker Compose 설정
뭘 하는 거죠?: 3대의 MongoDB 서버를 컨테이너로 띄우는 설정을 만드는 거예요.
version: '3.8' services: mongo1: image: mongo:6 container_name: mongo1 command: ["mongod", "--replSet", "rs0", "--bind_ip_all", "--keyFile", "/data/mongodb.key"] volumes: - "./mongodb.key:/data/mongodb.key:ro" - "mongo1_data:/data/db" ports: - "1234:27017" networks: - mongo-cluster mongo2: image: mongo:6 container_name: mongo2 command: ["mongod", "--replSet", "rs0", "--bind_ip_all", "--keyFile", "/data/mongodb.key"] volumes: - "./mongodb.key:/data/mongodb.key:ro" - "mongo2_data:/data/db" ports: - "1235:27017" networks: - mongo-cluster mongo3: image: mongo:6 container_name: mongo3 command: ["mongod", "--replSet", "rs0", "--bind_ip_all", "--keyFile", "/data/mongodb.key"] volumes: - "./mongodb.key:/data/mongodb.key:ro" - "mongo3_data:/data/db" ports: - "1236:27017" networks: - mongo-cluster volumes: mongo1_data: mongo2_data: mongo3_data: networks: mongo-cluster: driver: bridge # 실행! docker-compose up -d # 상태 확인 docker ps
✅ 잘 됐는지 확인: docker logs mongo1에서 "waiting for connections on port 27017" 메시지가 보이면 성공!
4. 🔧 레플리카셋 초기화 (드디어 핵심!)
뭘 하는 거죠?: 3대 서버에게 "이제부터 너희는 한 팀이야!" 라고 알려주는 거예요.
# 첫 번째 서버에 접속 mongosh --host localhost:234563456345 # 레플리카셋 초기화 (IP 주소 사용 권장!) rs.initiate({ _id: "rs0", members: [ {_id: 0, host: "192.168.1.100:433456345656"}, {_id: 1, host: "192.168.1.100:2345634410"} ] }) # 세 번째 멤버 추가 rs.add("192.168.1.100:241345634561") # 상태 확인 (이게 제일 중요!) rs.status()
✅ 잘 됐는지 확인: rs.status()에서 PRIMARY 1개, SECONDARY 2개가 보이고 모든 health가 1이면 대성공! 🎉
💡 실수 방지 팁: "Host not found" 에러가 뜨면 IP 주소로 다시 시도해보세요. DNS 문제가 가장 흔한 원인이에요.
5. 🚨 문제 해결 (이게 진짜 실력!)
자주 보는 에러들과 해결법:
# 상태 확인 명령어들 rs.status() # 전체 상태 rs.isMaster() # 현재 서버 상태 db.adminCommand({replSetGetStatus: 1}) # 더 자세한 정보 # 네트워크 문제 진단 nc -zv <IP> <포트> # 연결 테스트 ss -tlnp | grep 3456345647 # 포트 열려있나 확인
흔한 에러 패턴:
ReadConcernMajorityNotAvailableYet
→ 서버 수 부족 또는 네트워크 문제Host not found
→ DNS 문제, IP로 바꿔보세요Connection refused
→ 포트나 방화벽 문제
6. 🔗 Django 연결 (마지막 단계!)
뭘 하는 거죠?: Django 앱이 레플리카셋과 잘 대화할 수 있게 설정하는 거예요.
# settings.py 또는 환경변수 # 운영용 - 자동 장애조치 지원 MONGODB_URI = "mongodb://user:pass@192.168.1.100:3456,192.168.1.100:4563456,192.168.1.100:245645641141/mydb?replicaSet=rs0&authSource=admin" # 관리용 - 특정 서버 직접 연결 MONGODB_URI_DIRECT = "mongodb://user:pass@192.168.1.100:24674657567409/mydb?directConnection=true&authSource=admin"
✅ 잘 됐는지 확인: Django에서 데이터 읽기/쓰기가 잘 되고, PRIMARY 서버를 껐다 켜도 연결이 유지되면 완벽!
🎯 실제 경험담 (성공 vs 실패)
✅ 성공 사례: "드디어 됐다!"
상황: 도커 네트워크가 꼬여서 서버들이 서로 못 찾던 문제
해결: 공통 네트워크 만들고, IP 기반으로 멤버 등록하니까 바로 해결!
결과: PRIMARY 장애 시 몇 초 만에 자동 전환되고, Django도 끊김 없이 잘 동작 🎉
❌ 실패 사례: "이틀 동안 삽질했어요..."
상황: 서버 2대만 켜놓고 테스트하려고 했는데...
문제: "ReadConcernMajorityNotAvailableYet" 에러가 계속 뜸
교훈: 과반수 원칙을 무시하면 안 된다! 무조건 3대 이상! 😭
❓ 자주 묻는 질문들
Q. 꼭 3대여야 하나요? 2대면 안 되나요?
A. 2대는 위험해요! 한 대 죽으면 과반수가 안 되서 쓰기도 막혀요. 3대 이상 권장!
Q. keyFile 만들기 귀찮은데 생략하면 안 되나요?
A. 절대 안 됩니다! 보안 없으면 아무나 들어올 수 있어요 🔓
Q. "Host not found" 에러가 계속 뜨는데요?
A. DNS 문제일 확률이 높아요. IP 주소로 바꿔서 시도해보세요!
Q. Docker에서 서버들이 서로 못 찾아요
A. 같은 네트워크에 연결했나요? docker network create로 공통 네트워크 만드세요!
Q. Django 연결 문자열 어떻게 써야 하나요?
A. 여러 서버 주소를 콤마로 나열하고 replicaSet=rs0 옵션 꼭 넣으세요!
Q. 2대만 잠깐 테스트해도 되나요?
A. 권장하지 않아요. 과반수 문제로 에러가 많이 날 거예요 😅
Q. PRIMARY 서버가 안 뜨는데요?
A. rs.status()로 상태 확인하고, 네트워크/포트/keyFile 순서로 점검해보세요!
Q. 멤버 추가할 때 서비스 중단되나요?
A. 잘하면 무중단 가능해요! 하나씩 천천히 추가하세요
Q. Secondary로 읽기 분산 어떻게 하나요?
A. ReadPreference 설정으로 가능해요. 부하 분산에 좋죠!
Q. 에러 로그는 어디서 보나요?
A. docker logs <컨테이너명>이나 MongoDB 로그 파일 확인하세요!
💡 실전 운영 꿀팁들
🔍 문제 해결의 왕도: 네트워크 먼저! 포트 열렸나? 서로 통신 되나? 이거부터 확인하세요
🏠 DNS 불안정할 땐 IP 우선: 초기 설정은 IP로, 안정화 후 호스트명으로 바꾸는 게 안전해요
📊 시스템 리소스 체크: ulimit 설정이나 연결 수 제한 때문에 "connection refused" 날 수도 있어요
🎭 장애 전환 연습: 가끔 PRIMARY 서버 재시작해보면서 자동 전환 잘 되는지 확인해보세요!
🚀 마무리하며...
핵심 정리: 3대 이상, keyFile 인증, 네트워크 연결만 제대로 하면 Docker에서도 MongoDB 레플리카셋 잘 돌아가요! IP 주소 먼저 쓰고, 에러 패턴 익혀두고, 상태 확인 명령어 외워두시면 삽질 시간이 확 줄어들 거예요 😊
다음 스텝: 이제 기본기는 마스터했으니, ReadPreference로 읽기 분산하고, 백업 전략 세우고, 모니터링 시스템 붙여보세요. 그리고 Django 커넥션 풀 설정도 한번 보시면 좋을 것 같아요!
실무에서 진짜 유용한 자료들 많이 참고했어요: MongoDB 공식 문서, Severalnines 블로그, 그리고 무엇보다 실제 삽질 경험담들! 🛠️
다들 MongoDB 레플리카셋 구축 파이팅! 🎉
멀티호스트(메인2개,보조섭1개) , 몽고당 독립 도커 컴포즈셋,
키파일 공유 필수, ip:포트연결 기본
ufw allow 192, 172~ 내부망 멀티호스트, 같은 도커네트워크여도 도커 브릿지대역
아니면 편하게 host모드, docker-user 포트제외도
댓글
댓글 로딩 중...