[GCP 원데이] 무중단 배포 환경 (Git, Webhook)

2021. 4. 26. 18:06GCP/원데이

1. Git

1) Git 이란 ?

소프트웨어 개발 과정에서 중간 버전별 코드 상태를 기록할 수 있다. 이를 형상관리툴이라고 하며, Git은 가장 인기있는 툴이다. Git에서는 소프트웨어의 버전을 커밋 단위로 저장하고 여러 개의 줄기(Branch)를 만들어 여러 명에서 함께 개발이 가능하다.

2) 디렉토리, 파일 생성

'git-practice' 디렉토리와 그 하위에 'file1.js' 파일을 생성해준다. 그리고 터미널 창에서 해당 파일을 실행하여 동작을 확인한다.

3) Git Repository 생성 및 커밋

// 깃 폴더 생성
git init

// 깃 레포지토리 연동
git remote add origin [GitHub Repository URL]

// 깃 추가
git add .

// 깃 커밋 메시지 설정
git commit -m "Initial Commit"

// 깃 푸시 (현재 브랜치를 지정해둔 upstream 브랜치로 푸시)
git push --set-upstream origin master

// 일반적인 푸시
git push

// 깃 상태 확인
git status

 

 

 

2. Webhook

1) Webhook 이란?

Webhook은 깃 허브에서 특정 이벤트 발생 시 다른 URL로 API 호출을 할 수 있게 해준다. 깃 허브의 Webhook에 Jenkins URL을 등록을 해준 뒤, Jenkins에서 깃 허브로부터 온 API 요청을 받아 저장소의 소스를 다운받고 프로젝트를 빌드하여 JAR 파일로 만든 후 인스턴스에 배포를 해주도록 설정 해준다. 단, 권한이 필요하기에 별도의 설정이 필요하다.

2) Java 설치

우선 Java가 설치안된 인스턴스에 Java를 설치해준다.

sudo yum remove java*
sudo yum list java*
sudo yum install -y java-1.8.0-openjdk-devel.x86_64

javac -version
which javac
readlink -f /usr/bin/javac

sudo vi /etc/profile
source /etc/profile

echo $JAVA_HOME

3) Jenkins 설정

Git을 등록해주고 Webhook 설정과 실행할 명령어를 작성해준다.

이 후 각 인스턴스에서 빌드한 파일을 배포할 수 있도록 명령어를 작성해준다.

각 인스턴스 IP로 접속을 하여 확인을 해보면 도커를 사용하지 않았기 때문에 도커를 이용하여 배포했을 때 사용한 8080번 포트가 아닌, 80번 포트로 접속이 되는 것을 알 수 있다.

4) 자동 배포

실행중이던 모든 애플리케이션을 각 인스턴스이 접속하여 종료해준다.

ps -aux | grep java
sudo kill -9 [모든 Java 프로세스 ID]

이 후 깃허브에 접속하여 Webhook 설정을 해준다. Payload URL의 경우 Jenkins의 IP(http 포함) 뒤에 'github-webhook' 문자와 마지막에 '/'를 넣어 설정해준다.

다음으로는 애플리케이션이 8080포트로 동작할 수 있도록 application.properties 설정을 수정해준다.

server.port=8080

변경된 내용을 반영할 수 있도록 깃에 커밋과 푸시를 진행해주고, Jenkins로 돌아와 확인을 해보면 새로운 빌드가 생기는 것을 확인할 수 있다. 다시 각 인스턴스 IP로 접속할 경우, 80포트가 아닌 8080포트로 접속해야 동작이 되는 것을 확인할 수 있다.

5) 자동 배포 문제 해결

소스 코드를 수정하고 배포를 했을 때, 변경된 사항이 제대로 적용이 되지 않는 문제가 발생한다. 인스턴스에 접속하여 nohup.out 파일에서 로그를 확인해보면, 이미 8080 포트를 사용하기에 발생하는 문제임을 알 수 있다. 즉, 8080번 포트를 종료해준 뒤 새로운 프로세스를 띄우는 행위를 적용하지 않아서 생기는 문제다.

 

특정 포트를 사용하는 프로세스를 확인할 때에는 주로 'lsof' 명령을 많이 사용하지만, CentOS에서 기본적으로 제공해주지 않기 때문에 각 인스턴스에 별도로 설치해주고, lsof 명령어로 8080 포트를 사용하는 프로세스를 죽이는 명령을 Jenkins 스크립트에 적용해준다.

sudo yum install -y lsof
sudo kill -15 $(sudo lsof -t -i:8080)

6) 무중단

변경된 사항을 적용하여 자동으로 배포가 되는 과정은 완료가 되었으나, 무중단으로 이루어지지 않는다. 그 결과로 한번에 3개의 인스턴스에 배포를 하는 과정에서 스트레스 테스트를 적용했을 때 502 에러가 발생하는 것을 알 수 있다.

 

방법은 여러가지가 있지만, 인스턴스가 배포가 되는 동안 딜레이를 주어 간단하게 해결할 수 있다. 1번 인스턴스를 제외한 다른 2개의 인스턴스의 스크립트에 sleep 명령어를 추가해준다.

// 30초 딜레이
sleep 30

물론, 실제 서비스라면 30초의 딜레이로 배포하는 것은 권장하지 않는다. 다른 해결책으로는 Jenkins Pipeline을 이용한 방법을 권장한다. 하지만 배포 성공과 실패를 구분하고 실패 시 어떻게 대처할 것인지에 대한 고민이 필요하다.

728x90