목표
문제
- 지난번 EC2 배포(
링크
) 이후, 배포 후 변경 점을 서버에 적용하기 위해서 이미 .jar파일 실행을 종료하고 파일 변경 후 다시 실행시켜야한다는 번거로움이 있었다.
- 그래서,
CI/CD
를 적용하기로 했다.
- 현재 우리의 프로젝트는 상당히 가볍고 심플한 단계이므로 하나의 EC2안에서 젠킨스와 .jar을 둘 다 실행시킬 예정이다.

목표 과정
- SpringBoot 프로젝트에서 변경 후 GitHub 레포에 push
- EC2에서 해당 변경을 인지하여 clone
- 해당 SpringBoot 프로젝트 build
- 빌드된 .jar 파일을 실행
Jenkins 설치 및 설정
- Jenkins는 JVM환경에서 돌아가는 CI/CD 툴이다.
- 프로젝트의 소스의 통합과 테스트 및 빌드, 배포를 위해 사용
EC2에 Jenkins 설치
- 지난번 과정에서 EC2에 JDK는 설치하였으므로 JDK설치는 생략
- apt 업데이트
apt-get update
- Jenkins Repository에서 Key 받아오기
wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -
- sources.list에 Jenkins.list 추가
sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > \
/etc/apt/sources.list.d/jenkins.list'
sudo apt-get install jenkins
sudo systemctl start jenkins
sudo systemctl stop jenkins
sudo systemctl restart jenkins
sudo systemctl status jenkins
- 상태 체크 시, 아래와 같이 확인되면 잘 실행된 것

- 기본적으로 Jenkins를 처음 설치하면 8080포트가 기본으로 설정되어 있는데, 필요하다면 포트 변경이 필요하다
sudo vi /etc/default/jenkins
- vim 에디터를 켜서 포트 설정을 원하는 포트번호로 변경해준다
- vim 에디터 INSERT는
i
입력
- INSERT 나올 떄는
esc
입력
- 저장 후 종료는
:wq!
입력

- 위와 같이 설정하고 재시작을 해도 여전히 8080포트로 설정되어있을 경우에는
- jenkins.service 파일에 JENKINS_PORT 환경변수를 변경해줘야한다.
- jenkins 상태체크 시 확인된 jenkins.service 파일의 위치를 vim 에디터로 실행 후 JENKINS_PORT 변경
sudo vi /lib/systemd/system/jenkins.service

- 포트 변경 완료 후, Jenkins 재시작
- 변경된 포트의 EC2 인바운드 규칙이나 방화벽 설정도 필요하다면 해줘야한다.
Jenkins 설정
http://{EC2의 퍼블릭 IPv4 주소}:{설정한 포트번호}
에 접속하면 초기 비밀번호 화면이 나온다.

- 비밀번호 위치에 있는 비밀번호를 확인하여 Administrator password에 입력
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Install suggested plugins
을 눌러 추천 플러그인을 설치
- 로그인 정보를 입력한다.
- 이 로그인 정보는 이 젠킨스를 접속할 떄 사용할 것이므로, 잊어버리면 안된다.
- 여기까지 되면, Jenkins를 사용할 준비 완료!

Jenkins에 GitHub 연동 및 설정
- GitHub의 토큰은 이미 발급받았다고 판단하고 진행
GitHub Token 등록
Jenkins 관리
→ Manage Credentials
→ System
→ Global credentials
→ Add Credentials

- Username : GitHub ID
- Password : GitHub Token
- ID : 해당 Credentia 이름
GitHub Server 등록
Jenkins 관리
→ 시스템 설정
→ GitHub Servers
→ Add GitHub Server

- Add 버튼을 눌러
- Kind : Secret Text 선택
- Scret : GitHub token
- ID : 이 Credentials의 이름
- Name 설정 후 Test connection으로 연결 확인 후 저장
GitHub webhook 등록

- 등록하고자 하는 GitHub Repository 접속
- Settings → Webhooks → Add webhook

- PayloadURL : https://{젠킨스 hostIP}:{포트번호}/github-webhook/
- Content type : application/json으로 설정 후
- Add webhook
SpringBoot 프로젝트 빌드 및 배포
Gradle 설정
- 해당 프로젝트를 그래들로 빌드할 것이므로 그래들 설정을 해준다
- 플러그인 설치
- Jenkins 관리 → 플러그인 관리 → 설치가능 탭 → 필터 검색
Gradle Plugin
: 프로젝트를 Gradle로 빌드할 수 있는 플러그인
Post build task
: 빌드 로그를 판단해 batch/shell을 실행하는 플러그인


- Jenkins 관리 → Global Tool Configuration → Gradle → Add Gradle

프로젝트 추가
- 대시보드에서
+ 새로운 Item
클릭
- 현재는 아주 간단한 작업을 수행할 것이므로,
Freestyle project
를 만
들 것이다

1. 소스코드 관리
- Git으로 설정
- 연동하고자 하는 GitHub Repository URL 입력
- Credentials 은 이전에 등록했던 깃헙 아이디와 토큰을 가지고 있는 것을 선택

2. 빌드 유발
- GitHub Repo에 push하면 웹훅이 해당 젠킨스로 내용 전달해주는 것을 트리거로 빌드할 수 있도록 하는 설정
GitHub hook trigger for GITScm polling
활성화

3. 빌드
- Gradle로 빌드 할 것이므로
Invoke Gradle script
로 추가
- Gradle Version은 위에서 설정한 Gradle로 설정
bootJar
: 즉, Gradle이 SpringBoot 빌드하는 명령

4. 빌드 후 조치
- 이제 push → clone 후 build 까지는 완료 되었으니, 이미 실행 중인 프로젝트를 종료하고, 해당 빌드된 .jar파일을 실행시켜야한다.
- Log text : BUILD SUCCESS
- Script : 이미 실행중인 프로젝트 종료하는 스크립트와 실행시키는 스크립트
fuser -k -n tcp 8080
nohup java -jar /var/lib/jenkins/workspace/{현재 만들고 있는 프로젝트명}/build/libs/{빌드된 .jar파일명} &

EC2 프리티어 환경에서의 문제점
- EC2 프리티어 t2.micro 에서 제공하는 RAM 크기는 1GB
- t2.micro 인스턴스에서 Jenkins를 통하여 빌드를 시키면 인스턴스가 갑자기 먹통이 된다.
- 사양을 초과한 것이다.
해결
- Swap을 통하여, RAM 용량이 부족할 때, SWAP공간을 사용하여 RAM보단 느리지만 추가적인 용량을 제공받는 과정이 필요하다.
- 루트파일에 swapfile 생성 후 권한 부여
sudo dd if=/dev/zero of=/swapfile bs=128M count=16
sudo chmod 600 /swapfile
- swap 영역 설정
sudo mkswap /swapfile
- swap 영역에 swapfile 추가 사용
sudo swapon /swapfile
- 확인
sudo swapon -s
- 부팅 시, 스왑 파일 시작할 수 있도록 vim 에디터로 수정
- 맨 밑 줄에
/swapfile swap swap defaults 0 0
추가
sudo vi /etc/fstab

6. 추가 공간 확인
sudo free

테스트
- 위에서 연결한 GitHub Repository와 연결된 프로젝트를 push

- Jenkins Project에서 확인 build 내역 확인 가능

- 해당 빌드 내역에서 Console Output에서 내역 확인


- 실행되었을 프로젝트로 접속하여 변경 점 확인

추가적으로 해결할 문제
- 현재 젠킨스 서버와 프로젝트 서버가 하나의 EC2다 보니 상당히 불안하다
- 우리 프로젝트의 application.properties는 git의 관리 대상이 아니므로, 빌드할 때 어떻게 포함시킬지 고민해봐야한다