AWS를 이용한 게시판 서비스 배포 #3

임상규·2023년 10월 18일
1

AWS

목록 보기
25/33
post-thumbnail

이전 포스트)
AWS를 이용한 게시판 서비스 배포 #1
AWS를 이용한 게시판 서비스 배포 #2

Route 53 레코드 생성

위 그림과 같이 레코드를 생성했다.
트래핑 라우팅 대상으로 ALB를 추가하고 도메인으로 서버에 접근이 가능한지 확인한다.

정상적으로 접근이 가능했다.

서비스 테스트 하기

먼저 로그인 테스트를 하였다.

정상적으로 로그인 되었고

해시태그 검색도 정상적으로 작동했다.

글쓰기 테스트,

수정 테스트,

댓글 테스트도 잘 성공하였다.

Jenkins를 사용한 CICD 자동화

수동으로 소스코드를 배포해보았으니 이제는 Jenkins를 이용하여 CICD 자동화를 하였다.

목표 아키텍처

Jenkins용 EC2 생성

먼저 Jenkins용 인스턴스를 생성한다.

인스턴스 이름, 키페어, VPC를 설정한다.

그 다음 22, 8080포트를 통해 OpenVpn이 들어갈 수 있도록 설정하고
8080번 포트로 ALB가 들어갈 수 있도록 설정한다.

그 외에 값들은 디폴트값으로 두고 인스턴스를 생성하였다.

스왑파일을 이용한 메모리 설정

이전 포스트 참고

Jenkins도 프리티어 EC2 이므로 빌드 멈춤 현상이 발생하였다.
따라서 스왑파일을 생성하여 RAM의 크기를 늘려주었다.

패키지 다운로드

Jenkins 수동배포를 위해 다운받은 패키지는 다음과 같다.

  • Java
  • Git
  • Ansible
  • Jenkins

Java, Git, Ansible은 yum을 통해 바로 다운로드 받을 수 있으나 Jenkins는 바로 다운받을 수 없다.

따라서 Jenkins 공식문서를 참고하였다.
아마존 리눅스에 Jenkins 다운로드

Pem키를 통한 인증

Jenkins 인스턴스에서 애플리케이션 서버 인스턴스에 접근을 하기 위해서는 인증키가 필요하다.

따라서 Jenkins 인스턴스에 Pem키를 넣어주어야 한다.

FileZila를 통해 Pem키를 Jenkins-ec2에 넣고 Pem키에는 너무 많은 권한이 필요하지 않으므로 권한 수정을 진행하였다.

Ansible 플레이북에서 Pem키의 위치를 /usr/local/share 로 정의하였다.
따라서 Pem키를 해당 경로로 복사하였다.

현재는 Pem키의 소유자와 소유그룹은 root로 되어있는데, Jenkins에서 사용할 수 있도록
권한을 수정하였다.

Jenkins 실행

sudo systemctl start jenkins

Jenkins를 실행시킨다.

ps -ef | grep jenkins

정상적으로 Jenkins가 실행되었는지 확인한다.

실행하였으면

<Jenkins IP주소>:8080

로 들어간다.

비밀번호를 입력하라는 창이 나오는데 위에 경로로 가서 해당 파일을 열면 비밀번호를 확인할 수 있다.

그 다음 추천 플러그인을 설치하였다.

플러그인을 설치하면 계정 정보를 입력하는 화면이 나오고 입력을 완료하였다.

Jenkins에 들어오면 좌측에 새로운 Item이라는 카테고리가 있고 클릭하면

해당 창이 나오고 파이프라인을 선택하고 이름을 입력한다.

그 후 파이프라인 스크립트를 구성해야하는데 아래와 같은 스크립트를 작성하였다.

pipeline{
    agent any

    stages {
         stage ('Workspace Clean') {
            steps {
             cleanWs()   
            }
        }

            stage('Git Clone') {
                steps {
                    sh"""
                    echo ${WORKSPACE}
                    git clone https://github.com/sk-lim19f/project-board.git
                    """
                }
            }

            stage('Gradle Build') {
                steps {
                    sh """
                    cd project-board
                    chmod +x gradlew
                    ./gradlew clean build
                    """
                }
            }

            stage('Ansible Deploy') {
                steps {
                    script {
                        MY_KEYPAIR_NAME = ""
                        MY_APP_PRIVATE_IP = ""

                        sh """
                        git clone https://github.com/sk-lim19f/project-board-ansible.git
                        cd project-board-ansible

                        sed -i 's/MY_KEYPAIR_NAME/${MY_KEYPAIR_NAME}/g' hosts/hosts
                        sed -i 's/MY_APP_PRIVATE_IP/${MY_APP_PRIVATE_IP}/g' hosts/hosts

                        ansible-playbook deploy.yml -i ./hosts/hosts --extra-vars "deploy_hosts=app"
                        """
                    }
                }
            }
        }
    }

➡️ Workspace Clean 스테이지에서는 cleanWS() 스텝을 통해 이전 빌드에서 생성된 모든 파일을
   삭제하고 새로운 빌드를 위한 깨끗한 작업 디렉토리를 만든다.
   Git Clone 스테이지에서는 git clone 명령어를 통해 게시판 서비스를 복제한다.
   Gradle Build를 실시하고 Ansible을 사용하여 애플리케이션을 배포한다.
   Ansible 플레이북이 있는 깃 레포지토리를 복제하고 설정파일 변수를 변경한 후 배포를 수행한다.

Ansible Playbook

Ansible Playbook 저장소

쉽게 정리하면 환경변수들이 정리되어있고 nginx 실행, java 실행 등 배포에 관련된 내용들이 들어있다.

Error(1) - port 22: Connection timed out

배포가 진행되다가 해당 에러를 접하게 되었다.
app-sg로 가서 Jenkins-sg가 22번 포트로 들어올 수 있도록 보안그룹을 수정하였다.

Error(2) - Host key verification failed

해당 에러는 app-ec2에 접근하려고 하였으나 접근키 인증에 실패했다는 에러메시지이다.

내가 해결한 방법이 정답인지는 모르겠다.
보통 내가 어떤 작업을 하기위해 SSH연결을 할때 주로 보았던 에러메시지가

Permission denied

이었던것이 생각나서 Jenkins 파이프라인에 sudo 권한을 부여하였다.

sudo sed -i 's/MY_KEYPAIR_NAME/${MY_KEYPAIR_NAME}/g' hosts/hosts
sudo sed -i 's/MY_APP_PRIVATE_IP/${MY_APP_PRIVATE_IP}/g' hosts/hosts

sudo ansible-playbook deploy.yml -i ./hosts/hosts --extra-vars "deploy_hosts=app"

sudo 권한을 부여하고 빌드를 돌리니 새로운 에러메시지를 뱉어냈다.

해당 에러메시지를 확인해보니 sudo 권한을 얻기 위해서는 비밀번호가 필요하다는 것이었다.

따라서 Jenkins에게 비밀번호 필요없이 sudo 권한을 주어야했다.
해당 문제 해결은 아래 블로그를 참고하였다.

Jenkins에서 sudo권한 사용

빌드 성공

정상적으로 빌드가 성공하였다.

이제 Private IP 주소가 아닌 도메인으로 Jenkins에 접근할 수 있도록 레코드에 Jenkins를 추가하였다.

먼저 Jenkins에 접근 가능한 레코드를 생성하였고 대상그룹을 생성하였다.

대상그룹은 my-project-board-jenkins-ec2를 가르키고 있다.

그 다음 대상그룹과 로드밸런서 HTTP:443에 연결하였다.

상태검사가 비정상으로 나와서 상태 검사 경로를 /login으로 바꾸었다.
(Jenkins 도메인의 루트페이지 URL)

끝!!!

아마 다음 게시판 서비스 포스팅은 겪은 에러와 해결 방법에 대해서 작성하지 않을까 싶다.

  • 사용한 모든 AWS 리소스등은 최대한 비용 절약을 위해 프리티어를 사용하였지만
    각 리소스들은 트래픽 횟수, 사용 시간 등을 기준으로 프리티어 사용량을 계산한다.
    따라서 데모페이지는 따로 운영하지 않을 계획이다!
profile
Cloud Engineer / DevOps Engineer

0개의 댓글