네이버클라우드아카데미 Literacy 1기

[NCloud 1기] Naver Cloud Platform으로 3-Tier 아키텍처 구성하기

hwangsoojin 2025. 11. 18. 23:33

3-Tier 아키텍처 구성 미니 프로젝트

React + Spring Boot + NCP 인프라 구축 전체 요약 기록이다.


0. 프로젝트 전체 그림

이 프로젝트의 목표는 아주 명확하다.

React + Spring Boot 로 만든 “이미지 업로드 → NCP Image Optimizer로 300×300 리사이즈” 기능을
실제 Naver Cloud Platform(NCP)의 3-Tier 아키텍처(Web/WAS/DB) 위에 배포·운영해보는 것.

 

이를 하나의 흐름으로 보면 아래처럼 구성된다:

 
1. 로컬 개발 환경 & 코드 준비  
2. NCP 인프라(네트워크, 서버, DB, 스토리지) 만들기  
3. 서버 환경 설정 & 애플리케이션 배포  
4. 서비스 테스트 & 모니터링/백업 설정까지 확인

1. 로컬 프로젝트 구조 & 코드 준비

1-1. 폴더 구조

GitHub 레포지토리를 다음과 같이 구성했다:

 
ncp-3tier-image-platform/   ← GitHub 레포 루트
 ├─ backend/                ← Spring Boot 프로젝트
 ├─ frontend/               ← React 프로젝트
 ├─ architecture/           ← 아키텍처 다이어그램, mermaid 코드, 그림
 └─ README.md               ← 프로젝트 설명

 


1-2. GitHub 초기화

cd ncp-3tier-image-platform

git init
git add .
git commit -m "chore: initialize project structure"

git remote add origin https://github.com/abroniasj416/ncp-3tier-image-platform.git
git push -u origin main

 

이제부터 모든 커밋은 이 폴더에서 관리된다.


1-3. React 프론트엔드 준비

cd frontend
npm install
npm start
npm run build   # 빌드 파일은 frontend/build/ 에 생성됨
 

이 build 폴더가 나중에 WEB 서버의 /usr/share/nginx/html/로 올라가게 된다.

 

필요 기능

  • 파일 업로드
  • /api/images 로 multipart 요청 보내기
  • original URL / resized URL 표시

1-4. Spring Boot 백엔드 준비

필요한 dependencies:

  • Spring Web
  • Validation
  • Lombok
  • Spring Boot DevTools(선택)

빌드:

cd backend
./gradlew clean build
 

결과:

backend/build/libs/xxx.jar
 

이 JAR 파일이 WAS 서버에서 실행될 실제 애플리케이션이다.


2. NCP 인프라 만들기

아래는 내가 직접 설계한 3-Tier 아키텍처이다.


WEB–WAS–DB를 계층별로 분리하고,

Load Balancer를 통해 서버 부하를 분산하며,

SSL VPN·ACG를 활용해 외부로부터의 무분별한 접근을 통제하도록 구성했다.

IDS로 외부로부터의 침입을 탐지하도록 하였다.
또한 Object Storage와 Image Optimizer를 연동하여

이미지 리사이즈 기능을 구현하였다. 

Cloud Insight 모니터링을 더해,

실제 서비스 운영에 필요한 안정성과 관측성을 모두 갖춘 형태이다.

 

NCP 콘솔에서 모든 인프라를 손으로 구성한다. 이것이 참 신기하고 재미있다...


2-1. VPC & Subnet 구성 (서비스 전체의 네트워크 기반 설계)

 

VPC(Virtual Private Cloud)는 클라우드에서 독립된 프라이빗 네트워크를 만드는 서비스이며,
서브넷(Subnet)은 이 VPC 안에서 네트워크를 “용도별로 분리”해 구조적·보안적으로 안전한 환경을 만드는 핵심 요소이다.

✔ 적용 목적

  • 서비스 계층(Web/WAS/DB)을 물리적으로 분리하여 보안성 강화
  • Public/Private Subnet을 나눠 외부 노출 최소화
  • 앞으로 배포될 LB, WEB 서버, WAS 서버, Cloud DB의 배치 위치를 명확히 설계
  • 트래픽 흐름을 제어할 수 있는 기반(라우팅 테이블) 마련

✔ 구성 방법

  1. VPC 생성 ( 10.0.0.0/16 )
    • 충분히 넓은 주소 대역 확보
    • 이름:  image-platform-vpc 
  2. 서브넷 구성
    • Public Subnet (WEB/LB 용)
      • CIDR:  10.0.1.0/24 
      • Internet Gateway 연결되는 영역
    • Private Subnet (WAS/DB 용)
      • CIDR:  10.0.2.0/24 
      • 외부에서 직접 접근 불가
    • 필요 시 NAT Subnet 추가
  3. Route Table 구성
    • Public RT → IGW로 향하도록 설정
    • Private RT → NAT로 향하도록 설정
    • SSL VPN IP Pool 경로 추가

✔ 구성 후 기대 효과

  • 외부 접근이 필요한 요소(LB, WEB 서버)만 Public에 배치
  • 비즈니스 로직(WAS)과 데이터(DB)가 외부와 완전히 분리
  • 트래픽 흐름이 명확하게 통제되는 안정적 구조 확보

 

 


2-2. ACG(방화벽) 설계 (포트 기반 계층형 확보)

ACG(Access Control Group)는 서버에 접근할 수 있는 IP·포트·프로토콜을 정의하는 보안 계층으로,
3-Tier 구조에서는 WEB/WAS/DB 단계별로 권한을 분리하는 것이 핵심이다.

✔ 적용 목적

  • 계층 간 최소 권한 원칙(Least Privilege) 적용
  • 외부에서 Web Tier만 접근 가능하게 하고
    WAS/DB는 내부 트래픽만 허용
  • 아래 계층으로 내려갈수록 접근 범위를 좁혀 보안성 강화

✔ 구성 방법

acg-lb-public

  • 허용: 0.0.0.0/0 → 80, 443
  • 적용 대상: Load Balancer
  • 의미: 모든 외부 사용자는 LB만 접근 가능

acg-web

  • LB → 80
  • 내 IP → 22
  • SSL VPN → 22
  • HTTP → 80
  • HTTPS → 443
  • SSH(22)는 “운영자 IP 한정”
  • WEB 서버는 외부 사용자가 직접 접근하지 않음

acg-was

  • WEB → WAS API(8080)
  • WEB WAS SSH(22)
  • SSL VPN → 22
  • PUBLIC 접근 완전 차단

acg-db

  • WAS → 3306
  • 개발자 관리: SSL VPN IP Pool → 3306
  • 절대 Public 허용 없음

✔ 구성 후 기대 효과

  • 포트 기반 최소 공격 면적 확보
  • 외부 → WEB, WEB → WAS, WAS → DB 흐름만 허용
  • 모든 계층이 독립적으로 보호되는 탄탄한 구조


2-3. Server 인스턴스 생성 (WEB/WAS Tier 구성)

WEB/WAS 서버는 애플리케이션의 실제 실행 환경이며,
Subnet과 ACG 설계를 기반으로 계층별 역할이 명확히 나뉜 서버 구성이다.

✔ 적용 목적

  • WEB: 정적 파일 제공 + Nginx 리버스 프록시
  • WAS: Spring Boot 애플리케이션 실행
  • Public/Private Subnet에 맞는 서버 배치

✔ 구성 방법

▶ WEB 서버

  • OS: Rocky Linux 9
  • Subnet: Public
  • Security: acg-web
  • 공인 IP: 할당
  • 역할: React 정적 파일 제공, /api → WAS 프록시

▶ WAS 서버

  • OS: Rocky Linux 9
  • Subnet: Private
  • Security: acg-was
  • 공인 IP: 없음
  • 역할: Spring Boot backend 실행

✔ 구성 후 기대 효과

  • Public → WEB만 노출
  • WEB ↔ WAS 통신만 허용
  • Private Subnet의 WAS는 외부 접근 완전 차단


2-4. Cloud DB(MySQL) 구

Cloud DB(MySQL)는 데이터 저장 계층이며
Private Subnet에서만 접근 가능하도록 설계해야 한다.

✔ 적용 목적

  • 데이터 분리 및 보안 강화
  • 고가용성(다중화) / 자동 백업 지원
  • WAS에서만 접근 가능한 독립 데이터 계층 구성

✔ 구성 방법

  1. Cloud DB 생성
    • 타입: MySQL
    • 스펙: 4vCPU / 8GB
    • Region/Subnet: Private Subnet
  2. 네트워크 구성
    • ACG: acg-db
    • 포트: 3306
  3. 계정 생성
    •  appuser  + 강력한 패스워드

✔ 구성 후 기대 효과

  • 외부 접근 완전 차단 안전한 DB 운영
  • Cloud DB 다중화로 장애 대비
  • WAS에서만 접근 가능하므로 계층 분리 완성


2-5. Object Storage + Image Optimizer 구성

이미지 저장과 자동 리사이징을 담당하는 스토리지 시스템이다.

✔ 적용 목적

  • 파일을 서버 대신 Object Storage에 저장
  • Image Optimizer로 자동 리사이징
  • 스토리지 확장성 확보

✔ 구성 방법

  1. Object Storage 버킷 생성
    • 이름:  image-platform-bucket 
    • 권한: 기본 private
  2. Image Optimizer 생성
    • 원본 버킷 연결
    • 규칙 추가: 413×531 preset
    • CDN endpoint 제공됨 → backend 설정 필요

✔ 구성 후 기대 효과

  • WAS는 파일 저장 부담 ZERO
  • 자동 리사이징으로 자체 로직 필요 없음
  • 대규모 확장성 있는 이미지 처리


2-6. Backup Service 구성 (Cloud DB 백업)

백업은 예상치 못한 장애나 운영 실수를 대비한 필수 기능이다.

✔ 적용 목적

  • 데이터 유실 방지
  • 특정 시점 복구(정책 기반)
  • 운영 안정성 강화

✔ 구성 방법

  1. Backup → Cloud DB 선택
  2. 스케줄 생성
    • 시간: 06:00
    • 보관 기간: 30일
  3. 자동 백업 활성화

✔ 구성 후 기대 효과

  • 장애 시 즉시 복구 가능
  • 운영 실수(DDL, 삭제 등)에도 대비
  • 데이터 스냅샷 관리 자동화


2-7. Cloud Insight 구성(서버 모니터링 및 알림) 

Cloud Insight는 NCP의 실시간 모니터링 도구이다.

✔ 적용 목적

  • WEB/WAS/DB 리소스 실시간 모니터링
  • 트래픽 증가 조기 감지
  • 장애 알림으로 빠른 대응

✔ 구성 방법

  1. Cloud Insight → 리소스 등록
  2. 알림 정책 생성
    • CPU 80% 경고 / 90% 심각
    • Memory 80% 경고
    • Disk 80% 경고
  3. 알림 채널 설정

✔ 구성 후 기대 효과

  • 장애 발생 전 조기 감지
  • 대시보드에서 전체 상태 한눈에 파악
  • Auto Scaling 근거 데이터 활용 가능


2-8. Load Balancer 생성 (트래픽 분산 · 장애 조치)

Load Balancer는 사용자 요청을 WEB 서버로 분산시키고,
서버 장애 시 자동으로 다른 서버로 우회시킨다.

✔ 적용 목적

  • 웹 트래픽 부하 분산
  • 무중단 서비스 구성
  • Health Check 기반 장애 자동 조치

✔ 구성 방법

  1. LB 생성 (HTTP/HTTPS)
  2. Target Group 생성
  3. WEB 서버 등록
  4. Health Check 설정  /health 
  5. Public Subnet 연결
  6. ACG → acg-lb-public 적용

✔ 구성 후 기대 효과

  • 트래픽 증가에도 안정적인 서비스
  • 서버 1대 장애 시 서비스 중단 없음
  • WEB Tier 확장성 확보


2-9. IDS 구성 (웹 서버 공격 탐지)

IDS(침입 탐지 시스템)는 외부에서 WEB 서버로 들어오는 비정상적인 트래픽이나 공격 패턴을 탐지해주는 보안 계층이다.
특히 Public Subnet에 위치한 WEB 서버는 외부에 노출되어 있기 때문에 IDS 적용이 매우 중요하다.

✔ 적용 목적

  • WEB 서버로 들어오는 공격 패턴 탐지
  • 포트 스캐닝, 비정상 요청, 봇/크롤링 과도 요청 감지
  • 보안 인시던트 발생 시 관리자 알림
  • ACG 기반 ‘접근 차단’ + IDS 기반 ‘행위 탐지’로 다중 보안 구조 구성

✔ 구성 방법

  1. Network Security → IDS 메뉴 이동
  2. 새로운 IDS 그룹 생성
    • 이름: proj-ids-web
  3. WEB 서버 혹은 WEB ACG 연결
  4. 탐지 프로파일 선택
    • 기본: NCP 기본 정책
    • 탐지 레벨 중 “중간~높음” 권장
  5. 알림 설정
    • 이메일/SMS/콘솔 알림 연결
  6. 정책 적용 후 탐지 로그 확인 가능

✔ 구성 후 기대 효과

  • 외부 공격 패턴(Injection, Scanning 등) 실시간 탐지
  • WEB Tier 보안성을 한 단계 높임
  • SSL VPN·ACG·IDS가 함께 작동하여 방어 + 탐지 + 내부망 보호 구조 완성


2-10. Auto Scaling (WEB/WAS 서버 자동 확장)

Auto Scaling Group(ASG)은 트래픽 증가·감소에 따라
자동으로 서버를 늘리거나 줄여주는 기능이다.

✔ 적용 목적

  • 트래픽 변동 대응
  • 비용 최적화
  • 장애 조치 자동화

✔ 구성 방법

  1. Launch Configuration 생성
    • OS/스펙/Nginx 또는 Spring Boot 환경 포함
  2. Auto Scaling Group 생성
    • 최소 용량: 1
    • 기대 용량: 1
    • 최대 용량: 2
  3. 스케줄링 정책 생성
    • 예: 매달 1~3일 2대로 증가
  4. 헬스 체크 연동
    • LB Health Check와 연동하도록 설정

✔ 구성 후 기대 효과

  • 트래픽 증가에 자동 확장
  • 비용 효율적 서버 운영
  • 장애 서버 자동 교체로 높은 안정성


3. 서버 환경 설정 & 애플리케이션 배포

(이제부터 PuTTY / WinSCP / Big-IP SSL VPN이 본격 활용된다)

WEB 서버와 WAS 서버는 각각 다른 Subnet에 존재하며 역할도 다르기 때문에,
배포 과정에서도 접근 방식과 설정이 달라진다.

  • WEB 서버 → Public Subnet → SSH 바로 접속 가능
  • WAS 서버 → Private Subnet → SSH 불가능 → 반드시 SSL VPN 연결 후 접속해야 함

이 섹션에서는 두 서버의 환경을 실제로 운영 가능한 형태로 구축한다.


3-1. WEB 서버 설정 (Nginx + React 정적 파일 제공)

WEB 서버는 Public Subnet에 있기 때문에 외부에서 직접 접속 가능하다.
따라서 첫 단계는 PuTTY로 SSH 접속하는 것부터 시작한다.


▶ (1) PuTTY로 WEB 서버 SSH 접속

✔ 적용 목적

  • WEB 서버에 원격 접속해 Nginx 설치 및 설정 수행
  • React 빌드 파일을 배포할 수 있는 환경 구축

✔ 구성 방법

  1. PuTTY 실행
  2.  Host Name  → WEB 서버의 공인 IP 입력
  3.  Port 22  유지
  4. SSH 인증 → PPK 키 파일 등록
  5. Open 클릭하여 접속

✔ 구성 후 기대 효과

  • 터미널에서 WEB 서버 제어 가능
  • Nginx 설치·정적 파일 배포 모두 이 접속으로 진행

▶ (2) Nginx 설치 및 서비스 활성화

Nginx는 정적 파일을 제공하고 WAS 서버로의 프록시 역할을 동시에 수행한다.

✔ 명령어

sudo yum update -y
sudo yum install nginx -y
sudo systemctl enable --now nginx
 

✔ 설명

  •  yum update  : OS 패키지 최신화
  •  nginx install  : 웹 서버 설치
  •  enable --now  : 부팅 시 자동 실행 + 즉시 실행

✔ 구성 후 기대 효과

  • WEB 서버에서 React 정적 파일 제공 가능
  •  /api  요청을 WAS로 프록시할 준비 완료

▶ (3) React 빌드 파일 업로드 (WinSCP 사용)

WinSCP는 로컬과 서버 간 파일 이동을 위한 GUI 도구이다.

✔ 적용 목적

  • React 빌드 결과물을 WEB 서버에 올려 실제 서비스 화면을 제공

✔ 구성 방법

1. 로컬 PC에서 React 프로젝트 실행

npm run build

→  frontend/build/  폴더 생성

2. WinSCP 실행

3. 접속 옵션:

  • 호스트: WEB 공인 IP
  • 사용자 계정: root 또는 centos
  • 인증키(키페어) 등록

4. 원격 경로 이동:
 /usr/share/nginx/html/ 

5. 로컬  build/  폴더 내 파일 전체를 HTML 폴더로 드래그

6. 기존 기본 index.html 덮어쓰기

📌 [이미지 위치 – WinSCP 파일 업로드 화면]

✔ 구성 후 기대 효과

  • React 화면이 실제 WEB 서버에서 제공됨
  • 브라우저 접속 시 LB 없이도 테스트 가능

▶ (4) Nginx → WAS 프록시 설정

React는 /api 요청을 WAS로 전달해야 한다.
WEB → WAS는 Private network로 연결되어 있으므로 proxy_pass 설정이 필수다.

✔ 설정 파일 수정

sudo vi /etc/nginx/nginx.conf
 

server 블록 안에 추가:

location /api/ {
    proxy_pass http://WAS_PRIVATE_IP:8080/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}
 

✔ 설정 반영

sudo nginx -t     # 설정 문법 검사
sudo systemctl reload nginx
 

✔ 구성 후 기대 효과

  • 프론트엔드는  http://WEB_IP/api/...  로 호출하고
  • Nginx가 자동으로 WAS로 요청 전달

3-2. WAS 서버 설정 (Java + Spring Boot 배포)

WAS 서버는 Private Subnet에 있으므로
SSL VPN 연결 없이는 절대 접속할 수 없다.


▶ (1) Big-IP Edge Client로 SSL VPN 접속

✔ 적용 목적

  • Private Subnet에 있는 WAS·DB에 접근하기 위한 유일한 방법
  • 내부망 접근 시 보안 규칙(ACG+라우팅테이블)이 적용됨

✔ 구성 방법

  1. Big-IP Edge Client 실행
  2. 접속 URL 입력 (예:  https://sslvpn-kr-vpc-02.ncloud.com )
  3. 아이디/비밀번호 입력
  4. “Connected” 상태 확인

📌 [이미지 위치 – Big-IP Edge Client 접속 화면]

✔ 구성 후 기대 효과

  • 사설 IP(WAS Private IP)로 직접 SSH 접속 가능
  • 운영자만 접근 가능한 안전한 내부망 구성

▶ (2) PuTTY로 WAS 서버 SSH 접속

이제 WAS의 Private IP로 접속이 가능해진다.

  • Host:  10.0.2.x  (WAS Private IP)
  • Port 22
  • 키 파일 등록 → 접속

✔ 구성 후 기대 효과

  • 백엔드 애플리케이션 배포 가능
  • application.yml 편집·로그 확인 가능

▶ (3) Java 설치 (Spring Boot 실행 환경)

 
sudo yum install -y java-17-openjdk
java -version

✔ 설명

  • Spring Boot JAR 파일은 Java 환경에서 실행되므로 필수

▶ (4) Spring Boot JAR 업로드 (WinSCP)

✔ 경로 예

 
/home/centos/app/app.jar

✔ 구성 방법

  • WinSCP로 WAS 서버 접속
  •  /home/centos/app/  폴더 생성
  • 로컬에서  build/libs/*.jar  업로드

▶ (5) application.yml 설정

이 파일에는 DB 정보, Object Storage 설정, Image Optimizer base URL 등이 들어간다.

예시:

 
spring:
  datasource:
    url: jdbc:mysql://CLOUD_DB_PRIVATE_IP:3306/image_platform
    username: appuser
    password: strongpassword

▶ (6) Spring Boot 실행 (systemd 서비스)

운영 환경에서는 백엔드가 재부팅해도 자동 실행되어야 한다.
이를 위해 systemd 서비스를 만든다.

✔ 서비스 생성

sudo vi /etc/systemd/system/imageapp.service
 

✔ 서비스 파일 예시

(초안 그대로)

✔ 서비스 적용

sudo systemctl daemon-reload
sudo systemctl enable --now imageapp
sudo systemctl status imageapp
 

✔ 구성 후 기대 효과

  • 서버 재부팅 시 자동 실행
  • 로그 관리  /var/log/messages   / journalctl 가능
  • 운영 환경에서 필수적인 안정성 확보

4. 서비스 테스트 & 마무리

4-1. 내부 테스트 (서버 간 연결 확인)

▶ WAS → DB 연결 테스트

DB 커넥션 설정이 올바른지 확인:

mysql -h CLOUD_DB_PRIVATE_IP -u appuser -p
 

문제 없으면 MySQL 프롬프트 진입.


▶ WEB → WAS 연결 테스트

Nginx 프록시 설정 확인:

curl http://WAS_PRIVATE_IP:8080/health
 

정상일 경우:

{"status":"UP"}

4-2. 외부 테스트 (사용자 기준 테스트)

Load Balancer DNS 또는 Public IP 입력:

http://LOADBALANCER_DNS
 

✔ 확인해야 할 UI 흐름

  • React 페이지 정상 렌더링
  • 파일 업로드 버튼 클릭
  • 원본 이미지 미리보기 표시
  • resized(413×531) 이미지 표시
  • 네트워크 탭에서  /api/images  요청 성공 확인

4-3. Cloud Insight 모니터링 확인

Cloud Insight 콘솔에서 다음을 확인한다:

✔ WEB/WAS 서버

  • CPU 사용률
  • Memory 사용률
  • Disk 사용률
  • 네트워크 트래픽

✔ Cloud DB

  • Connection 수
  • CPU/Memory
  • 스토리지 용량 증가 추세

✔ 구성 후 기대 효과

  • 장애 징후 실시간 탐지
  • 트래픽 증가 시 Auto Scaling 판단
  • 운영 상태를 한눈에 파악 가능

5. 요약 한 줄

React/Spring Boot 기능을 만들고 →
NCP에서 VPC/Subnet/ACG/Server/LB/DB/Object Storage/Image Optimizer를 구성해 →
WinSCP로 배포하고 PuTTY로 실행시키고 SSL VPN으로 내부망을 관리하면서
3-Tier 구조의 실제 서비스 운영 흐름을 완성했다.