ECS를 이용한 Blue/Green 무중단 배포 구성하기 (1) - 프로젝트 생성과 ECR 리포지토리
작성 일자 : 2024년 05월 26일
시리즈 순서
- 프로젝트 생성과 ECR 리포지토리 (👈 지금 보고 있는 포스트)
- VPC 생성 및 NAT Instance를 이용한 인터넷 연결
- Route 53 Hosted Zone 생성 및 ACM SSL 인증서 발급
- 애플리케이션 로드 밸런서(ALB) 생성
- ECS를 이용한 컨테이너 배포
- CodeDepoly를 이용한 Blue/Green 무중단 배포 테스트
- Github Actions를 이용한 배포 자동화 구축
들어가는 말
본 시리즈는 온디맨드 EC2 인스턴스 기반의 ECS 클러스터를 이용하여 Blue/Green 무중단 배포를 구성하는 방법을 다룹니다.
소프트웨어 개발 및 배포 과정에서 가장 큰 도전 중 하나는 서비스 중단 없이 새로운 기능이나 버그 수정을 사용자에게 제공하는 것입니다. 이를 위해 많은 조직들이 무중단 배포(Zero Downtime Deployment) 방식을 채택하고 있습니다. 무중단 배포란 말 그대로 서비스의 가동을 중단하지 않고 새로운 코드를 배포하는 방법을 의미합니다. 이로 인해 사용자는 서비스 이용 중에 불편함을 겪지 않고, 개발팀은 안정적으로 업데이트를 배포할 수 있습니다.
그 중에서도 Blue/Green 배포는 무중단 배포를 구현하는 대표적인 방법 중 하나입니다. Blue/Green 배포는 두 개의 환경(Blue와 Green)을 사용하여 배포를 수행합니다. Blue 환경은 현재 프로덕션 환경을 나타내고, Green 환경은 새로운 버전의 애플리케이션이 배포될 준비가 된 환경입니다. 새로운 코드가 Green 환경에 배포되고 모든 테스트가 완료되면 트래픽을 Green 환경으로 전환하여 사용자에게 새로운 버전을 제공합니다. 이러한 방식은 배포 과정에서 다운타임을 최소화하고, 필요시 빠르게 이전 버전으로 롤백할 수 있어 사용자 경험을 향상시킵니다.
이 블로그 포스팅에서는 AWS ECS(Elastic Container Service)를 이용하여 Blue/Green 무중단 배포를 구성하는 방법을 자세히 설명합니다. 이를 통해 여러분의 애플리케이션 배포 과정을 개선하고, 사용자에게 보다 안정적인 서비스를 제공할 수 있을 것입니다.
ECS란?
Amazon Elastic Container Service(Amazon ECS)는 AWS에서 제공하는 완전 관리형 컨테이너 오케스트레이션 서비스입니다. 간단히 말해, ECS는 컨테이너화된 애플리케이션을 쉽게 배포하고 관리하며 확장할 수 있도록 도와줍니다. 이를 통해 개발자들은 서버나 인프라를 직접 관리할 필요 없이 애플리케이션 개발에 집중할 수 있습니다.
배포 방식의 차이: EC2 vs ECS
Amazon EC2(Elastic Compute Cloud)와 Amazon ECS(Elastic Container Service)는 각각 전통적인 서버 기반 배포와 컨테이너 기반 배포 방식을 대표합니다. EC2를 사용하여 Blue/Green 무중단 배포를 구현하려면 Nginx와 같은 웹 서버와 배포 스크립트를 통해 복잡한 설정을 직접 관리해야 합니다. 트래픽 전환을 위해 스크립트를 통해 Health Check를 진행하며, 이러한 스크립트를 설정하고 관리하는 작업이 필요합니다. 반면, ECS는 AWS CodeDeploy와 통합되어 자동화된 Blue/Green 배포를 제공합니다. ALB(Application Load Balancer)를 통해 Health Check를 수행하며, 트래픽 전환도 자동으로 이루어지므로 복잡한 설정이나 수동 개입이 필요 없습니다.
서비스 확장 측면에서도 ECS는 많은 이점을 제공합니다. EC2를 사용하여 확장을 수행할 때는 각 인스턴스에 JDK 및 기타 의존 라이브러리를 설치하고 환경을 설정해야 합니다. 이는 많은 시간과 노력을 요구하며, 설정 오류가 발생할 수 있습니다. 하지만 ECS는 컨테이너 기반으로 확장을 수행하므로, 새로운 컨테이너 인스턴스가 생성될 때마다 동일한 이미지와 설정을 사용합니다. 이를 통해 별도의 환경 설정 작업이 필요 없으며, Auto Scaling 그룹을 통해 자동으로 확장 및 축소를 수행할 수 있습니다.
결론적으로, Amazon EC2와 Amazon ECS는 각각 장단점이 있지만, ECS는 컨테이너 기반의 애플리케이션 배포 방식으로 Blue/Green 무중단 배포와 서비스 확장 측면에서 큰 이점을 제공합니다. 자동화된 무중단 배포와 간편한 확장 기능을 통해 복잡성을 줄이고, 배포와 관리의 효율성을 높일 수 있습니다.
1. 프로젝트 생성
본 시리즈의 첫 시작으로 Spring Boot 프로젝트를 생성하고 Docker 이미지를 빌드해, ECR(Elastic Container Registry)에 이미지를 업로드하는 과정을 진행하겠습니다.
1-1. Spring Boot 프로젝트 생성
먼저, Spring Boot 프로젝트를 생성합니다. 저는 Spring Initializr를 통해 프로젝트를 생성하고, Spring Web, Spring Boot Actuator 의존성을 추가했습니다. Spring Boot Actuator는 애플리케이션의 상태를 모니터링하고 관리하는 기능을 제공하며, 이를 통해 Blue/Green 배포 과정에서 ALB(애플리케이션 로드밸런서)가 애플리케이션의 상태를 확인할 수 있습니다.
- Project: Gradle Project
- Language: Java
- Spring Boot: 3.3.0
- Packaging: Jar
- Java: 17
- Dependencies: Spring Web, Spring Boot Actuator
1-2. IndexController
생성
배포 시, 테스트를 위해서 IndexController
를 생성하여, /
경로로 요청이 들어왔을 때 Hello, World!
를 반환하도록 합니다.
@Controller
public class IndexController {
@GetMapping("/")
@ResponseBody
public String index() {
return "Hello, World!";
}
}
1-3. Dockerfile 작성
다음으로, Docker 이미지를 빌드하기 위해 Dockerfile을 작성합니다. 프로젝트 루트 디렉토리에 Dockerfile
을 생성하고, 다음과 같이 작성합니다.
FROM eclipse-temurin:17-jdk
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
1-4. build.gradle
수정 및 JAR 파일 빌드
지금 단계에서 ./gradlew build
명령어를 통해 프로젝트를 빌드하게 되면, build/libs
디렉토리에 ecsdeploy-0.0.1-SNAPSHOT-plain.jar
파일과 ecsdeploy-0.0.1-SNAPSHOT.jar
파일이 두 개 생성됩니다. Plain Archive는 애플리케이션 실행에 필요한 모든 의존성을 포함하지 않고, 작성된 소스코드의 클래스 파일과 리소스 파일만을 포함합니다. 때문에 -plain
키워드가 없는 실행 가능한 JAR 파일(Executable Archive)만을 생성하도록 build.gradle
파일 상단에 다음과 같이 설정을 추가합니다.
jar {
enabled = false
}
위 설정을 추가하고, ./gradlew build
명령어를 실행하면 build/libs
하위에 -plain
키워드가 없는 실행 가능한 JAR 파일만 생성되는 것을 확인할 수 있습니다.
1-5. Docker 이미지 빌드
이제, Docker 이미지를 빌드합니다. Dockerfile이 있는 디렉토리에서 다음 명령어를 실행하면, Docker 이미지가 빌드되고 로컬에 저장됩니다.
docker build --platform linux/amd64 --build-arg JAR_FILE=build/libs/\*.jar -t gerrymandering-ecsdeploy .
--platform linux/amd64
명시
M1과 같은 애플 실리콘 기반 프로세서를 사용하는 머신에서 Docker 이미지를 빌드할 때는 --platform linux/amd64
옵션을 명시하여 빌드 대상 플랫폼을 x86_64 아키텍처로 지정합니다. 이는 Amazon ECS에서 사용하는 EC2 인스턴스가 x86_64 아키텍처를 사용하기 때문에 이를 명시하지 않으면 ECS에서 서비스를 실행할 때 아래와 같은 에러가 발생할 수 있습니다.
exec /usr/local/bin/docker-entrypoint.sh: exec format error
2. ECR 리포지토리 생성 및 이미지 푸시
Amazon ECR (Elastic Container Registry)은 AWS에서 제공하는 완전 관리형 Docker 컨테이너 레지스트리 서비스입니다. ECR은 Docker 이미지를 안전하게 저장, 관리, 배포할 수 있도록 설계되었으며, AWS의 다른 서비스와 통합하여 효율적인 워크플로우를 지원합니다. 사용자는 ECR을 통해 Docker 이미지를 저장하고, 이 이미지를 AWS ECS(Elastic Container Service), AWS EKS(Elastic Kubernetes Service) 등과 같은 서비스에서 직접 사용할 수 있습니다.
이번 단계에서는 ECR 리포지토리를 생성하고, 로컬에서 빌드한 Docker 이미지를 ECR에 푸시하는 과정을 진행하겠습니다.
2-1. 이미지 푸시를 위한 AWS CLI 유저 생성
ECR에 Docker 이미지를 푸시하는 과정을 간략하게 설명하면 아래와 같습니다.
aws ecr get-login-password
명령어를 통해 AWS CLI가 ECR에 접근할 수 있는 인증 토큰을 생성합니다.- Docker CLI가 파이프(
|
)로 이 토큰을 읽고 로그인해서, ECR에 Docker 클라이언트를 인증시킵니다. docker push
명령어를 통해 로컬에서 빌드한 Docker 이미지를 ECR에 푸시합니다.
때문에 ECR에 Docker 이미지를 푸시하기 위해서는 먼저 AmazonEC2ContainerRegistryFullAccess
권한을 가진 IAM 유저를 생성하고, 해당 유저의 액세스 키와 시크릿 키를 사용하여 AWS CLI를 구성해야 합니다. IAM 콘솔에서 새로운 사용자를 생성하고, 해당 사용자에게 AmazonEC2ContainerRegistryFullAccess
권한을 부여하겠습니다.
2-1-1. IAM 콘솔에서 새로운 사용자 생성
- AWS Management Console에서 IAM 서비스로 이동합니다.
- Users 메뉴에서 Create user를 클릭합니다.
- User name을 입력하고 Next를 클릭합니다.
- Attach policies directly를 선택하고, AmazonEC2ContainerRegistryFullAccess 정책을 선택, Next를 클릭합니다.
- Permissions summary에서 AmazonEC2ContainerRegistryFullAccess 정책이 추가된 것을 확인하고, Create user를 클릭해 사용자를 생성합니다.
2-1-2. 사용자 액세스 키 생성
- 사용자가 생성되면 생성된 사용자를 클릭하고 Security credentials 탭으로 이동합니다.
- Access keys 섹션에서 Create access key를 클릭합니다.
- Use case에서 Command Line Interface (CLI)를 선택하고, Confirmation을 체크한 후 Next를 클릭합니다.
- Create access key를 클릭하여 액세스 키와 시크릿 엑세스 키를 생성합니다.
- 발급된 액세스 키와 시크릿 엑세스 키를 복사하여 안전한 장소에 기록해둡니다.
2-1-3. AWS CLI 구성
- AWS CLI를 설치합니다.
brew install awscli
aws configure
명령어를 통해 AWS CLI를 구성합니다.
aws configure
- AWS Access Key ID: 위에서 발급한 액세스 키를 입력합니다.
- AWS Secret Access Key: 위에서 발급한 시크릿 액세스 키를 입력합니다.
- Default region name:
ap-northeast-2
- Default output format:
json
2-2. ECR 리포지토리 생성
- AWS Management Console에서 ECR (Elastic Container Registry) 서비스로 이동합니다.
- Repositories 메뉴에서 Create repository를 클릭합니다.
- Repository name을 입력하고, Create repository를 클릭합니다.
2-3. ECR 리포지토리에 Docker 이미지 푸시
- 생성한 ECR 리포지토리를 클릭하고, 우측 상단의 View push commands를 클릭합니다.
aws ecr get-login-password
명령어를 통해 AWS CLI가 ECR에 접근할 수 있는 인증 토큰을 생성, 이 토큰을 Docker CLI에 파이프로 전달해 로그인하여 ECR에 Docker 클라이언트를 인증시킵니다. 이미지의 1번 과정에 나와있는 명령어를 복사하여 터미널에 붙여넣기합니다.
명령어(참고용)
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 730335408691.dkr.ecr.ap-northeast-2.amazonaws.com
# 출력
Login Succeeded
- Docker 이미지 빌드 과정은 이미 위에서 진행하였으므로, 이미지 3번 과정에 나와있는 명령어를 통해 생성한 Docker 이미지의 태그를 설정합니다.
명령어(참고용)
docker tag gerrymandering-ecsdeploy:latest 730335408691.dkr.ecr.ap-northeast-2.amazonaws.com/gerrymandering-ecsdeploy:latest
- 이미지 4번 과정에 나와있는 명령어를 통해 Docker 이미지를 ECR에 푸시합니다.
명령어(참고용)
docker push 730335408691.dkr.ecr.ap-northeast-2.amazonaws.com/gerrymandering-ecsdeploy:latest
# 출력
The push refers to repository [730335408691.dkr.ecr.ap-northeast-2.amazonaws.com/gerrymandering-ecsdeploy]
6d5569eb27c6: Pushed
86cb6a9eb3cd: Pushed
985fdc63de98: Pushed
4ab2850febd7: Pushed
2db7720a8970: Pushed
629ca62fb7c7: Pushed
latest: digest: sha256:3cdf702bb09a0459dcd988c65ea140b7f4bb4424879b4b240b9b095502c50d2a size: 1580
- ECR 리포지토리로 이동하여 이미지가 성공적으로 푸시되었는지 확인합니다.
다음 글: VPC 생성 및 NAT Instance를 이용한 인터넷 연결
ECS를 이용한 Blue/Green 무중단 배포 구성하기 (2) - VPC 생
ECS를 이용한 Blue/Green 무중단 배포 구성하기 (2) - VPC 생성 및 NAT Instance를 이용한 인터넷 연결 작성 일자 : 2024년 06월 2일 시리즈 순서프로젝트 생성
gerrymandering.tistory.com