본문 바로가기
make-delivery 프로젝트

[#6] Jenkins를 이용하여 CI/CD 환경 구축해보기

by sunggook lee 2020. 11. 26.

 

 

제가 진행했던 make-delivery 프로젝트를 배포하기 위해서는 리눅스 서버에서 Git Pull을 하여 소스코드를 가져온 다음 maven을 이용하여 build를 하고 jar파일을 실행해야 했습니다. 하지만 매번 git pull을 하고 빌드를 하고 jar파일을 실행하는 것은 지루하고 반복적인 과정이며 불필요한 시간 낭비였습니다.

 

따라서 이러한 문제를 해결하기 위해 여러 글들을 읽어봤고 예전에 Agile방식에 대한 글을 읽었던 경험이 생각나 검색 후 CI (지속적 통합)이라는 개념을 알게 되었습니다.

 

CI란 개발자들이 빠른 주기로 작업한 내용을 통합 브랜치에 통합하고 빌드하는 개발방식을 말합니다.

 

# CI를 해야하는 이유

tjdrnr05571.tistory.com/12
 

IT 기업들에서 왜 Jenkins를 사용할까?

CI (지속적통합)은 개발자들이 빠른 주기로 작업한 내용을 통합 브랜치에 통합하고 빌드하는 개발방식을 말합니다. 통합이란 개인이 작업한 코드를 공용 작업환경에 올리는것을 말하고 이 과정

tjdrnr05571.tistory.com

 

Jenkins를 이용한 CI 과정 

1. 개발자가 Github에 수정한 코드를 Push한다.

2. Github은 이를 감지하고 Jenkins에 Github Webhook을 보낸다.

3. Jenkins에서는 Github Webhook을 JSON파일로 받고 파싱한다.

4. 파싱하여 변화된 branch를 파악하고 이 branch의 코드를 Git clone한다.

5. Jenkins에서는 Maven 빌드과정, 컴파일 -> 테스트 -> 패키징을 거쳐 빌드한다.

 

이 과정을 개발하기 위해 여러 글들을 읽어보니 모두 젠킨스 플러그인을 이용하는  글들이었습니다.하지만 제가 젠킨스를 서버에 설치할 때 젠킨스 공식 사이트의 플러그인 파일 서버에 오류가 있어 플러그인을 다운받지 못하는 상황이었습니다. (플러그인 수동 설치조차 불가능했습니다). 어차피 CI와 CD에 대해 제대로 이해를 하고 구현하고 제 프로젝트에 맞게 자동화를 하려면 bash script를 이용해 프로젝트에 맞는 자동화가 필요하다고 생각하여 젠킨스 플러그인을 아예 사용하지 않고 bash shell script를 이용해 구현해 보기로 결정했습니다.

Jenkins를 이용해 전체적으로 구현해야할 방향은 다음과 같았습니다.

1. Github Webhook

2. bash parse using python

3. git clone -b {해당 branch}

4. maven compile, test, build

5. github api를 이용해 github으로 빌드&테스트 성공 실패 여부 전송

6. 배포서버로 빌드파일 전송

7. 젠킨스 서버에서 ssh로 배포서버 접속 (pub키 설정 먼저해야함)

8. 젠킨스 서버에 있던 빌드 스크립트를 배포 서버에서 실행

 

위 과정을 한번에 적용하기 위해 Jenkins pipeline 사용했습니다. 젠킨스의 잡들은 원래 하나하나 지정해줘서 동작하게끔 작동했는데 젠킨스 파이프라인을 이용하면 이 과정을 스크립트 한곳에서 모아서 적용시킬 수 있으며 소스코드에 Jenkinsfile로 포함시키기도 용이합니다.

 

1. Github Webhook

Github Webhook을 받을 젠킨스 url

Github Webhook 설정페이지에서 "Github토큰@{젠킨스서버url}/job/{job-name}/buildWithParameters?token={job-token} " 으로 Github Webhook을 보내면 Jenkins에서는 토큰을 확인하고 payload를 받습니다. 젠킨스 관리 페이지에서 String Parameter를 payload로 지정하면 json형태의 payload를 받아서 사용할 수 있습니다.

 

Github Webhook payload

2. bash parse using python & git clone -b {해당 branch}

 

payload를 받으면 다음과 같이 python을 이용하여 shell 상에서 parsing을 한 뒤  젠킨스에서 Git Checkout & Git Clone할 Branch와 Commit Id를 변수로 파싱합니다.

 

GIT_CHANGE_BRANCH_NAME = sh(returnStdout: true, script: 'echo ${payload} | python3 -c \"import sys,json;print(json.load(sys.stdin,strict=False)[\'ref\'][11:])\"').trim()
GIT_COMMIT_SHA = sh(returnStdout: true, script: 'echo ${payload} | python3 -c \"import sys,json;print(json.load(sys.stdin,strict=False)[\'head_commit\'][\'id\'])\"').trim()
echo "arrive ${GIT_CHANGE_BRANCH_NAME}"
sh "git clone -b ${GIT_CHANGE_BRANCH_NAME} --single-branch \"https://github.com/f-lab-edu/make-delivery.git\""

 

3. maven compile, test, build

 

젠킨스 서버에서 변경된 코드를 git clone받으면 빌드,테스트 할 통합된 코드가 젠킨스 서버에 생성됩니다. 이 코드를 이용해 maven build를 해줘야 합니다.

 

 

다음과 같이 maven build를 해주면 컴파일-> 테스트 -> 패키징 까지 완료하고 jar파일을 다음과 같은 경로에 저장합니다.

 

4. github api를 이용해 github으로 빌드&테스트 성공 실패 여부 전송

 

빌드가 성공한다면 이를 Github에 빌드가 성공했다고 GITHUB API를 이용해 알려줘 Pull request에 체크표시로 성공여부를 표시해줄 수 있습니다.

 

 

젠킨스 파이프라인에서는 post를 이용해 어떠한 단계 후 성공하거나 실패 했을 때 어떠한 행위를 할 수 있도록 post를 제공해줍니다. 리눅스 쉘 상에서 post를 보내야 하므로 curl을 사용하여 토큰값을 포함해 보내줍니다. 빌드가 성공하고 GITHUB API를 이용해 빌드의 성공 여부를 GITHUB에 보내주는 것까지 완료했다면 CI 과정은 완료된 것입니다.

 

5. 배포서버로 빌드파일 전송

 

이렇게 코드의 지속적 통합을 완료하고 나면 서버에 jar파일을 배포해야 합니다. 요즘은 보통 CD에 Docker를 이용하지만 직접 jar파일을 배포해보고 싶어서 쉘에서 구현해봤습니다.

 

scp를 이용하여 jar파일 전송

scp를 이용하여 빌드 완료된 jar파일을 젠킨스 서버에서 배포 서버로 전송합니다. 이 과정에서는 ssh 공개 키 설정이 양쪽 서버에서 완료되어야 scp 파일 전송이 가능합니다. (id_rsa.pub , authorized_keys를 이용하여)

 

6. 젠킨스 서버에서 ssh로 배포서버 접속 (pub키 설정 먼저해야함)  & 젠킨스 서버에 저장해둔 빌드 스크립트를 배포 서버에서 실행

 

배포서버에 ssh 접속한 뒤 배포 스크립트 실행

ssh 공개 키 설정이 완료되었다면 젠킨스 서버에서 배포서버로 접속한 뒤 젠킨스 서버에 저장해두었던 deploy.sh 배포 스크립트를 실행해줄 수 있습니다.

deploy.sh

만약 현재 배포가되어 실행되고 있는 어플리케이션이 있다면 이를 pgrep -f make-delivery 로 백그라운드로 돌아가는 어플리케이션을 확인하여 이를 kill -15로 중단시켜줍니다. 만약 돌아가는 어플리케이션이 없다면 그냥 배포를 새로 시작해주면 됩니다.

 

또한 jenkins pipeline내에서 스크립트가 실행되는 것이니 터미널에서 백그라운드로 실행시켜주어야 합니다. 따라서 nohup java~~ >> nohupt.out 2>&1 & 로 실행시켜줍니다.

 

이 과정까지 완료되었다면 CI/CD 까지 전부 구현이 완료된 것입니다. CD쪽은 도커를 이용하는 것이 여러모로 좋은 방법이니 이는 다음 글에서 작성하겠습니다.

 

CI/CD 과정을 적용한 전체 파이프라인 Jenkinsfile은 아래 github url에서 확인하실 수 있습니다.

github.com/f-lab-edu/make-delivery/blob/develop/Jenkinsfile

 

프로젝트 url 

github.com/f-lab-edu/make-delivery

 

f-lab-edu/make-delivery

구매자에게 음식 배달을 제공하는 서비스입니다. Contribute to f-lab-edu/make-delivery development by creating an account on GitHub.

github.com

참고

jojoldu.tistory.com

 

기억보단 기록을

Java 백엔드, AWS 기술을 익히고 공유합니다.

jojoldu.tistory.com

git-scm.com/book/ko/v2/GitHub-GitHub-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8C%85

 

Git - GitHub 스크립팅

몇 가지 방법으로 인증할 수 있다. 사용자이름과 암호가 필요한 Basic 인증도 가능하지만, 개인 엑세스 토큰을 사용하는 게 낫다. 설정 페이지의 “Applications” 탭에서 생성할 수 있다. 토큰을 어

git-scm.com

doogle.link/ssh-%ED%82%A4%EC%9D%B8%EC%A6%9D%EC%9C%BC%EB%A1%9C-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-%EC%97%86%EC%9D%B4-%EC%9E%90%EB%8F%99%EB%A1%9C%EA%B7%B8%EC%9D%B8-%ED%95%98%EA%B8%B0/

 

SSH 키인증으로 비밀번호 없이 자동로그인 하기 | 두글 블로그

이제는 서버 작업을 위해 필수인 SSH 인데요. 접속하려면 항상 비밀번호를 입력해야 하는 번거로움이 있었습니다. 여기서는 SSH 로그인을 키인증으로 대체하고 자동로그인을 하는 방법을 알아보

doogle.link

 

 

댓글