EKS – Spring 백엔드 서버 배포 아키텍처

Spring 백엔드 서버 배포는 두 단계로 진행한다

  • 모놀로식 서버 배포: 단일 Spring 애플리케이션을 Kubernetes에 배포
  • MSA 아키텍처 배포: Spring Cloud 기반의 마이크로서비스를 Kubernetes에 배포

MSA와 Kubernetes를 같이 사용하는 이유

MSA 아키텍처는 Kubernetes와 궁합이 매우 잘 맞는다

  • 대규모 시스템: MSA를 채택하는 기업은 대부분 대규모 시스템을 운영
  • 다수의 컨테이너: 여러 마이크로서비스가 각각 컨테이너로 실행됨
  • 컨테이너 오케스트레이션: Kubernetes가 다수의 컨테이너를 효율적으로 관리

따라서 MSA 아키텍처를 사용하는 기업에서는 Kubernetes(특히 EKS)로 배포 환경을 구성하는 경우가 많다. MSA 서버 배포까지 경험해야 Kubernetes 배포를 제대로 이해했다고 할 수 있다

전체 아키텍처 구성

구성요소역할구현 방식
Spring Pod백엔드 애플리케이션Deployment (Replicas: 2)
Worker NodePod가 실행되는 물리적 서버Amazon EC2 2대
Database영구 데이터 저장Amazon RDS
Redis캐시/세션 저장소Kubernetes Pod
이미지 저장소Docker 이미지 관리Amazon ECR
CI/CD빌드/배포 자동화Github Actions

RDS vs Redis Pod

RDS를 사용하는 이유(데이터베이스)
  • 데이터의 영속성과 안정성이 매우 중요
  • Pod는 언제든재 재생성될 수 있어 데이터 손실 위험
  • RDS는 자동 백업, 복제, 장애 조치 등 관리형 서비스 제공
Pod로 구성하는 이유 (Redis)
  • 캐시 데이터는 상대적으로 휘발성이 허용됨
  • Pod 재시작 시 캐시가 초기화되어도 서비스에 치명적이지 않음
  • 필요시 Redis도 AWS ElastiCache로 개체 가능

배포 프로세스 상세

Spring 프로젝트의 문제점

application-local.yaml

spring:
  config:
    activate:
      on-profile: local
  redis:
    host: localhost
    port: 6379
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ordersystem?useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 1234
```

**문제점:** Redis와 MySQL을 `localhost`로 참조하고 있습니다. 이 상태로 Pod를 배포하면 **Pod 내부에 Redis와 MySQL이 없기 때문에 에러가 발생**합니다.

### 3.2 해결 방안
```
[기존 - 로컬 개발 환경]
Spring → localhost:6379 (Redis)
Spring → localhost:3306 (MySQL)

[변경 - Kubernetes 환경]
Spring Pod → Redis Service → Redis Pod
Spring Pod → RDS Endpoint → Amazon RDS
```

- **Redis**: 별도의 Pod + Service로 구성하고, Spring에서 Service 이름으로 접근
- **RDB**: AWS RDS를 생성하고, Spring에서 RDS 엔드포인트로 접근

### 3.3 배포 순서
```
1. 사전 준비 (선행 작업)
   ├── Redis Pod + Service 생성
   └── Amazon RDS 생성

2. Spring 배포
   ├── Docker 이미지 빌드
   ├── ECR에 이미지 업로드
   ├── Deployment 적용 (Pod 생성)
   ├── Service 적용
   └── Ingress 적용 (HTTPS 포함)

3. CI/CD 자동화
   └── GitHub Actions 설정

문제점: Redis와 MySQL을 `localhost`로 참조하고 있다. 이 상태로 Pod를 배포하면 Pod 내부에 Redis와 MySQL이 없기 때문에 에러가 발생한다

해결 방안

[기존 - 로컬 개발 환경]
Spring → localhost:6379 (Redis)
Spring → localhost:3306 (MySQL)

[변경 - Kubernetes 환경]
Spring Pod → Redis Service → Redis Pod
Spring Pod → RDS Endpoint → Amazon RDS
  • Redis: 별도의 Pod + Service로 구성하고, Spring에서 Service 이름으로 접근
  • RDB: AWS RDS를 생성하고, Spring에서 RDS 엔드포인트로 접근

배포 순서

1. 사전 준비 (선행 작업)
   ├── Redis Pod + Service 생성
   └── Amazon RDS 생성

2. Spring 배포
   ├── Docker 이미지 빌드
   ├── ECR에 이미지 업로드
   ├── Deployment 적용 (Pod 생성)
   ├── Service 적용
   └── Ingress 적용 (HTTPS 포함)

3. CI/CD 자동화
   └── GitHub Actions 설정

이미지 관리와 배포 흐름

수동 배포 프로세스

개발자가 소스코드를 변경했을 때 수행해야 하는 작업

Docker 이미지 빌드
docker build -t my-spring-app:latest .
ECR에 이미지 업로드
docker tag my-spring-app:latest <ECR-URI>/my-spring-app:latest
docker push <ECR-URI>/my-spring-app:latest
Pod 재생성 (이미지 갱신)
kubectl rollout restart deployment/<deployment-name> -n <namespace>

rollout restart가 필요한 이유

이미지 태크를 `latest`로 사용할 경우, Deployment YAML 자체는 변경되지 않는다. Kubernetes는 변경 사항이 없으면 Pod를 재생성하지 않는다. 따라서 새 이미지를 반영하려면 Kubernetes rollout restart 명령어로 ReplicaSet을 새로 생성해야 한다

문제점

위 과정은 소스코드가 변경될 때마다 반복해야 한다

  • 회사의 소스코드는 지속적으로 변경된다
  • 매번 이미지 빌드 → 업로드 → rollout restart를 수동으로 수행한다
  • 반복적이고 실수가 발생하기 쉬운 작업이다

CI/CD 자동화

  • Continuous Integration (CI): 지속적 통합 – 코드 변경 시 자동으로 빌드 및 테스트
  • Continuous Deployment/Delivery (CD): 지속적 배포 – 빌드된 결과물을 자동으로 서버에 배포

CI/CD 자동화의 핵심: 프로젝트를 빌드하고, 이미지를 만들어서, 서버에 배포하는 작업을 자동화하는 것

Github Actions를 통한 자동화

개발자가 main 브랜치에 push/merge
           ↓
    GitHub Actions 트리거
           ↓
    ┌────────────────────┐
    │ 1. 소스코드 체크아웃    │
    │ 2. 프로젝트 빌드       │
    │ 3. Docker 이미지 빌드 │
    │ 4. ECR에 이미지 푸시   │
    │ 5. kubectl rollout │
    │    restart 실행     │
    └────────────────────┘
           ↓
    새로운 Pod 자동 생성

지속적으로 변경되는 것 vs 한 번만 설정하는 것

  • 한 번만 설정: Deployment, Service, Ingress YAML – 거의 변경 없음
  • 지속적 변경: Spring 소스코드 → Docker 이미지 → Pod – 빈번하게 변경

따라서 CI/CD 자동화의 대상은 이미지 빌드 → 업로드 → Pod 재생성 과정이다

Amazon ECR vs Docker Hub

ECR을 사용하는 이유

비교 항목Docker HubAmazon ECR
소유Docker Inc.AWS
EKS 연동별도 설정 필요네이티브 통합
IAM 권한지원 안 함AWS IAM 기반 권한 관리
비용무료 티어 제한적AWS 사용량 기반
실무 사용EKS 환경에서는 드묾EKS와 함께 많이 사용

AWS 생태계(EKS, RDS 등)를 사용한다면 서비스의 통일성과 보안 관리 측면에서 ECR 사용이 권장된다. 실무에서 EKS를 사용하면서 Docker Hub를 사용하는 경우는 많지 않다

전체 흐름 요약

사용자 요청 흐름

사용자 → Route53 → Load Balancer → Ingress → Service → Pod (Spring)
                                                          ↓
                                              ┌───────────┴───────────┐
                                              ↓                       ↓
                                        Redis Service            Amazon RDS
                                              ↓
                                         Redis Pod

개발자 배포 흐름

개발자 → GitHub (push) → GitHub Actions → ECR (이미지) → EKS (Pod 재생성)

출처 – eks를 활용한 spring 운영서버 배포(feat. devops의 모든것)