일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- AWS 자격증
- EC2
- Amazon Web Service
- 자바
- 쓰기 고려
- 조대협
- 코드프레소
- iam
- 몽고디비
- java spring framework
- NoSQL
- 스프링 프레임워크
- 대용량 아키텍처와 성능 튜닝
- Text Index
- Code Presso
- STS
- 읽기 고려
- JPA
- mongoDB
- 위치 기반 쿼리
- Spring Framework
- Java
- 스프링
- Write Concern
- aws
- Jenkins
- Spring
- AWS Developer
- 스프링 부트
- spring boot
- Today
- Total
개발과 기록의 조화
[Jenkins] Jenkins , EC2 를 이용한 스프링 부트 CI/CD 파이프라인 구축 본문
해당 게시물은 학습 및 기록 목적으로 작성되었습니다. 사실과 다른 내용이 있을 수 있으며, 오류가 있거나 궁금한 점은 댓글이나 dlaudtjr07@gmail.com 으로 메일 주시면 감사하겠습니다.
이번 게시물에서는 Jenkins와 아마존 EC2 서버를 이용한 스프링 부트 CI/CD 파이프라인 구축 실습을 진행합니다.
본 실습에 앞서 몇 가지의 조건이 충족되어야 진행에 차질이 생기지 않습니다.
- 2개 이상의 EC2 인스턴스 (구축, 배포용)
- JAVA 8 (openjdk-1.8)
- maven 3.x (구축서버 , 필자는 3.6)
- Git (구축서버)
젠킨스 설치
설치 명령어는 아래와 같습니다.
wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -
echo deb https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list
sudo apt-get update
sudo apt-get install jenkins
설치가 완료되면 서비스가 자동으로 시작됩니다. 혹여나 실행 안되어 있을 수도 있으니 systemctl 명령어로 확인합니다.
sudo systemctl status jenkins
기본적으로 젠킨스는 8080 포트로 지정되어 있습니다. 변경을 원하면 아래 경로를 통해 변경할 수 있습니다.
sudo vi /etc/default/jenkins
이제 EC2의 서버 ip(혹은 도메인) , 포트를 브라우저에 입력해 들어갑시다. 초기 접근 시 젠킨스 언락을 요청하는 UI가 출력됩니다.
빨갛게 나와있는 경로를 통해 코드를 알아낸 후 다음으로 넘어갑니다. 그 후 아래와 같이 똑같이 진행하도록 합시다.
기본 설정이 완료되었습니다. Start using Jenkins를 클릭하면 아래와 같은 화면이 출력됩니다.
Sample 프로젝트 배포
Git , 배포용 서버에 각각 SSH Key 연동
SSH 키를 저장하기 위한 디렉토리를 생성합니다. 이 디렉토리에 SSH Key를 생성할 예정입니다.
mkdir /var/lib/jenkins/.ssh
cd /var/lib/jenkins/.ssh
SSH 키를 생성합니다. 생성할 때 발생하는 커맨드 입력은 모두 스킵합니다.(엔터 2번)
ssh-keygen -t rsa -f /var/lib/jenkins/.ssh/Key이름
생성이 완료되었습니다. Github로 넘어갑시다.
Settings -> Deploy keys- add deploy key 순서입니다. 하단에 있는 ssh키는 신경 안쓰셔도 됩니다.
등록할 이름 , 아까 만들었던 SSH Public 키를 등록해야 합니다. 해당 경로로 이동해 키를 복사해 붙여넣어 줍시다.
sudo vi /var/lib/jenkins/.ssh/Key이름.pub
등록 완료 시 아래와 같이 SSH 키가 등록된 것을 확인할 수 있습니다.
다시 젠킨스로 넘어갑시다. 젠킨스 쪽에서 Private 키 등록을 해야 비로소 연동이 완료됩니다.
Credentials -> System으로 이동해 Global credentials 항목을 클릭합니다.
아래와 같이 설정합니다. Private Key는 이전에 Public 키 위치와 똑같은 곳에 위치합니다.
sudo vi /var/lib/jenkins/.ssh/Key이름
생성 시 아래와 같이 SSH 키가 연동된 것을 확인할 수 있습니다.
배포 서버와도 SSH key를 연동합시다. 위와 같은 과정으로 배포 서버에서 똑같이 SSH 키 저장 디렉토리 생성 후 Key를 생성합시다.
생성 후 Jenkins 관리 -> 시스템 설정으로 이동합니다.
밑으로 내리다 보면 Publish over SSH 항목이 나옵니다. 그 중에서 SSH Server를 정의해 주어야 합니다.
- Name : 말 그대로 설정할 이름입니다.
- Hostname : 배포용 EC2 서버의 ip주소나 도메인 주소를 지정합니다.
- Username : 배포용 EC2 서버의 계정(root) 이름을 지정합니다.
- Remote Directory : SSH 통신을 통해 파일을 전송받을 디렉토리의 경로입니다. 이 경로를 잘 기억해 두세요.
- Passphrase/Password : SSH key를 통해 인증하므로 비워둡니다. (알아서 채워집니다)
- Path to key :SSH Key의 경로인데, 필자는 직접 키를 복사해 등록합니다.
- Key : SSH Private Key를 '직접' 등록하는 항목입니다. 키를 복사해 붙여넣어 줍시다.
- Port : SSH 포트는 기본적으로 22번 포트입니다.
설정이 완료되면 마지막으로 Test Configuration을 통해 연결 테스트를 진행하셔야 합니다. Success 시에는 정상적으로 연결에 성공했다는 뜻이지만, 연결 실패 시 그에 따른 에러 코드가 출력됩니다.
Test 연결이 성공하면, 다음 단계로 넘어갑니다.
Jenkins에 Maven 연동
Jenkins 관리 -> Global Tool Configuration으로 이동합니다.
Maven 항목에 EC2 서버 내부에 설치된 Maven 경로를 지정해 줍니다.
item 생성 및 설정
좌측 새로운 item을 클릭합니다.
이름을 정한 후 Freestyle project를 선택 후 OK를 클릭합니다.
item 구성으로 진입하면 소스 코드 관리, 빌드 , 빌드 후 조치 세 가지 설정을 진행합니다.
소스 코드 관리로 진입해 Git URL을 지정하고 해당 프로젝트에 연동한 ssh Key 및 브랜치를 등록합니다.
빌드 부분에서는 이전에 설정한 Maven 구성을 적용합니다.
- clean package : 패키지 정리
- tomcat:redeploy : 톰캣 매니저를 통한 재배포
- -D maven.test.skip=true : 테스트 생략
빌드 후 조치 단계에서 삽질 많이 합니다. 신중한 확인이 필요합니다.
Source files는 배포될 파일 경로를 의미합니다. Git 프로젝트를 루트삼아 경로를 지정합니다. jar로 배포할 예정이므로 jar 파일의 경로를 지정합니다. 필자의 경로는 target/ 입니다.
Remove prefix는 배포할 파일(들)의 상위 경로를 지정합니다.
Remote directory는 이전에 잘 기억해 놓으라고 했던 경로, SSH Remote Directory 경로를 지정합니다. 그런데 잘 보면 이전에 설정했던 경로랑 다릅니다.
Reomte Directory에서 지정해야 하는 경로는 /home/ubuntu/AskAnything 내부에 있는 디렉토리 경로를 지정하라는 의미입니다. 경로가 하나라도 삐끗나면 정상적으로 빌드가 진행되지 않습니다.
우분투 내 디렉토리는 /home/ubuntu/AskAnything/delpoy 로 구성되어야 하는 것입니다.
마지막으로 쉘 스크립트를 통한 명령어 실행입니다.
cd 설정디렉토리
sudo ./스크립트 이름.sh
sh 파일 구성은 아래와 같습니다.
#! /bin/bash
echo "Shutting down Previous Service ... "
fuser -k 8081/tcp
echo "Starting New AskAnything Service ... "
export BUILD_ID=dontKillMe
nohup java -jar 파일이름.jar >> nohup.out 2>&1 &
fuser -k 8081/tcp
필자는 스프링 부트 프로젝트 서버 실행 포트를 8081번으로 지정했으므로 8081번 포트를 죽이는 명령어를 수행합니다.
export BUILD_ID=dontKillMe
젠킨스에서 nohup을 통한 백그라운드 프로세스가 진행되지 않습니다. 이는 젠킨스에서 프로세스를 안정적으로 종료하기 위해 ProcessTreeKiller 라는 기능이 구현되어 있기 때문인데, 젠킨스 빌드를 종료하면 해당 자식 프로세스(스프링 부트) 또한 종료되므로 BUILD_ID 매개변수에 dontKillMe 값을 넣어주어 빌드가 완료되어도 자식 프로세스가 죽지 않게끔 해 주어야 합니다. (해당 작업은 매개 변수 항목에서도 구현 가능합니다.)
nohup java -jar 파일이름.jar >> nohup.out 2>&1 &
- nohup java -jar 파일이름.jar : nohup으로 jar 파일을 실행합니다.
- nohup.out : nohup.out 파일에 스프링 부트 로그를 저장합니다.
- 2>&1 : 표준 출력이 전달되는 곳으로 표준에러를 전달합니다. (0: 표준입력 1: 표준출력 2:표준에러)
- 마지막 & : 백그라운드 실행
쉘 스크립트가 실행되지 않을 시 chmod +rx 스크립트이름.sh 로 권한을 할당해 줍니다.
샘플 프로젝트 실행해보기
깃허브에 프로젝트 Push 후 젠킨스에서 빌드를 클릭합니다.
빌드에 성공했고 SSH 명령어를 통한 파일 전송 또한 정상적으로 수행됬습니다.
빌드 히스토리에 파란색은 성공, 노란색은 불안정, 빨간색은 실패를 의미합니다.
배포 서버의 IP와 포트번호(혹은 도메인)를 치고 들어가면 정상적으로 사이트가 서비스되는 것을 확인하실 수 있습니다.
해당 글은 코드프레소 DevOps Roasting 코스를 수강하면서 작성한 글입니다.