[러닝하이] 테스트 서버 배포 - EC2를 활용한 Spring Boot 서버 배포

수박이삼촌·2024년 7월 7일
1

러닝하이

목록 보기
9/11
post-thumbnail

이번 포스팅에서는 AWS의 EC2를 이용한 Spring Boot 서버 배포 방법을 글로 정리해보겠습니다.

우선, 서버를 왜 개인PC를 활용한 On-premises 환경으로 배포하지 않고 AWS 환경을 사용하는지에 대해서 정리해보겠습니다.

On-premises 방법을 채택한다면, 개인 pc 혹은 회사용 서버 pc 를 이용하게 될 텐데요. 이러한 경우, 서버 pc는 365일 24시간 켜져 있어야 합니다. 서버 운영자는 pc 설정이 자유롭지만 관리 또한 운영자의 몫입니다.

서버를 확장하기 위해선 pc를 구매하고, 임시적인 서버 확장이었다면 pc를 구매했다가 보관하거나 중고로 판매해야 하죠.. 서버 담당자가 신경써야 할 부분이 상당합니다.

반면에 AWS를 비롯한 Cloud Service는 설정에 따라 서버 담당자가 관리해야 하는 부분을 양도할 수 있습니다. 책임을 분리할 수 있는 것이죠. 원한다면 간단한 설정 변경과 과금으로 스케일 업 혹은 스케일 아웃이 가능합니다. 일시적인 트래픽 밀집을 대비할 수 있는 것입니다.

출처) https://www.redhat.com/ko/topics/cloud-computing/iaas-vs-paas-vs-saas

저는 위와 같은 이유 중, 클라우드 서비스의 서버와 네트워크 관리 책임을 전가할 수 있는 AWS EC2 를 선택하게 되었습니다.

🐳 EC2 배포

저희 러닝하이 팀은 현재 Spring Boot 3.2.3 버전으로 개발을 진행해왔습니다. 프론트엔드 분들께서 서버를 테스트해볼 수 있도록 개발 서버도 배포가 필요했습니다.

Spring Boot 프로젝트를 서버에 옮기는 방법은 두 가지가 있습니다.

  1. jar파일로 빌드를 진행하고 jar파일을 배포된 서버에 전달
  2. 배포된 서버에 git설치 후 프로젝트 clone

그 중 저는 더 간간한 jar파일을 이용한 프로젝트 전달 방법을 사용하겠습니다.
(EC2 인스턴스 생성, 탄력적 IP 설정은 참고 자료가 많으므로 생략하겠습니다.)

EC2 OSUbuntu를 사용하였습니다.
EC2 생성 간 발급받은 ssh pem key는 잘 보관해주셔야 합니다.

* SSH - Secure Shell의 줄임말로, 원격 호스트에 접속하기 위해 사용되는 보안 프로토콜입니다. (*Shell(쉘): 명령어와 프로그램을 사용할 때 쓰는 인터페이스를 말합니다.)

SSH 원격 접속

우선, 발급받은 ssh pem key를 이용해서 배포된 EC2 서버에 원격 접속합니다. 터미널에 접속해주세요!

  1. pem key가 저장된 경로로 이동 후 권한을 변경해주어야 합니다.

    chmod 400 {PEM KEY 파일명}
  2. ssh 원격 접속 하기.
    ec2 - 인스턴스 - 연결 - ssh 클라이언트에 있는 명령어를 복사해 실행합니다.

    ssh -i "{pem key 파일 명}" {사용자 ID}@{퍼블릭 IP 혹은 도메인}

    pem key는 RSA 알고리즘 방식으로 생성된 aws에서 제공해주는 공개키입니다.

진입 성공 시 {사용자ID}@{퍼블릭 IP 혹은 도메인} 으로 명령어 창이 변경됩니다.

SSH 접속 실패 시

  1. 가장 많이 실패하는 이유가 보안 그룹 인바운드 설정입니다.
    ssh 접속이 사용하는 기본 포트는 22포트입니다. 해당 포트가 인바운드 규칙에 포함되지 않으면 보안그룹에서 막히는 것입니다.

    ec2 인스턴스 - 보안 그룹 - 인바운드 규칙

    위 사진처럼 모든 IP에서 22번 포트로 접속이 가능하도록 설정합니다.
    (보안을 위해서 추후에 서버 ip만을 허용하도록 변경해야 합니다.)


  1. 다음으로 많이 되는 실패 사유가 인스턴스를 재생성한 경우입니다.
    기존에 접속한 ip의 서버가 달라지면 에러가 발생합니다.

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
    Someone could be eavesdropping on you right now (man-in-the-middle attack)!
    It is also possible that a host key has just been changed.

    2이 경우에는 아래의 명령어를 입력하면 해결된다. {접속했던 ip 주소} 에는 현재 컴퓨터의 ip 주소, 이전에 접속했던 EC2의 ip 주소, 이전에 접속했던 EC2의 도메인을 입력하여 각각 실행해야 한다.

     ssh-keygen -R {접속했던 ip 주소}

방화벽 설정

앞으로도 ssh로 서버 원격접속을 진행할 것이기 때문에, 22번 포트에 대해서 방화벽 허용 설정을 해주어야 합니다. 미설정 시 time out처리가 되므로 복잡한 과정을 거쳐 다시 설정해야 합니다.

  # 22번 포트 방화벽 허용
  sudo ufw allow 22
  
  # 방화벽 실행
  sudo ufw enable
  
  # 방화벽 상태 확인
  sudo ufw status

데이터베이스 설치

저희 서버에서 사용할 데이터베이스를 설치해줍니다.
데이터베이스의 경우, ec2 내부 pc에서 설치해 사용하거나 RDS를 설정하여 외부 통신을 하기도 합니다.
(그러면 아웃바인드 규칙도 데이터베이스 포트(3306)을 추가해주어야 합니다.)

RDS는 비싸기 떄문에 저희는 우선 ec2 내부에 설치하겠습니다.
저희 서버는 현재 MySQL을 사용했으므로 해당 데이터베이스를 설치하겠습니다.

  1. MySQL APT Repository를 설정합니다. MySQL의 APT Repository 패키지를 다운로드합니다.

    wget -P {원하는 위치} https://dev.mysql.com/get/mysql-apt-config_0.8.22-1_all.deb
  2. 다운로드한 패키지를 설치합니다.

    sudo dpkg -i {설치한 위치}/mysql-apt-config_0.8.22-1_all.deb

    여기서 mysql server를 8.0으로 선택하고 OK를 선택해줍니다.

  1. APT 패키지 목록 업데이트
  sudo apt-get update
  1. MySQL Server 패키지 설치

      sudo apt-get install mysql-server

    설치하면 root계정의 비밀번호를 설정하는 창이 나옵니다.
    비밀번호를 설정해주고, 권장 설정을 해줍니다.

  1. 버전 확인 및 서비스 실행

      mysql --version
      sudo systemctl start mysql
      sudo systemctl enable mysql // Ubuntu 서버 재시작시 MySQL 자동 재시작
  2. mysql 서버 연결 테스트

       sudo /usr/bin/mysql -u root -p
          // 또는
        sudo mysql -u root -p
        Enter password: 
        Welcome to the MySQL monitor.  Commands end with ; or \g.
        Your MySQL connection id is 11
        Server version: 8.0.38 MySQL Community Server - GPL
    
        Copyright (c) 2000, 2024, Oracle and/or its affiliates.
    
        Oracle is a registered trademark of Oracle Corporation and/or its
        affiliates. Other names may be trademarks of their respective
        owners.
    
        Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
        mysql> 
    

    비밀번호를 누르고 root계정으로 로그인 시 연결되는 것을 확인할 수 있습니다.

MySQL 외부 접속 허용

MySQL을 설치했지만 외부에서 직접 MySQL로 접근이 가능하도록 방화벽 설정을 해주어야 합니다.

방화벽 설정

  sudo ufw allow mysql // 또는 3306

보안 규칙 설정

3306 포트에 대한 외부 접근이 가능하도록 모든 IP에 대해서 허용을 해주겠습니다.

MySQL 접속 계정 생성 및 권한 부여

우선, 계정을 생성하기 위해 관리자 계정인 root계정으로 로그인합니다.

  sudo mysql -u root -p
  1. 사용할 계정 & 스키마 생성

    CREATE USER 'new ID'@'%' IDENTIFIED BY  'Password'; -- 'localhost' 대신 '%'를 쓰면 외부 ip로 접속 가능하다.
    
     CREATE DATABASE {스키마};
  2. 스키마에 대한 계정 권한 부여

    GRANT ALL PRIVILEGES ON {스키마}.* TO '{계정}'@'%';
    FLUSH PRIVILEGES;
    SHOW GRANTS FOR '{계정}'@'%'; // 권한 확인

IntelliJ에서 EC2 서버 MySQL 접속하기

이제 로컬 PC에서 접근이 되는지 확인해보겠습니다.
인텔리제이 프로젝트를 열겠습니다.(아무 프로젝트나 괜찮습니다.)
우측에 메뉴 중에 database를 설정하고 사용하는 데이터베이스에 맞게 설정합니다.

입력창이 나올텐데요!!

이제 Host 부분에 EC2 서버 IP 혹은 도메인을 입력해줍니다.
User/Password는 이전에 원격 서버에서 설정한 아이디와 패스워드를 입력해줍니다!
Database 부분은 사용하실 schema를 적어주셔도 되구, 공란으로 두고 콘솔 창에서 use {스키마}를 입력해주셔도 됩니다.

모두 입력했다면 Test Connection을 눌러서 잘 되는지 확인이 가능합니다.

Java 설치

  sudo apt update
  sudo apt upgrade
  
  sudo apt install openjdk-17-jdk
  java --version

프로젝트 jar 전송

이제 모든 준비는 마쳤습니다.
프로젝트를 Build해서 생성된 jar파일을 ec2 서버로 전송해주면 됩니다.
배포하실 프로젝트로 이동해서 아까와 같은 메뉴의 gradle - task - build - build 를 실행해주시면 됩니다.

빌드가 성공되면, /build/libs에 jar파일이 두 개 생성됩니다.

💡 파일이 하나가 생성되게 하려면, build.gradlejar.enabled = false를 추가해주세요.

이제 파일을 EC2 서버로 보내겠습니다.

  scp -i "{PEM KEY 명}.pem" "{jar파일 위치&파일명}.jar" {사용자명}@{AWS EC2 도메인 명 or 탄력적 IP 주소}:/home/ubuntu

프로젝트 원격 실행 & 로깅 설정

다시 EC2 서버로 원격 접속합니다.
/home/ubuntu위치에 파일이 잘 전송되었는지 확인합니다.

이제 명령어로 jar 파일을 실행하면 성공입니다!
실행 시에 백그라운드로 실행하지 않으면, ssh 접속이 끊기는 순간 프로세스가 종료됩니다.
즉, 서버 백그라운드로 실행해야 ssh 접속이 끊겨도 실행이 지속됩니다.

# 사용 중인 포트를 차지하고 있는 프로세스가 있다면 종료
sudo fuser -k {프로젝트 설정 포트}/tcp

# 로그 디렉토리가 없다면 생성
mkdir -p /home/ubuntu/logs

# nohup을 사용하여 JAR 파일을 백그라운드에서 실행하고 로그를 /logs/nohup.out 파일에 기록
nohup sudo java -jar ~.jar > /home/ubuntu/logs/nohup.out 2>&1 &

📒 References

profile
Today I Learned

0개의 댓글