[Jenkins] - spring boot project pipeline 생성하기
2024. 11. 11. 10:05ㆍ현대 오토에버 SW 스쿨 - 클라우드/버전관리_Jenkins
SMALL
1. Spring Boot Project Pipeline
Spring Boot Project Pipeline 를 생성하고 Git Hub 와 연동
1) check out : SCM 으로부터 코드를 내려받는 동작
- git remote 사이트로부터 내려받을 때
git url: 'URL', branch: '브랜치이름'
- New Item 을 선택해서 이름을 결정하고 Pipeline 을 선택
# script 만 작성
pipeline{
agent any
stages{
stage("checkout"){
steps{
git url: "https://github.com/itggangpae/JenkinsPipeline.git", branch: "master"
}
}
}
}
2) 코드를 작성하고 로컬에서 단위 테스트
- 단위 테스트를 하기 위해서 build.gradle 파일의 dependenciese 항목
-> JUnit 라이브러리의 의존성을 추가하고 Rebuild 를 수행해서 의존성 라이브러리 다운로드
// https://mvnrepository.com/artifact/junit/junit
testImplementation 'junit:junit:4.13.2'
- 테스트 클래스 생성: src/test 디렉터리에 생성 (Calculator Test)
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class CalculatorTest {
private Calculator calculator = new Calculator();
@Test
public void testSum(){
assertEquals(Integer.valueOf(5), calculator.sum(2, 3));
}
}
- 테스트 수행 : ./gradlew test --> 현재 상태는 error
- Calculator 클래스 구현
import org.springframework.stereotype.Service;
@Service
public class Calculator {
public Integer sum(Integer a, Integer b){
return a+b;
}
}
- 테스트 수행 -> 테스트 성공
- Controller 클래스 생성 ( CalculatorController)
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class CalculatorController {
private final Calculator calculator;
@RequestMapping("/")
String sum(@RequestParam("a") Integer a, @RequestParam("b") Integer b) {
return String.valueOf(calculator.sum(a, b));
}
}
- 실행 (./gradlew bootRun) 후 브라우저에서 확인
http://localhost:8080/?a=10&b=7 - 코드 push
3) Jenkins 에서 컴파일과 테스트
- script 에 3개의 stage 를 추가하고 빌드를 수행
stage("permission"){
steps{
sh "chmod +x ./gradlew"
}
}
stage("compile"){
steps{
sh "./gradlew compileJava"
}
}
stage("test"){
steps{
sh "./gradlew test"
}
}
4) Code Coverage
- 코드 전체를 대상으로 테스트를 진행하고 검증이 완료된 부분을 식별하는 것
- 코드를 업데이트 할 때 필수 항목
- 로컬에서 코드 커버리지 수행
- 코드 커버리지 도구를 build.gradle 의 plugins 항목에 추가
- 빌드 다시 수행 (id 'jacoco')
- 코드 커버리지 기준을 build.gradle 에 설정 후 빌드를 다시 수행
jacocoTestCoverageVerification{
violationRules{
rule{
limit{
minimum = 0.2
}
}
}
}
- 수행 및 보고서 발행 -> 코드 push
./gradlew test jacocoTestCoverageVerification
./gradlew test jacocoTestReport
- 파이프라인에 stage 로 추가
stage("test coverage"){
steps{
sh "./gradlew test jacocoTestCoverageVerification"
sh "./gradlew test jacocoTestReport"
}
}
4) 정적 코드 분석
- 코드의 품질을 검사하는 과정
- 코드를 읽기 쉽고 유지보수하기 좋도록 만드는 것을 보증
- checkstyle 이나 findbug, PMD 등을 주로 이용
- checkstyle 활용
- 문서 : https://checkstyle.sourceforge.io/config.html
- build.gradle 파일의 plugins 에 checkstyle 추가
id 'checkstyle' - naver 의 checkstyle 환경 설정 샘플
https://github.com/naver/hackday-conventions-java/blob/master/rule-config/naver-checkstyle-rules.xml - 환경설정 : config/checkstyle/checkstyle.xml 파일로 설정
<?xml version="1.0" ?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="TreeMaker">
<module name="ConstantName" />
</module>
</module>
# 로컬에서 수행
./gradlew checkstyleMain
2. trigger 와 알림
1) 트리거
- 빌드를 자동으로 시작하는 동작을 pipeline trigger
- 트리커의 유형
- 외부 트리거
- 폴링 SCM 트리거
- 스케쥴 빌드 트리거
- 외부 트리거
- 노티파이어가 호출되면 jenkins 가 빌드를 시작하는 방식
- 노티파이어의 역할을 할 수 있는 것은 다른 파이프라인 빌드나 SCM 시스템의 원격 script
- 깃헙 - 트리거 > jenkins
- github 을 이용해서 jenkins 에 trigger
- jenkins 에 github 플러그인을 설치
- jenkins 용 비밀키를 생성
- github webhook 을 설정하고 jenkins 의 주소와 키를 저장
- 폴링 SCM 트리거
- jenkins 가 주기적으로 SCM 을 호출하고 repository 에 push 가 발생했는지를 체크
- 변경 시 빌드를 다시 진행
- jenkins 가 SCM 에 접속할 수 없는 방화벽 네트워크 안에 있는 경우 유용함
- 빌드 시간이 길고 커밋이 자주 발생해서 서버에 과부하가 초래되는 겨웅
- Jenkinsfile 을 이용한 파이프라인으로 변경
- 프로젝트에 jenkinsfile 을 생성하고 이전에 수행했던 작업을 작성
pipeline{ agent any stages{ stage("permission"){ steps{ sh "chmod +x ./gradlew" } } stage("compile"){ steps{ sh "./gradlew compileJava" } } stage("test"){ steps{ sh "./gradlew test" } } stage("test coverage"){ steps{ sh "./gradlew test jacocoTestCoverageVerification" sh "./gradlew test jacocoTestReport" } } } }
- Jenkins 에 접속해서 SCM 에서 GIT -> URL 설정
- 빌드해서 빌드가 제대로 수행되는지 확인
- Polling SCM 설정
- 구성에서 PollSCM 체크
- 스케쥴 입력 - 분 시간 일 월 요일
- 33 * * * * 을 설정하면 33분에 수행
- commit 이 동일하지 않을 때만 수행
- Build periodically 옵션
- 설정 방법 - polling SCM 과 동일
- 변경된 내용이 없어도 무조건 Build 를 다시 수행
- commit pipeline 에서는 거의 사용하지 않고 밤에 실행되는 복잡한 통합 테스트에서 사용
- 프로젝트에 jenkinsfile 을 생성하고 이전에 수행했던 작업을 작성
2) push 가 발생했을 때 build
- git hub 에서 token 발급 - jenkins 에 등록해서 연동
- jenkins 와 Git hub 연결
- Dashboard 화면에서 Jenkins 관리를 클릭
- System 을 클릭하고 화면을 하단으로 스크롤
-> Git Hub 항목 -> Add GitHub Server -> 이름 설정 -> Credential -> Add > Jenkins - Domail 은 두고 Kind 를 Secret test 로 변경 후 ID 에 토큰 이름 지정
-> Secret 에 토큰 값 설정 -> Add -> Test Connection 수행 - Jenkins Item 에서 트리거로 Github hook trigger for GITScm polling 을 선택
3) 트리커 생성 옵션
- Build periodically : 주기적으로 무조건 Build
- Github hook trigger for GITScm polling: Github 의 브랜치에 push 발생 시 수행 -> Credential 설정
- poll SCM: 주기적으로 빌드, 변경 내역이 있을 때만 빌드 다시 수행
3. 알림
1) 개요
- jenkins 에서는 다양한 방식으로 빌드 상태를 알려줄 수 있음
- 기본은 email 이지만 plugin 설치 시 다른 방식으로 알림을 보낼 수 있음
2) email 을 전송
- SMTP 서버 확보 후 설정에 추가
- script 에서 mail to 명령으로 전송
4. 팀 단위 개발 전략
1) 개발 워크플로우
- 트렁크 기반 워크플로우
- 트렁크 또는 마스터라고 불리는 하나의 중앙 레포지토리에 프로젝트의 모든 변경 사항이 저장되는 구조
- 모든 팀원들은 중앙 레포지토리를 복제해서 자신의 컴퓨터에 로컬 복사본을 만들어서 사용
- 변경된 내용은 중앙 레포지토리로 직접 커밋
- 브랜치 워크플로우
- 코드를 각기 다른 브랜치에 저장
- 개발자가 신규 기능을 개발하는 경우 :: 트렁크에서 분기된 전용 브랜치 생성 -> 해당 브랜치에 기능 구현과 관련된 모든 변경 사항을 저장
- 메인 코드를 건드리지 않고 기능 개발 가능
- 포크 워크플로우
- 오픈 소스 커뮤니티에서 사용
- 각 개발자는 각자의 서버 레포지토리를 갖는 구조
5. 자동 인수 테스트
1) 인수 테스트
- 요구사항대로 기능이 구현되었는지 확인하는 과정
- 테스트 :: 전체 시스템을 사용자 관점에서 시험하는 블랙박스 테스트 포함
- 인스 테스트 자동화가 어려운 이유
- 사용자 참여 : 테스트를 만들 때 사용자와 함께 작성
- 의존성 통합
- 시스템이 전체적으로 잘 동작하는지를 확인해야 함
- 따라서 테스트할 애플리케이션은 모든 의존성을 포함해서 실행해야 함
- 스테이징 환경
- 기능 및 비기능 테스트를 확실히 수행하고자 하면 스테이징 환경이 프로덕션 환경과 일치해야 함
- 애플리케이션의 동일성
- 애플리케이션은 한 번만 빌드해야 하고 프로덕션에서도 동일한 바이너리를 사용해야 함
- 도커 이미지를 만들어서 배포
- 실행 환경이 달라서 발생할 수 있는 문제를 제거해야 하기 때문
- 릴리스 준비
- 애플리케이션이 인수 테스트를 통과하면 사용자에게 바로 제공할 수 있도록 준비 되어야 함
2) 도커 레지스트리
- 도커 레지스트리는 도커 이미지 저장소로 도커 이미지를 push 하거나 pull 할 수 있는 서버 애플리케이션
- 도커 허브는 클라우드 기반의 공식 도커 레지스트리
- 소프트웨어 레포지토리 or 아티팩트 레포지토리
:: 애플리케이션을 개발하는 곳에서는 별도의 서버를 만들어서 소프트웨어 패키지를 저장하고 불러오거나 검색할 수 있도록 함 - 애플리케이션을 배포하는 곳에서 별도의 레포지토리를 만드는 이유
- 파일 크기
- 버전 관리
- 리비전 매핑 : 산출물과 바이너리가 정확히 매핑
- 패키징 : 산출물은 압축된 형식으로 저장
- 접근 제어 : 소스 코드에 직접 접근할 수 있는 사용자와 바이너리에 접근할 수 있는 사용자를 구분하는 것 가능
- 도커 레지스트리 사용
- 클라우드 방식의 도커 레지스트리
- Docker Hub
- 대체 서비스
AWS 의 ECR
GCP 의 Artifact Registry
Azure 의 Container Registry
Gitlab 의 Container Registry
- 대체 서비스
- 자체 호스팅 방식의 도커 레지스트리
- 사내 네트워크가 아닌 외부에 소프트웨어를 보관하는 것을 금지하는 경우 사용
3) 도커 레지스트리 구축
- 도커 레지스트리 애플리케이션을 설치
# 레지스트리 시작
docker run -d -p 5000:5000 --restart=always --name registry registry
- 도메인 인증서 추가
- CA( 인증 기관) 에서 서명한 인증서를 사용하는 것을 권장
- 위의 경우가 어렵다면 자체 서명 인증서 발행
https://docs.docker.com/registry/insecure/#using-self-signed-certificates
Registry
The Docker Hub registry implementation
docs.docker.com
- 인증서를 발급받은 경우 registry 실행
인증서 파일 (domain.crt 와 domain.key 파일) 을 컨테이너의 certs 디렉토리로 이동한 후 수행
docker run -d -p 5000:5000 --restart=always --name registry -v ‘pwd’/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key registry
- 접속 제한 추가
4) Spring Boot 프로젝트를 도커 이미지로 만들기
- 프로젝트를 빌드 : 실행 가능한 파일을 생성
./gradlew clean build
# 빌드에 성공을 하면 build/libs 에 실행 파일이
# 프로젝트이름-0.0.1-SNAPSHOT.jar 라는 이름으로 만들어짐
- Dockerfile 을 루트 디렉터리에 생성하고 작성
FROM bellsoft/liberica-openjdk-alpine:17
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
- Gradle Build 를 수행 : ./gradlew clean build
- Docker Build 를 수행 : docker build -t jenkinspipeline .
- 이미지 확인 : docker images
- Jenkinsfile 에 stage 추가
stage("Gradle Build"){
steps{
sh "./gradlew clean build"
}
}
stage("Docker Build"){
steps{
sh "docker build -t jenkinspipeline ."
}
}
5) 이미지를 레지스트리로 푸시
- 이미지를 레지스트리로 푸시를 하고자 하는 경우
- 레지스트리이름/이미지이름:태그 형태로 만들어야 함
- 로그인을 요구하는 레지스트리라면 Credential 을 추가
- 직접 구축한 레지스트리를 사용하고자 하는 경우 daemon.json 파일에 레지스트리를 추가
{
"insecure-registries":["54.180.146.200:5000"],
"debug": true,
"experimental": false
}
반응형
LIST
'현대 오토에버 SW 스쿨 - 클라우드 > 버전관리_Jenkins' 카테고리의 다른 글
[argoCD] - AWS 의 ECR 과 ECS 를 이용한 CI/CD 구현 (0) | 2024.11.18 |
---|---|
[Jenkins] - Jenkins 를 이용한 CI/CD (0) | 2024.11.12 |
[Jenkins] - 프로젝트와 jenkins 연결 (2) | 2024.11.11 |
[Jenkins] - jenkins 사용 실습 - pipeline 구축 (3) | 2024.11.08 |
[Jenkins] - Jenkins 기본 개념 (1) | 2024.11.08 |