[CL] v3 인프라 구성 문서화 - 100-hours-a-week/6-nemo-wiki GitHub Wiki

1. 인프라 구성

🏗️ 전체 아키텍처

V3는 GCP에서 AWS로 완전 마이그레이션하여 AWS 단일 클라우드 기반의 완전한 클라우드 네이티브 인프라를 구축했습니다. EKS 클러스터에서 핵심 애플리케이션이 실행되고, AI 서버는 별도의 EC2 인스턴스에서 컨테이너로 운영되는 AWS 통합 아키텍처입니다. 모든 인프라는 Terraform을 통해 Infrastructure as Code로 관리됩니다.

📋 인프라 구성 요소

🌐 VPC 및 네트워킹 (AWS)

VPC: 10.0.0.0/16 (AWS Seoul Region)
├── Public Subnets
│   ├── 10.0.1.0/24 (ap-northeast-2a) - ALB, Bastion, NAT Gateway
│   └── 10.0.2.0/24 (ap-northeast-2b) - ALB 고가용성
├── Private Subnets  
│   ├── 10.0.3.0/24 (ap-northeast-2a) - EKS Nodes, RDS
│   ├── 10.0.4.0/24 (ap-northeast-2b) - EKS Nodes, RDS
│   └── 10.0.5.0/24 (ap-northeast-2c) - EKS Nodes, RDS
├── Internet Gateway - 외부 인터넷 연결
└── NAT Gateway - Private 서브넷 아웃바운드 트래픽

📍 각 서브넷별 상세 구성

Public Subnets

10.0.1.0/24 (ap-northeast-2a):

  • Bastion Host (t2.medium): SSH 접근점 및 관리 서버
  • NAT Gateway: Private 서브넷 아웃바운드 트래픽 처리

10.0.2.0/24 (ap-northeast-2b):

  • AI 서버 - VLLM (g5.xlarge): GPU 기반 LLM 추론 서버
  • AI 서버 - FastAPI (t3.medium): CPU 기반 AI API 서버

Private Subnets

10.0.3.0/24 (ap-northeast-2a):

  • EKS Worker Node 1: Kubernetes 워크로드 실행
  • RDS MySQL: 데이터베이스 (Multi-AZ 구성)

10.0.4.0/24 (ap-northeast-2b):

  • EKS Worker Node 2: Kubernetes 워크로드 실행
  • RDS Standby: Multi-AZ 백업 인스턴스

10.0.5.0/24 (ap-northeast-2c):

  • EKS Worker Node 3: Kubernetes 워크로드 실행

🤖 AI 서버 (AWS EC2 컨테이너 구성)

VLLM GPU 서버 (10.0.2.0/24):
  인스턴스: g5.xlarge (NVIDIA A10G GPU)
  위치: ap-northeast-2b Public Subnet
  컨테이너: vllm/vllm-openai:latest
  포트: 8002
  용도: LLM 추론 및 텍스트 생성
  
FastAPI CPU 서버 (10.0.2.0/24):
  인스턴스: t3.medium × 2
  위치: ap-northeast-2b Public Subnet  
  컨테이너: 
    - ai-prod: 8000 포트 (프로덕션 API)
    - ai-dev: 8001 포트 (개발 API)
  레지스트리: ECR (084375578827.dkr.ecr.ap-northeast-2.amazonaws.com)
  
컨테이너 런타임:
  - Docker Engine 기반
  - GPU 런타임 지원 (VLLM)
  - 모델 저장: EBS 볼륨 마운트

주요 특징:

  • 3개 가용영역: 고가용성을 위한 Multi-AZ 구성 (AWS)
  • 공개/비공개 분리: 보안을 위한 계층화된 네트워크 구조
  • Kubernetes 태그: EKS ALB 컨트롤러를 위한 서브넷 태그 설정
  • AI 서버 분리: GPU/CPU 워크로드별 인스턴스 최적화
  • 통합 네트워킹: VPC 내부에서 EKS ↔ AI 서버 간 고속 통신

⚙️ EKS 클러스터 (AWS)

클러스터 설정:
  이름: nemo_EKS_kluster
  버전: Kubernetes 1.33
  위치: Private Subnets (3개 AZ)
  
노드 그룹:
  이름: nemo_node_group
  인스턴스 타입: t3.large (2 vCPU, 8GB RAM)
  노드 수: 3개 (고정)
  디스크: 20GB EBS (각 노드)
  키페어: keypair-kube-master

실행 중인 워크로드:
  - Frontend (React): 3 replicas
  - Backend (Spring Boot): 3 replicas  
  - Kafka: 3 brokers (Stateful)
  - Redis: Master/Slave 구성
  - Zookeeper: 3 nodes ensemble
  - Sentinel: Redis 모니터링
  - ArgoCD: GitOps 배포 도구
  - ArgoCD Image Updater: 자동 이미지 업데이트

보안 그룹 설정:

  • NodePort 범위: 30000-32767 (Kafka 외부 접근용)
  • Kafka 전용 포트: 9094 (AI 서버 → EKS 통신)
  • HTTPS: 443 (ALB 트래픽)
  • SSH: 22 (VPC 내부만, Bastion 경유)
  • AI API 포트: 8000-8002 (EKS Backend → AI 서버)

🗄️ 데이터베이스 (RDS)

RDS MySQL 설정:
  식별자: nemo-db-instance
  엔진: MySQL 8.0
  인스턴스 클래스: db.t3.micro
  스토리지: 20GB
  데이터베이스명: prod_db
  사용자명: prod
  Multi-AZ: 활성화 (고가용성)
  암호화: 활성화
  위치: Private Subnets

연결 설정:

  • VPC 보안 그룹: EKS 클러스터에서만 접근 허용
  • 서브넷 그룹: 3개 Private 서브넷에 배치
  • 공개 접근: 비활성화 (보안)

🖥️ Bastion Host (AWS)

Bastion 설정:
  인스턴스 타입: t2.medium
  AMI: ami-0662f4965dfc70aca (Amazon Linux 2)
  위치: Public Subnet (ap-northeast-2a)
  키페어: keypair-kube-master
  탄력적 IP: 고정 공인 IP 할당

용도:

  • SSH 접근점: EKS 노드 및 Private 리소스 관리
  • 보안 게이트웨이: Private 리소스 접근을 위한 점프 서버
  • 관리 도구: kubectl, aws-cli 등 운영 도구
  • 디버깅: 클러스터 내부 네트워크 문제 해결

🌍 DNS 및 로드밸런싱

Route53

도메인 설정:
  도메인명: onurivit01.store
  타입: Public Hosted Zone
  레코드: ALB와 연결된 A 레코드

Application Load Balancer (ALB)

ALB 컨트롤러:
  설치: Helm Chart (aws-load-balancer-controller)
  네임스페이스: kube-system
  버전: 1.7.1
  IRSA: ALB 컨트롤러용 IAM 역할 연결

☁️ AWS 통합 서비스

ECR (Elastic Container Registry) - 통합 관리

레지스트리:
  계정: 084375578827
  리전: ap-northeast-2
  리포지토리:
    - backend: Spring Boot API 서버
    - frontend: React 웹 애플리케이션

이미지 태그 규칙:
  형식: prod-YYYYMMDD-HHMM
  예시: 
    - backend: prod-20250714-1752
    - frontend: prod-20250718-1040
  자동화: ArgoCD Image Updater가 최신 태그 감지

Lambda 함수

EC2 제어 Lambda:
  함수명: eks-ec2-startstop
  런타임: Node.js 18.x
  용도: EKS 노드 자동 시작/중지
  트리거: CloudWatch Events/Manual

Lambda 코드 구조:

// 환경변수 기반 EC2 인스턴스 제어
const action = process.env.ACTION; // 'start' or 'stop'
const instanceIds = process.env.INSTANCE_IDS.split(',');

🔧 Terraform 모듈 구조

v3/modules/
├── vpc/                    # VPC, 서브넷, 라우팅 테이블, IGW, NAT
├── eks/                    # EKS 클러스터, 노드 그룹, IAM 역할, 보안 그룹
├── rds/                    # RDS MySQL, 서브넷 그룹, 보안 그룹  
├── bastion/                # Bastion 호스트, 보안 그룹
├── route53/                # DNS 호스팅 존, 레코드
├── ALB/                    # ALB Ingress Controller, IAM 역할
├── ebs/                    # EBS CSI Driver, IRSA 설정
├── secret/                 # External Secrets Operator
├── lambda/                 # EC2 제어 Lambda, IAM 정책
├── argocd/                 # ArgoCD Helm 차트 배포
└── argocd_image_updater/   # 이미지 자동 업데이트, IRSA

주요 모듈별 역할

VPC 모듈

# 네트워크 인프라 전체 구성
resource "aws_vpc" "this" {
  cidr_block           = var.vpc_cidr
  enable_dns_support   = true
  enable_dns_hostnames = true
}

# Kubernetes 태그 설정
tags = {
  "kubernetes.io/role/elb"                     = "1"      # Public
  "kubernetes.io/role/internal-elb"            = "1"      # Private  
  "kubernetes.io/cluster/nemo_EKS_kluster"     = "owned"
}

EKS 모듈

# 클러스터 및 노드 그룹 구성
resource "aws_eks_cluster" "this" {
  name     = var.cluster_name
  version  = var.cluster_version
  role_arn = aws_iam_role.cluster.arn
  
  vpc_config {
    subnet_ids = var.subnet_ids  # Private 서브넷
  }
}

# IRSA (IAM Roles for Service Accounts) 설정
resource "aws_iam_openid_connect_provider" "this" {
  client_id_list = ["sts.amazonaws.com"]
  url = aws_eks_cluster.this.identity[0].oidc[0].issuer
}

🔐 보안 구성

IAM 역할 및 정책

주요 IAM 역할:
  - EKS 클러스터 역할: AmazonEKSClusterPolicy
  - EKS 노드 그룹 역할: AmazonEKSWorkerNodePolicy + CNI + ECR
  - EBS CSI Driver: AmazonEBSCSIDriverPolicy (IRSA)
  - ALB Controller: AWSLoadBalancerControllerIAMPolicy (IRSA)
  - ArgoCD Image Updater: ECR 읽기 권한 (IRSA)
  - Lambda 실행 역할: EC2 시작/중지 권한

네트워크 보안

보안 그룹 규칙:
  EKS 노드:
    - Ingress: VPC 내부 트래픽, NodePort 범위, HTTPS
    - Egress: 모든 아웃바운드 허용
  
  RDS:
    - Ingress: EKS 보안 그룹에서만 3306 포트
    - Egress: 없음
  
  Bastion:
    - Ingress: 특정 IP에서 SSH (22)
    - Egress: VPC 내부 모든 트래픽

📊 리소스 사용량

컴퓨팅 리소스

EKS 노드 (t3.large × 3):
  vCPU: 2 × 3 = 6 cores
  메모리: 8GB × 3 = 24GB
  네트워크: 최대 5Gbps
  
총 Pod 수용량: ~30개 Pod

스토리지

EBS 볼륨:
  - EKS 노드: gp3 20GB × 3 = 60GB
  - RDS: gp2 20GB (확장 가능)
  - PersistentVolume: 동적 프로비저닝 (EBS CSI)

네트워크 트래픽 흐름

외부 사용자 → ALB Ingress Controller → EKS Service → Pod
EKS Backend → RDS (VPC 내부 통신)
EKS Backend → AI 서버 (VPC 내부, Private → Public)
EKS Pod → ECR (NAT Gateway 경유)
AI 서버 → ECR (인터넷 경유)
Bastion → EKS Nodes/AI 서버 (SSH, VPC 내부)

🔄 클라우드 마이그레이션 히스토리

V1 → V2 → V3 진화 과정

V1 (초기):
  플랫폼: 단일 VM 수동 배포
  AI: GCP VM에서 운영
  관리: 완전 수동 프로세스
  
V2 (중간):  
  플랫폼: Docker Compose 기반
  AI: GCP VM 유지
  관리: 스크립트 자동화
  
V3 (현재):
  플랫폼: AWS EKS + EC2 통합
  AI: AWS로 완전 이전 (GPU/CPU 분리)
  관리: GitOps (ArgoCD) + Terraform IaC

GCP → AWS 완전 마이그레이션

이전 상태 (V1/V2):
  - AI 서버: GCP VM (docker-compose)
  - 백엔드/프론트엔드: GCP 또는 온프레미스
  - 관리: 수동/스크립트 기반
  
마이그레이션 결과 (V3):
  - 메인 애플리케이션: AWS EKS로 이전
  - AI 서버: AWS EC2로 완전 이전
  - GPU/CPU 워크로드 분리: 성능 최적화
  - 통합 네트워킹: VPC 내부 고속 통신
  
이전 이유:
  - AWS의 통합 관리 및 운영 효율성
  - VPC 내부 네트워크 성능 향상
  - 비용 최적화 및 리소스 통합
  - Terraform 기반 통합 IaC 관리

V3 인프라는 AWS 단일 클라우드 기반의 완전 통합 아키텍처로, EKS 클러스터와 AI 전용 EC2 인스턴스가 동일한 VPC 내에서 최적화된 성능을 제공합니다. GPU/CPU 워크로드 분리를 통해 각 작업에 최적화된 리소스를 제공하며, 통합된 네트워킹으로 지연시간을 최소화했습니다.