비슷한 포스트 를 올렸지만, 이번 프로젝트를 만들면서 또 헤메길래 제대로 기억하기 위해 다시 한번 포스트...
출저:레드헷
최근에 여러 서비스를 만들어보기도 하는데, 트래픽이 몰리지 않는 작은 서비스여서 마이크로 서비스 아키텍쳐 로 구축해보려고 한다.
1인터넷 (외부 사용자)2 ↓3 [도메인 요청]4 ↓5┌─────────────────────────────────────────┐6│ nginx-proxy (리버스 프록시) │ ← 포트 80/443 독점7│ "쇼핑몰 안내데스크 역할" │8└─────────────────────────────────────────┘9 ↓ (도메인별 라우팅)10 ┌────┴────┐11 ↓ ↓ ↓12[csmorning] [kidsbugs] [growpromise]13 ↓ ↓ ↓14┌─────────┐ ┌─────────┐ ┌─────────┐15│nginx-cs │ │nginx-kb │ │nginx-gp │ ← 각 서비스별 nginx16└─────────┘ └─────────┘ └─────────┘17 ↓ ↓ ↓18┌─────────┐ ┌─────────┐ ┌─────────┐19│front+api│ │front+api│ │ api │ ← 실제 애플리케이션20└─────────┘ └─────────┘ └─────────┘이렇게 구현을 했는데, 구글에 의하면
마이크로서비스 아키텍처(MSA)는 애플리케이션을 작은 독립적인 서비스 단위로 분할하여 구축하는 아키텍처 스타일입니다. 각 서비스는 특정 비즈니스 기능을 수행하며, 서로 독립적으로 배포, 확장 및 유지 보수할 수 있습니다.
최상위 : nginx-proxy(게이트웨이)
1포트: 80 (HTTP), 443 (HTTPS)2역할: 도메인별 트래픽 분산3위치: ~/nginx-proxy/동작 원리
- 모든 HTTP/HTTPS 요청을 받음
- Host 헤더를 보고 어느 서비스로 보낼지 결정
- SSL 인증서 관리
중간층 : 각 서비스별 nginx
1nginx-csmorning: 내부 포트 80, 외부 노출 없음2nginx-kidsbugs: 내부 포트 80, 외부 노출 없음 3nginx-growpromise: 내부 포트 80, 외부 노출 없음역할
- 정적 파일 서빙(HTML,CSS,JS)
- API 라우팅(/api -> 백엔드)
- 보안 헤더 추가
최하위 : 애플리케이션 컨테이너
1cs-morning:2 - landing-page-csmorning (프론트엔드)3 - api-server-csmorning (백엔드, 포트 3000)4
5kidsbugs:6 - landing-page-kidsbugs (프론트엔드) 7 - api-server-kidsbugs (백엔드, 포트 3000)8
9growpromise:10 - api-server-growpromise (백엔드, 포트 3000)네트워킹 구조
Docker 네트워크 격리
1csmorning-network: cs-morning 컨테이너들2kidsbugs-network: kidsbugs 컨테이너들 3growpromise-network: growpromise 컨테이너들ningx-proxy 연결
1# nginx-proxy가 모든 네트워크에 연결됨2networks:3 - csmorning-network # cs-morning과 통신4 - kidsbugs-network # kidsbugs와 통신 5 - growpromise-network # growpromise와 통신실제 요청 흐름
예시 1 : https://csmorning.co.kr/api/users 요청
11. 사용자 브라우저 → nginx-proxy (443포트)22. nginx-proxy → "csmorning.co.kr이니까 nginx-csmorning으로!"33. nginx-csmorning → "/api니까 api-server-csmorning:3000으로!"44. api-server-csmorning → 데이터베이스 조회55. 응답이 역순으로 돌아감예시 2 : https://growpromise.com/ 요청
11. 사용자 → nginx-proxy (443포트)22. nginx-proxy → "growpromise.com이니까 nginx-growpromise로!"33. nginx-growpromise → "/ 요청이니까 기본 응답 반환"44. "GrowPromise API Server" 텍스트 응답볼륨 마운트 구조
SSL 인증서 공유
1ningx-proxy 볼륨:2- ~/cs-morning-project/<SSL 인증서 받은 파일 경로>3- ~/growpromise-project/<SSL 인증서 받은 파일 경로>설정 파일 관리
1~/nginx-proxy/conf.d/2├── csmorning.conf # csmorning.co.kr 라우팅3├── kidsbugs.conf # kidsbugs.co.kr 라우팅4└── growpromise.conf # growpromise.com 라우팅이러한 구조의 장단점은?
확장성
- 새 서비스 추가 - 새폴더 + conf 파일 하나만 추가
- 기존 서비스에 영향 없음
격리성
- 각 서비스는 독립적인 네트워크
- 한 서비스 장애가 다른 서비스에 영향 업승ㅁ
유지보수성
- 각 서비스별로 개별 배포 가능
- 설정 변경이 간단함
보안성
- 외부에서는 nginx-proxy만 접근 가능
- 내부 서비스들은 완전히 숨겨짐
스스로 해보는 QnA
Q1. 이 구조가 진짜 마이크로서비스인가요? 단순히 멀티 테넌트 모놀리스 아닌가요? A1. 멀티테넌스 마이크로서비스 입니다. 독립 배포 + 도메인 분리 그리고 Docker로 격리 하지만, MSA 정의로 엄격하게 들어가면, 각 서비스마다 독립적인 데이터베이스가 없고, 완전히 다른 인프라에서 실행하지 않습니다 따라서 마이크로서비스의 성격을 가지고 있는 아키텍쳐입니다.
Q2. nginx-proxy가 SPOF(Single Point of Failure)가 되는 문제는 어떻게 해결하시겠어요? A2. nginx-proxy가 단일 장애점이 될 수 있습니다. 트래픽이 증가함에 따라 다르게 적용하는데, 3단계로 나누어 1단계에서는 nginx-proxy를 여러대로 구성, 2단꼐에서는 로드밸런서 앞단에 HAProxy 또는 AWS ALB 추가, 3단계는 Kubernetes 환경으로 이전할 것 같습니다.