카테고리 없음

8.8.가. Auto Scaling 환경에서 Spring Boot 애플리케이션 자동 기동 및 종료 처리하는 EC2 인스턴스 AMI 생성 가이드

backend 따라쟁이 2025. 2. 23. 21:45

AWS Auto Scaling을 활용하여 EC2 인스턴스를 자동으로 기동 및 종료하는 환경에서, 인스턴스 라이프사이클에 맞춰 Spring Boot 애플리케이션을 자동으로 시작하고 정상 종료하는 방법이 필요해졌습니다. 본 포스트에서는

  1. EC2 인스턴스에 필요한 환경 구성
  2. Spring Boot 애플리케이션을 시스템 서비스로 등록하여 기동/종료를 자동화
  3. AMI 이미지를 생성하여 Auto Scaling Launch Template/Configuration에 적용하는 과정을 단계별로 설명합니다.

1. 사전 준비 사항

  • AWS 계정EC2 인스턴스 (예: Amazon Linux 2 또는 Ubuntu 등)
  • Java 런타임 환경 (JRE/JDK) 및 Spring Boot 애플리케이션 빌드 파일 (예: app.jar)
  • AWS CLI 또는 Management Console 사용 경험
  • 기본적인 Linux 셸 스크립트 및 systemd 유닛 파일 작성 경험

2. EC2 인스턴스 환경 구성

먼저 EC2 인스턴스를 생성한 후, Java와 Spring Boot 애플리케이션을 실행할 수 있도록 환경을 설정합니다.

예시: Java 설치 및 애플리케이션 파일 배포

1) 생성한 EC2 인스턴스에 openjdk 설치
   . jdk 버전은 조금씩 다를 수 있음
# ubuntu Linux 기준
sudo apt update -y
sudo apt install openjdk-21-jre-headless


sudo mkdir -p /opt/myapp
sudo cp /path/to/app.jar /opt/myapp/
2) Local PC에서 EC2 인스턴스로 jar 파일과 application.properties 파일 copy
   . 애플리케이션 파일 복사 (S3 또는 Git 등에서 가져올 수 있음)
   . 나는 Local pc에서 Spring boot Application 컴파일을 통해 jar 파일을 생성함.
# Local PC에 Spring boot Application 디렉토리로 이동 후 컴파일을 통해 jar파일 생성
mvnw clean package -DskipTests

# target 디렉토리에 생성된 jar 파일 확인
cd target 
ls -l *.jar

# jar파일을 EC2 인스턴스에 ubuntu 유저 홈 디렉토리로 Copy (나의 EC2 인스턴스 PublicIP :13.125.19.229 )
scp -i ~/aws-iam/sshkeySeoul.pem RestfulapiJSON-0.0.1-SNAPSHOT.jar ubuntu@13.125.19.229:.
3) Spring Boot Application 기동시 사용할 properties파일 생성(내 파일 : app.properties )
    . 웹 서비스 포트 80 지정, logging 레밸 지정, 기타 환경 변수 지정(server.hostname : EC2 인스턴스 hostname을 Appl.에 전달)
pring.application.name=RestfulapiJSON

# 서비스 포트 지정(80을 사용하려면 root유저 권한으로 java 실행)
server.port=80

# DEBUG
# logging.level.org.springframework=DEBUG

# EC2 Instance 식별자
server.hostname=

3. Spring Boot 애플리케이션을 시스템 서비스로 등록

인스턴스가 기동될 때 자동으로 애플리케이션이 실행되도록 하기 위해 systemd 서비스로 등록합니다. 또한 인스턴스 종료 시 서비스가 정상적으로 종료되도록 ExecStop 옵션을 활용합니다.

systemd 서비스 파일 작성

다음과 같이 /etc/systemd/system/springboot.service 파일을 생성합니다.

springboot.service 파일  
. systemd의 서비스 파일과 systemctl 명령에 대한 상세한 내용은 LINUX 관련 정보 참조 요망
[Unit]
Description=Spring Boot Application
After=network.target

[Service]
User=root
WorkingDirectory=/home/ubuntu
ExecStartPre=/bin/rm -f /home/ubuntu/springboot.log
ExecStartPre=/bin/sh -c '/bin/sed -i "/server.hostname/c\\server.hostname=$(hostname -f)" /home/ubuntu/app.properties'
ExecStart=/usr/bin/java -jar /home/ubuntu/RestfulapiJSON-0.0.1-SNAPSHOT.jar --spring.config.location=/home/ubuntu/app.properties 
SuccessExitStatus=143
Restart=always
RestartSec=10
StandardOutput=append:/home/ubuntu/springboot.log
StandardError=append:/home/ubuntu/springboot.log

[Install]
WantedBy=multi-user.target
 

이 파일은 인스턴스 부팅 시 자동으로 애플리케이션을 실행하며, 인스턴스 종료 시 SIGTERM 신호를 보내어 애플리케이션이 정상 종료할 시간을 제공합니다.

 

ExecStart : Application 기동 명령

StandardOutput / StandardError : Application stdout / stderr 로그 파일 지정("append:" 옵션으로 application 재기동시에 로그 파일을 clear하지 않고 기존 로그파일에 내용을 append함.)

ExecStartPre : Application 기동전 실행할 명령으로 여러번 지정 가능하며, 아래 내용은 app.properties파일에 server.hostname을 현재 EC2 인스턴스의 hostname으로 값이 설정되도록 함.(ALB 설정 상태에 로드 발란싱 확인 목적으로 환경변수 추가함) 

ExecStartPre=/bin/sh -c '/bin/sed -i "/server.hostname/c\\server.hostname=$(hostname -f)" /home/ubuntu/app.properties'

서비스 등록 및 활성화

EC2 인스턴스에서 서비스 등록 및 활성화 방법
# 서비스 파일 재로드
# springboot.service 파일 작성/수정 후 실행
sudo systemctl daemon-reload 

# 서비스 자동 시작 등록 
sudo systemctl 
enable springboot.service 

# 즉시 서비스 시작 (테스트용) 
sudo systemctl start springboot.service

이제 인스턴스가 기동될 때마다 Spring Boot 애플리케이션이 자동으로 실행됩니다.

4. 인스턴스 종료 시 애플리케이션 정상 종료 처리

Auto Scaling 환경에서 인스턴스가 종료될 때, EC2 종료 신호가 전달되면 systemd는 등록된 ExecStop 명령을 실행합니다.
따라서 위의 서비스 파일에 설정된 ExecStop 옵션을 활용하여 Spring Boot 애플리케이션이 graceful shutdown을 수행하도록 구성합니다.

  • 참고: Spring Boot 애플리케이션 내에서도 shutdown hook 설정을 추가하여 보다 세밀한 종료 처리를 할 수 있습니다.

5. AMI 이미지 생성

애플리케이션과 서비스 설정이 완료된 EC2 인스턴스는 Auto Scaling에서 사용할 수 있도록 AMI 이미지로 생성합니다.

AMI 생성 방법

  1. AWS Management Console 또는 AWS CLI를 통해 인스턴스의 스냅샷을 생성합니다.
  2. 인스턴스가 중단되기 전에 설정이 정상적으로 반영되었는지 확인합니다.
  3. 생성된 AMI를 Auto Scaling Launch Template/Configuration에 반영합니다.
1)  AWS CLI를 사용하는 경우
 -no-reboot 옵션을 사용하면 인스턴스를 재부팅하지 않고 AMI를 생성할 수 있습니다.
 -CLI명령에서 instance-id를 내 EC2 인스턴스 ID로 변경하여 실행하면 됨.
aws ec2 create-image --instance-id i-0123456789abcdef0 --name "my-springboot-ami" --no-reboot

 

2) AWS Management Console를 사용하는 경우 
(그림1) EC2 목록에서 AMI Image 생성할 인스턴스를 선택 한다.
            작업 버튼을 클릭하여 "이미지 및 템플릿" 메뉴 선택, 하위 메뉴에 "이미지 생성" 메뉴를 클릭 한다.
(그림2) 이미지 이름, 이미지 설명 작성 후 "이미지 생성" 버튼 클릭 한다.

 

(그림1) EC2 선택 "이미지 생성" 메뉴 클릭

 

 

(그림2) 이미지 이름, 이미지 설명 작성 후 "이미지 생성" 버튼 클릭

 

6. Auto Scaling 그룹에 AMI 적용 및 검증

AMI 이미지가 생성되면 이를 기반으로 Auto Scaling 그룹의 Launch Template 또는 Launch Configuration을 업데이트합니다.

  1. Launch Template/Configuration 생성: 생성한 AMI ID를 지정하고, 필요에 따라 인스턴스 유형, 키 페어, 보안 그룹 등을 설정합니다.
  2. Auto Scaling 그룹 업데이트: 새로 생성한 Launch Template/Configuration을 적용합니다.
  3. 테스트: Auto Scaling 그룹에서 인스턴스를 기동 및 종료하여, Spring Boot 애플리케이션이 자동 기동되고 종료되는지 확인합니다.

※ Launch Template/Configuration 생성: 

"시작 템플릿 버전 세부 정보" 텝에서 작업 버튼에 "템플릿 수정(새 버전 생성)" 메뉴를 클릭합니다.

오픈된 화면에서 템플릿 버전 설명을 입력, 시작 템플릿 콘텐츠에서 "내 AMI" 텝을 클릭하여 방금전 내가 생성한 AMI 이미지를 선택 합니다. 추가로 키 페어, 네트워크 설정 정보를 입력하고 템플릿 버전 생성 버튼을 클릭하면 Auto Scaling Launch Template에 AMI 이미지 등록이 완료됩니다.  

(그림1) "템플릿 수정(새 버전 생성)" 메뉴를 클릭

 

(그림2) Auto Scaling Launch Template에 AMI 이미지 등록


7. 결론

이번 가이드에서는 Auto Scaling 환경에서 EC2 인스턴스가 기동될 때 Spring Boot 애플리케이션을 자동 실행하고, 종료 시 애플리케이션이 graceful shutdown을 하도록 구성하는 방법을 알아보았습니다.
주요 단계는 다음과 같습니다.

  • EC2 인스턴스 환경 구성: Java 설치 및 애플리케이션 배포
  • systemd 서비스 등록: 애플리케이션 자동 기동 및 종료 처리
  • AMI 이미지 생성: 구성 완료된 인스턴스를 AMI로 캡처
  • Auto Scaling 적용: Launch Template/Configuration에 AMI 반영 및 테스트

이와 같이 구성하면 Auto Scaling 시 인스턴스 라이프사이클에 맞춰 애플리케이션이 안정적으로 관리되며, 운영 효율성을 높일 수 있습니다.


이 가이드가 여러분의 AWS Auto Scaling 환경 구축에 도움이 되길 바랍니다. 추가적인 질문이나 개선 사항은 댓글로 남겨주세요.