EC2와 RDS를 연결해보자🔗(+Elastic IP, health check, security groups)

euphony·2025년 3월 21일
0

내일배움캠프

목록 보기
66/66

이번 개인 과제 중 AWS를 실습하는 부분이 있는데, 요구사항은 다음과 같다. 먼저 EC2와 RDS를 구축하고 연결하는 과정을 기록해보려고 한다.✍🏻

✔️ EC2
- EC2 인스턴스에서 어플리케이션을 실행한다.
- 탄력적 IP를 설정해 외부에서도 접속할 수 있도록 한다.
- 서버 접속 및 Live 상태를 확인할 수 있는 health check API를 만든다.

✔️ RDS
- RDS 데이터베이스를 구축한다.
- EC2에서 실행되는 어플리케이션에 연결한다.

✔️ S3
- S3 버킷을 생성한다.
- 유저의 프로필 이미지 업로드 및 관리 API를 구현한다.

프로젝트를 EC2에 배포하기

로컬에서 프로젝트 빌드하기

인텔리제이에서 프로젝트를 빌드해보자! EC2 인스턴스는 이미 만들어놨다는 가정 하에 진행하겠다.

1) Gradle 탭에서 Task - build에서 왼쪽에 톱니바퀴 모양이 있는 build를 두 번 클릭한다.

2) BUILD SUCCESSFUL 메시지가 뜨고 빌드가 정상적으로 수행되었다면 프로젝트에서 build - libs에 생긴 파일을 확인한다.

여기서 expert-0.0.1-SNAPSHOT.jar 파일을 EC2로 보내야 한다.

🤔 .jar 파일이 뭐길래...?

  • Java ARchive (자바 아카이브) 파일의 줄임말.
  • Spring Boot 프로젝트 전체를 하나로 압축한 실행 파일이다.
  • 내가 작성한 소스 코드, 사용하는 라이브러리, 설정 파일, 실행 메타 정보 등이 전부 들어있다.
  • 따라서 이 파일만 보내면 EC2에서도 별다른 설치 없이 바로 실행할 수 있다!

⚠️ 빌드 과정에서 발생한 오류

  • Error creating bean with name 'jwtAuthenticationFilter' defined in file ... 오류
    • JwtAuthenticationFilter 클래스가 JwtUtil을 주입받으려고 했는데 스프링 컨테이너에 JwtUtil 빈이 등록되어 있지 않아 발생한 오류이다.
    • JwtUtil을 Mock으로 주입해 해결했다.
  • Spring Security 인증이 걸리는 테스트가 있어 인증 객체가 필요하다는 문제가 있었다.
    • @WithMockUser을 추가해 테스트용으로 가짜 인증 객체(SecurityContext)에 넣어 해결했다.

EC2에 .jar 파일 보내고 실행하기

1) 로컬에서 .jar 파일을 EC2로 보낸다. 로컬에서 다음 명령어를 입력한다.

나는 window라서 wsl에서 입력했다.

scp -i key.pem build/libs/expert-0.0.1-SNAPSHOT.jar ubuntu@EC2_IP:/home/ubuntu/

혹시 key.pem과 빌드된 파일이 다른 곳에 있다면 각 경로를 입력해줘야 한다. 나는 각자 다른 곳에 있어서 다음과 같이 경로를 하나하나 입력했다. 만약 잘 전송됐다면 왼쪽에 파일명이 뜨고 오른쪽에 100% 라고 뜰 것이다.

2) EC2에 접속한다.

key.pem이 있는 폴더에서 다음과 같이 입력한다.

ssh -i key.pem ubuntu@EC2_IP

이렇게 Welcome to Ubuntu~라는 글자가 나오면 정상적으로 접속된 것이다.

3) EC2에서 Spring boot 서버를 백그라운드로 실행한다.

우선 ls 명령어를 통해 실제로 EC2에 .jar 파일이 있는지 확인한다. 파일이 제대로 있다면 다음 명령어를 입력한다.

nohup java -jar expert-0.0.1-SNAPSHOT.jar &
  • nohup : no hang up의 줄임말로, 터미널 연결이 끊겨도 프로세스가 죽지 않고 계속 실행된다. 로그는 기본적으로 nohup.out 파일에 저장된다.
  • java -jar expert-0.0.1-SNAPSHOT.jar : java 명령어로 .jar 파일을 실행한다. Tomcat이 내장되어있어 8080 포트에서 바로 실행된다.
  • & : 해당 명령어를 백그라운드로 실행한다. 터미널에서 바로 다음 명령어를 입력할 수 있고, 실행된 프로세스는 PID를 부여받아 별도로 동작한다.

서버가 잘 실행된다면 다음과 같이 뜰 것이다.

  • [1] : 백그라운드 작업 번호
  • 16824 : 실행된 프로세스의 PID (Process ID)
  • nohup: ignoring input and appending output to 'nohup.out' : 터미널 입력을 무시하고 모든 출력(로그)을 nohup.out 파일에 저장하겠다는 의미

⚠️ 배포 과정에서 발생한 오류

  • MySQL 연결 실패 오류 발생
    • DB URL에서 localhost로 되어 있으면 EC2가 자기 자신을 찾다가 오류가 발생한다고 한다.
    • 이때는 RDS를 구축하지 않은 상태여서 일단 DB 연결 없이 서버만 실행하는 방향으로 시도했다.
    • 따라서 아래와 같이 application.properties에서 DB 설정을 주석 처리한후 다시 빌드했다.
  • 8080 포트를 이미 다른 프로세스가 잡고 있는 문제 발생
    • 새로 빌드하고 배포 후 다시 실행하려고 하자 위와 같은메세지가 나왔다. 기존에 실행한 java -jar 프로세스가 아직 살아있거나 두 번 실행해 포트 충돌이 난 것이다.
    • ps -ef | grep java 명령어를 이용해 PID를 확인 후, kill -9 [PID] 명령어로 기존 프로세스를 종료한 후, 다시 서버를 실행한다.
  • 접속이 안된다면 보안 규칙에서 8080 포트가 열려 있는지 확인한다. 만약 열려있지 않다면 다음과 같이 Inbound rules에 8080 포트를 추가한다.
  • nohup java -jar expert-0.0.1-SNAPSHOT.jar & 명령어 오류 : nohup: failed to run command 'java': No such file or directory 라는 오류 메세지가 나타났다. EC2 인스턴스에 Java가 설치되어 있지 않아서 발생한 오류이다. 다음과 같은 명령어를 입력해 Java를 설치 후 다시 시도한다.
sudo apt update
sudo apt install openjdk-17-jdk -y

탄력적 IP(Elastic IP) 설정하기

EC2 대시보드에서 Network & Security - Elastic IPs를 클릭한다.

Allocate Elastic IP address 클릭하고 Amazon에서 제공하는 IP를 선택 후 Allocate 한다.

생성된 Elastic IP를 선택하고 Actions - Associate Elastic IP address를 누른다.

연결할 인스턴스를 선택 후 Associate 한다.

이제 Public IP 대신 Elastic IP를 사용하면 된다. Elastic IP를 사용하면 인스턴스를 재시작해도 IP가 변하지 않고, Route53이나 외부 DNS에서 연결을 쉽게 할 수 있다. 그런데 연결이 안 된 EIP는 비용이 발생한다고 하니 꼭 인스턴스 연결 상태를 확인하자!

RDS

RDS 인스턴스를 생성 했다면, EC2와 RDS를 연결해야 한다.

보안 그룹 설정하기

기존에 EC2가 속한 보안그룹을 RDS에 추가한다. 나는 launch-wizard-2 라는 이름의 보안 그룹을 EC2에 적용했으므로 RDS에도 같은 것을 적용했다.

그리고 RDS 보안 그룹 Inbound rules에 MySQL/Aurora 포트(TCP 3306)를 추가했다. RDS 인스턴스는 AWS 내에서 격리되어 있기 때문에 외부에서 바로 접근할 수 없다. 따라서 RDS의 보안 그룹에서 MySQL/Aurora 포트(3306)를 허용해야, EC2 인스턴스의 보안 그룹 또는 특정 IP가 RDS와 연결될 수 있다.

RDS 연결 정보 작성하기

application.properties에 다음과 같이 RDS 연결 정보를 작성했다.

spring.datasource.url=jdbc:mysql://<엔드포인트>:<포트>/<DB명>
spring.datasource.username=admin
spring.datasource.password=비밀번호
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  • spring.datasource.url : RDS 엔드포인트 + 포트 + DB명
  • spring.datasource.username : RDS 사용자명
  • spring.datasource.password : RDS 비밀번호
  • driver-class-name ; MySQL 사용 시 추가

참고로 RDS 엔드포인트는 RDS 내 데이터베이스에 들어가면 나와있다.

다시 빌드 후 배포하기

이제 위에서 EC2로 배포할 때 했던 과정을 다시 해주면 된다.

  • 빌드
  • EC2로 새로 빌드한 .jar 파일 전송
  • EC2 접속 후 새 버전 실행
  • 로그 확인 or 브라우저 테스트

health check API로 확인하기

health check를 위해 다음 의존성을 추가한다.

implementation 'org.springframework.boot:spring-boot-starter-actuator'

다음은 application.properties에 추가하는 설정으로, RDS 연결 확인을 위해 필요하다.

management.endpoint.health.show-details=always
management.health.db.enabled=true
  • management.endpoint.health.show-details=always
    • 기본값은 when-authorized로, 권한이 없으면 status: "UP"만 보여준다.
    • DB, Disk, Custom Health 등 상세 정보까지 모두 출력한다.
  • management.health.db.enabled=true
    • Spring Boot Actuator에서 DataSource 연결(DB Health Check) 여부를 켜는 설정이다.
    • DB 연결 상태를 확인하고 싶을 때 true로 설정한다.

health check로 확인해보면 다음과 같이 tjqjdmlDB가 정상적으로 돌아가고 있는 것을 알 수 있다.

위 결과에서 기본 경로가 /actuator/health가 아니라 그냥 /health인데, 아래 설정을 추가하면 /actuator 없이 루트 경로로 health check가 가능하다.

management.endpoints.web.base-path=/

0개의 댓글

관련 채용 정보