05.3.Clouds‐AWS - yojulab/learn_DevOps GitHub Wiki

AWS 주요 서비스 개요

**AWS(Amazon Web Services)**는 클라우드 컴퓨팅 플랫폼으로 다양한 서비스를 제공합니다.

서비스 설명 주요 용도
EC2 Elastic Compute Cloud 가상 서버 제공, 유연한 컴퓨팅 환경 구성
S3 Simple Storage Service 객체 스토리지, 대규모 데이터 저장 및 관리
RDS Relational Database Service 관계형 DB 관리 자동화 (MySQL, PostgreSQL 등)
Lambda 서버리스 컴퓨팅 서버 관리 없이 코드 실행, 이벤트 기반 자동 실행

사용 기호 설명

기호 의미
@ 브라우저
~$ EC2 인스턴스 터미널
~# EC2 내 Docker 컨테이너
> 별도 터미널

1. AWS EC2 인스턴스 생성 및 기본 설정

EC2 인스턴스 생성 플로우

graph TB
    A[AWS 콘솔] --> B[EC2 대시보드]
    B --> C[인스턴스 시작]
    C --> D[인스턴스 구성]
    D --> E[키 페어 생성]
    E --> F[보안 그룹 설정]
    F --> G[인스턴스 시작]
    G --> H[SSH 접속]
    
    subgraph 인스턴스_구성
        D1[이름: team-spring-mysql-fastapi]
        D2[AMI: Ubuntu 20.04 LTS]
        D3[유형: t2.medium]
        D4[스토리지: 50GB]
    end
    
    subgraph 보안_그룹
        F1[SSH: 22]
        F2[HTTP: 80]
        F3[HTTPS: 443]
    end
    
    D --> D1
    D --> D2
    D --> D3
    D --> D4
    F --> F1
    F --> F2
    F --> F3

EC2 인스턴스 생성 과정

@ AWS Management Console > EC2 > 인스턴스 시작

# 인스턴스 설정
- 이름: team-spring-mysql-fastapi
- AMI: Ubuntu 20.04 LTS
- 인스턴스 유형: t2.medium
- 키 페어: 새로 생성 후 다운로드 (.pem 파일)
- 스토리지: 50GB
- 보안 그룹: HTTP(80), HTTPS(443), SSH(22) 포트 허용

# SSH 접속 방법 1: AWS 콘솔
@ 인스턴스 선택 > 연결 > EC2 Instance Connect

# SSH 접속 방법 2: 로컬 터미널
$ ssh -i "your-key.pem" ubuntu@[EC2-PUBLIC-IP]

기본 패키지 설치

~$ sudo apt-get update && sudo apt-get install -y unzip docker-compose nginx certbot python3-certbot-nginx dnsutils nano vim

# Docker Compose 설치
~$ sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-linux-x86_64" -o /usr/local/bin/docker-compose
~$ sudo chmod +x /usr/local/bin/docker-compose
~$ docker-compose --version

# 시스템 리소스 확인
~$ lscpu
~$ df -h
~$ sudo systemctl status nginx
~$ sudo tail -f /var/log/nginx/access.log
~$ sudo tail -f /var/log/nginx/error.log

# 초기 웹 서버 테스트
~$ wget 127.0.0.1
@ http://[EC2-PUBLIC-IP]/

2. DNS 관리 및 서브도메인 설정

DNS 설정 옵션 비교

방법 장점 단점 추천 상황
외부 DNS (가비아 등) 기존 도메인 활용 별도 관리 필요 기존 도메인 보유 시
AWS Route 53 AWS 통합 관리 추가 비용 발생 AWS 전용 환경 구축 시

가비아 DNS 설정

@ https://dns.gabia.com/
> 도메인 관리 > 'cocolabhub.store' 선택
> DNS 레코드 설정:
  - @ (A 레코드) → EC2 Public IP
  - www (A 레코드) → EC2 Public IP
  - fast (A 레코드) → EC2 Public IP

# DNS 전파 확인
~$ nslookup cocolabhub.store
~$ nslookup www.cocolabhub.store
~$ nslookup fast.cocolabhub.store

AWS Route 53 설정 (대안)

@ AWS Console > Route 53 > 호스팅 영역 생성
- 도메인 이름: 'cocolabhub.store'
- A 레코드 생성:
  - @ → EC2 Public IP
  - www → EC2 Public IP
  - fast → EC2 Public IP

3. Docker 컨테이너 설치 및 구성

Docker 환경 구성

~$ sudo docker system prune

@ https://cocolabhub.com/teams/list
> 원하는 팀의 'shell' 버튼 클릭

~$ wget -O docker_files.zip http://cocolabhub.com/comodules/r/download/[66e10f1ba5684486c3b91b3a]
~$ unzip docker_files.zip -d docker_folder && cd ./docker_folder

~/docker_folder$ sudo docker-compose build --no-cache
~/docker_folder$ sudo docker-compose --project-name teams_java_jupyterlab_mysql up -d

# 컨테이너 상태 확인
~$ sudo docker ps
~$ sudo docker exec -it [java_springboot_mysql-springboot_3.1_fastapi-1] bash

4. FastAPI 서버 설정

FastAPI 서버 구성 및 실행

# 기존 FastAPI 프로세스 확인 및 종료
~# ps aux | grep uvicorn 
~# kill -9 [PID]

# 필요 패키지 설치
~# apt-get update && apt-get install -y nano

# 환경 설정 파일 편집
~# cd /apps/fastapis/app && nano .env

# 최신 코드 업데이트
/apps/fastapis/app# cd ../ && git pull

# FastAPI 서버 백그라운드 실행
/apps/fastapis# nohup uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 --workers 2 & 
/apps/fastapis# tail -f nohup.out 

# 로컬 테스트
outside_docker:~$ wget http://localhost:8000

5. Spring Boot 서버 설정

Spring Boot 애플리케이션 구성

# 기존 Spring Boot 프로세스 확인 및 종료
~# ps aux | grep gradlew 
~# kill -9 [PID]

# 설정 파일 편집
~# cd /apps/springboots && nano ./src/main/resources/application.properties

application.properties 핵심 설정

server.address=0.0.0.0
server.port=8080
spring.datasource.url=jdbc:mysql://[db_mysql_8]:3306/cocolabhub
remote.server.url=https://fast.cocolabhub.store/images/

Spring Boot 서버 실행

/apps/springboots# chmod +x ./gradlew && nohup ./gradlew bootRun & 
/apps/springboots# tail -f nohup.out 
/apps/springboots# exit

# 로컬 테스트
outside_docker:~$ wget http://localhost:8080

6. HTTPS 인증서 및 Nginx 설정

SSL 인증서 발급 (멀티 도메인)

# 모든 도메인에 대해 SSL 인증서 발급
~$ sudo certbot --nginx -d cocolabhub.store -d www.cocolabhub.store -d fast.cocolabhub.store

Nginx 설정 파일 구성

~$ sudo rm /etc/nginx/sites-available/default
~$ sudo nano /etc/nginx/sites-available/default

완전한 Nginx 설정

# HTTP to HTTPS 리다이렉트
server {
    listen 80;
    server_name cocolabhub.store www.cocolabhub.store fast.cocolabhub.store;
    
    # Let's Encrypt 인증을 위한 예외 처리
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }
    
    # 모든 HTTP 요청을 HTTPS로 리다이렉트
    location / {
        return 301 https://$server_name$request_uri;
    }
}

# HTTPS - Spring Boot (메인 도메인)
server {
    listen 443 ssl http2;
    server_name cocolabhub.store www.cocolabhub.store;
    
    # SSL 인증서 경로
    ssl_certificate /etc/letsencrypt/live/cocolabhub.store/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cocolabhub.store/privkey.pem;
    
    # SSL 보안 설정
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    # HSTS 보안 헤더
    add_header Strict-Transport-Security "max-age=31536000" always;
    
    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

# HTTPS - FastAPI (서브도메인)
server {
    listen 443 ssl http2;
    server_name fast.cocolabhub.store;
    
    # SSL 인증서 경로 (메인 도메인과 동일)
    ssl_certificate /etc/letsencrypt/live/cocolabhub.store/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cocolabhub.store/privkey.pem;
    
    # SSL 보안 설정
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    # HSTS 보안 헤더
    add_header Strict-Transport-Security "max-age=31536000" always;
    
    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

Nginx 설정 적용 및 테스트

# 설정 파일 문법 검사
~$ sudo nginx -t

# Nginx 서비스 재시작
~$ sudo systemctl restart nginx

# 서비스 상태 확인
~$ sudo systemctl status nginx

7. 서비스 접속 확인 및 테스트

최종 서비스 매핑

서비스 URL 대상 서버 포트
Spring Boot (HTTPS) https://cocolabhub.store/ EC2 :8080 443
Spring Boot (HTTPS) https://www.cocolabhub.store/ EC2 :8080 443
FastAPI (HTTPS) https://fast.cocolabhub.store/ EC2 :8000 443
이미지 서비스 (HTTPS) https://fast.cocolabhub.store/images/empty.txt EC2 :8000 443

접속 테스트 명령어

# HTTPS 접속 테스트
@ https://cocolabhub.store/ → Spring Boot
@ https://www.cocolabhub.store/ → Spring Boot  
@ https://fast.cocolabhub.store/ → FastAPI
@ https://fast.cocolabhub.store/images/empty.txt → FastAPI

# cURL을 통한 상태 확인
~$ curl -I https://cocolabhub.store/
~$ curl -I https://fast.cocolabhub.store/
~$ curl -k https://fast.cocolabhub.store/images/empty.txt

8. AWS 보안 그룹 최적화

보안 그룹 권장 설정

프로토콜 포트 소스 목적
SSH 22 My IP (권장) 관리 접속
HTTP 80 0.0.0.0/0 HTTPS 리다이렉트용
HTTPS 443 0.0.0.0/0 웹 서비스
Custom 8080 내부 전용 Spring Boot (선택)
Custom 8000 내부 전용 FastAPI (선택)

보안 그룹 수정 방법

@ AWS Console > EC2 > 보안 그룹
> 인스턴스의 보안 그룹 선택 > 인바운드 규칙 편집
> 필요한 포트만 열고 불필요한 포트는 제거

9. 유지보수 및 모니터링

SSL 인증서 자동 갱신

# 자동 갱신 테스트
~$ sudo certbot renew --dry-run

# 자동 갱신 스케줄 설정
~$ sudo crontab -e
# 다음 라인 추가:
# 0 12 * * * /usr/bin/certbot renew --quiet && systemctl reload nginx

AWS CloudWatch 모니터링 설정 (선택사항)

# CloudWatch 에이전트 설치 (선택사항)
~$ wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
~$ sudo rpm -U ./amazon-cloudwatch-agent.rpm

로그 모니터링

# 시스템 로그 확인
~$ sudo docker logs [CONTAINER_NAME]
~$ sudo tail -f /var/log/nginx/access.log
~$ sudo tail -f /var/log/nginx/error.log

# 서비스 상태 확인
~$ sudo systemctl status nginx
~$ sudo docker ps -a

10. 트러블슈팅 가이드

일반적인 문제 및 해결방법

문제 증상 해결 방법
SSL 인증서 오류 "Not Secure" 표시 sudo certbot renew 실행
502 Bad Gateway Nginx 오류 페이지 백엔드 서버 상태 확인
서브도메인 접속 불가 DNS 해석 실패 nslookup fast.cocolabhub.store 확인
Docker 컨테이너 중단 서비스 응답 없음 sudo docker-compose restart
보안 그룹 오류 연결 거부 AWS 콘솔에서 포트 확인

단계별 문제 해결

# 1. 서비스 상태 전체 확인
~$ sudo systemctl status nginx
~$ sudo docker ps -a
~$ sudo netstat -tlnp | grep -E ':80|:443|:8000|:8080'

# 2. 로그 확인
~$ sudo tail -20 /var/log/nginx/error.log
~$ sudo docker logs --tail 50 [CONTAINER_NAME]

# 3. 서비스 재시작 (순서 중요)
~$ sudo docker-compose restart
~$ sudo systemctl restart nginx

# 4. 전체 시스템 재부팅 (최후 수단)
~$ sudo reboot

11. AWS 비용 최적화 팁

비용 절약 방법

방법 설명 예상 절약
Reserved Instance 1년 약정으로 할인 최대 75%
Spot Instance 유휴 용량 활용 최대 90%
인스턴스 크기 최적화 적절한 크기 선택 20-50%
불필요 리소스 정리 미사용 EBS, EIP 제거 변동적

모니터링 설정

@ AWS Console > CloudWatch > 빌링 알람 설정
- 월 사용량 $10 초과시 알림 설정
- 인스턴스 CPU 사용률 모니터링

14. 참고 자료

유용한 링크

구분 링크 설명
AWS 공식 EC2 사용 가이드 공식 문서
블로그 EC2 생성하기 실습 가이드
YouTube AWS EC2 & ELB & WAF 완전 가이드 영상 튜토리얼
Nginx 설정 default_nginx_config 설정 파일 예제