Infra & DevOps/CICD

[Jenkins]Jenkins 설치 및 실습

용감한 개복치 2024. 4. 19. 03:44

Jenkins

개념

- 지속적 통합 & 배포를 위한 워크플로우 제어에 사용되는 툴

- 자바 기반의 오픈소스 -> 자바와 친화성이 높음

- 아파치 톰캣처럼 서블릿 컨테이너 내부에서 실행되는 서버 시스템

- 파이프라인이라고 부르는 스크립트 작성 -> 각 빌드 단계마다 세부적으로 젠킨스의 태스크 정의 가능

- 다양한 플러그인 연동 제공

  • Build Plugins : Maven, Ant, Gradle …
  • VCS Plugins : Git, SVN …
  • Languages Plugins : Java, Python, Node.js …

- github action 과 함께 CI/CD 툴로 많이 거론 됨

- 간단한 비교 요약

출처 : https://wookiist.dev/155

- 워크플로우 예시

  1. 최신 코드 가져오기 : 개발을 위해 중앙 코드 리포지터리에서 로컬 시스템으로 애플리케이션의 최신 코드를 가져옴
  2. 단위 테스트 구현과 실행 : 코드 작성 전 단위 테스트 케이스를 먼저 작성
  3. 코드 개발 : 실패한 테스트 케이스를 성공으로 바꾸면서 코드 개발
  4. 단위 테스트 케이스 재실행 : 단위 테스트 케이스 실행 시 통과(성공!)
  5. 코드 푸시와 병합 : 개발 소스 코드를 중앙 리포지터리로 푸시하고, 코드 병합
  6. 코드 병합 후 컴파일 : 변경 함수 코드가 병함되면 전체 애플리케이션이 컴파일된다
  7. 병합된 코드에서 테스트 실행 : 개별 테스트뿐만 아니라 전체 통합 테스트를 실행하여 문제 없는지 확인
  8. 아티팩트 배포 : 애플리케이션을 빌드하고, 애플리케이션 서버의 프로덕션 환경에 배포
  9. 배포 애플리케이션의 E-E 테스트 실행 : 셀레늄 Selenium과 같은 User Interface 자동화 도구를 통해 애플리케이션의 전체 워크플로가 정상 동작하는지 확인하는 종단간 End-to-End 테스트를 실행.

 

실습

설치 및 설정

자바 설치 및 환경 변수 설정

# 실습 편리를 위해서 root 계정 전환
sudo su -

# Add required dependencies for the jenkins package
# https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/amazon-linux-install.html
sudo yum install fontconfig java-17-amazon-corretto -y
java -version
alternatives --display java
JAVA_HOME=/usr/lib/jvm/java-17-amazon-corretto.x86_64
echo $JAVA_HOME

 

젠킨스 설치

# 젠킨스 설치
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum upgrade
sudo yum install jenkins -y
sudo systemctl daemon-reload
sudo systemctl enable jenkins && sudo systemctl start jenkins   # 다소 시간 걸림
sudo systemctl status jenkins

# 초기 암호 확인
sudo systemctl status jenkins
cat /var/lib/jenkins/secrets/initialAdminPassword

# 접속 주소 확인 
curl -s ipinfo.io/ip | awk '{ print "Jenkins = http://"$1":8080" }'

 

설치 완료 되면 초창기 로그인 화면이 뜸

아까 cat 이하로 확인했던 암호로 입장

 

install

 

유저설정

 

주소 같은지 확인

 

 

 

대시보드 설명

구성에 대해 간략히 설명

 

item

- 작업 최소단위, job

- 종류

  • 프로젝트 : 가장 기본적인 job 세팅
  • 파이프라인 : 스크립트로 미리 정의된 템플릿 프로세스들로 job 실행

사람

- 계정 관련한 설정

 

젠킨스 관리

- 전역적인 설정

- tool 등을 설정 할 수 있음

 

실습

tool 설정 : 자바 JDK 를 사용하도록 path 지정 > save

 

item 생성 > 프로젝트

 

빌드 설정

 

빌드

 

확인

 

빌드에 변경 사항 추가하기 > 지금 빌드

 

변경 된 부분 확인

 

젠킨스 설치된 ec2 에서 프로젝트 위치 확인

#
find / -name First-Project

# 프로젝트(job, item) 별 작업 공간 확인
tree /var/lib/jenkins/workspace/First-Project

 

Jenkins with Docker

젠킨스에서 도커를 사용하는 방법

 

사전 준비

젠킨스 유저로 도커 사용하도록 설정 > 젠킨스 유저 전

# jenkins 유저로 docker 사용 가능하게 설정
grep -i jenkins /etc/passwd
usermod -s /bin/bash jenkins
grep -i jenkins /etc/passwd

# jenkins 유저 전환
su - jenkins
whoami
pwd
docker info
exit

 

su - jenkins 로 jenkins 사용자 로그인 후 기본적인 명렁어 확인했으나 docker 정보의 경우 권한 에러 발생

-> 권한 줘야함(666은 모든 사용자에게 읽기쓰기 오픈함 주의)

chmod 666 /var/run/docker.sock
usermod -aG docker jenkins

# Jeknins 유저로 확인
su - jenkins
docker info

 

# Dockerhub로 로그인 하기
docker login
Username: <자신의 계정명>
Password: <자신의 암호>

# myweb:v2.0.0 컨테이너 이미지 생성을 위한 Dockerfile 준비
# 실습을 위한 디렉터리 생성 및 이동
mkdir -p ~/myweb2 && cd ~/myweb2

# Dockerfile 파일 생성
vi Dockerfile
FROM ubuntu:20.04
ENV TZ=Asia/Seoul VERSION=2.0.0 NICK=peachdo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
    sed -i 's/archive.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list && \
    apt-get update && apt-get install -y apache2 figlet && \
    echo "$NICK Web Server $VERSION<br>" > /var/www/html/index.html && \
    echo "<pre>" >> /var/www/html/index.html && \
    figlet AEWS Study >> /var/www/html/index.html && \
    echo "</pre>" >> /var/www/html/index.html
EXPOSE 80
CMD ["usr/sbin/apache2ctl", "-DFOREGROUND"]

# 모니터링
watch -d 'docker images; echo; docker ps'

-----------
# (참고) 이미지 빌드
docker build -t myweb:v2.0.0 -f /var/lib/jenkins/myweb2/Dockerfile

# (참고) 컨테이너 실행
docker run -d -p 80:80 --rm --name myweb myweb:v2.0.0

 

젠킨스에서 Docker-Project 생성 & 빌드 스텝 설정

# build step
cd /var/lib/jenkins/myweb2
docker build -t myweb:v2.0.0 .

# add build step
docker run -d -p 80:80 --rm --name myweb myweb:v2.0.0

 

빌드 > 콘솔 출력

터미널에서 도커 이미지 빌드 할 때 봤던 로그들 확인

 

터미널에서 docker images 확인 & 이미지가 실행되는지 확인

 

Github 저장소 연결

실습용 레포지토리 포크

https://github.com/gasida/aews-cicd

 

GitHub - gasida/aews-cicd: cloudneta aws workshop study

cloudneta aws workshop study. Contribute to gasida/aews-cicd development by creating an account on GitHub.

github.com

 

프로젝트 생성

 

파라미터 string 추가 > VERSION & NICK

 

소스코드 관리(Source Code Management) 설정

 

additional behaviours 에서 sparse checkout path 를 1로 설정

 

build trigger 에서 poll scm 에 schedule '*****' 추가

+) poll scm

- 웹훅을 사용하지 않아도 빌드를 유발 시키기 위한 옵션

- 형상관리 서버를 주기적으로 감시하여 변경된 사항이 존재할때 빌드를 수행하는 설정

 

build step 설정

cd /var/lib/jenkins/myweb2
rm -rf Dockerfile
wget https://raw.githubusercontent.com/$NICK/aews-cicd/main/1/Dockerfile

docker build -t myweb:$VERSION .
docker run -d -p 80:80 --rm --name myweb myweb:$VERSION

 

Github 레포에서 1/Dockerfile 수정 후 커밋 > 트리거 발동

 

젠킨스에서 확인

노란 부분에서 어떤 커밋을 반영해서 돌아갔는지 보임

 

실패한 부분

Dockerfile 경로를 못찾음 -> 동일하게 Execute shell 수정

 

파이프라인

이론

위에 실습이 프로젝트에 관한 것이었다면, 지금 항목은 파이프라인에 관한 것

출처 : 스터디 자료

- 파이프라인 장점

  • 코드 : 애플리케이션 CI/CD 프로세스를 코드 형식으로 작성할 수 있고, 해당 코드를 중앙 리포지터리에 저장하여 팀원과 공유 및 작업 가능
  • 내구성 : 젠킨스 서비스가 의도적으로 또는 우발적으로 재시작되더라도 문제없이 유지됨
  • 일시 중지 가능 : 파이프라인을 실행하는 도중 사람의 승인이나 입력을 기다리기 위해 중단하거나 기다리는 것이 가능
  • 다양성 : 분기나 반복, 병렬 처리와 같은 다양한 CI/CD 요구 사항을 지원

-  파이프라인 용어

  • 파이프라인 : 전체 빌드 프로세스를 정의하는 코드.
  • node : 파이프라인을 실행하는 시스템.
  • stage : 특정 단계에서 수행되는 작업들의 정의.
  • step : 파이프라인의 특정 단계에서 수행되는 단일 작업을 의미

- 파이프라인 3가지 구성 형태

  • Pipeline script : 일반적인 방식으로 Jenkins 파이프라인을 생성하여 Shell Script를 직접 생성하여 빌드하는 방식
  • Pipeline script from SCM : 사전 작성한 JenkinsFile을 형상관리 저장소에 보관하고, 빌드 시작 시 파이프라인 프로젝트에서 호출 실행하는 방식
  • Blue Ocean : 젠킨스 ui 로 관리하면 자동으로 jenkinsfile이 생성, 실행

- 구문 형태

  • 선언형 : 쉽게 작성 가능, 최근 문법이고 젠킨스에서 권장하는 방법, step 필수!

예제)

pipeline {
    agent any     # Execute this Pipeline or any of its stages, on any available agent.
    stages {
        stage('Build') {   # Defines the "Build" stage.
            steps {
                //         # Perform some steps related to the "Build" stage.
            }
        }
        stage('Test') { 
            steps {
                // 
            }
        }
        stage('Deploy') { 
            steps {
                // 
            }
        }
    }
}
  • 스크립트형 : 커스텀 작업에 용이, 복잡하여 난이도가 높음, step은 필수 아님

예제 )

node {          # 	Execute this Pipeline or any of its stages, on any available agent.
    stage('Build') {    # Defines the "Build" stage. stage blocks are optional in Scripted Pipeline syntax. However, implementing stage blocks in a Scripted Pipeline provides clearer visualization of each stage's subset of tasks/steps in the Jenkins UI.
        //              # Perform some steps related to the "Build" stage.
    }
    stage('Test') { 
        // 
    }
    stage('Deploy') { 
        // 
    }
}

 

실습 : 파이프라인 w. script

파이프라인 아이템 생성

 

스크립트로 정의

pipeline {
    agent any

    stages {
        stage('정보 확인') {
            steps {
                echo 'Hello World'
                sh 'java -version'
            }
        }
        stage('가라 배포') {
            steps {
                echo "Deployed successfully!";
            }
        }
    }
}

 

스크립트 자리에 내용 바꿔보기 > echo 동작 확인

pipeline {
    agent any
    environment { 
        STUDYNAME = 'AEWS'
    }
    stages {
        stage('연습') {
            environment { 
                mykey = 'abcd'
            }
            steps {
                echo "${STUDYNAME}";
                sh 'echo ${mykey}'
            }
        }
    }
}

 

maven 수정 테스트

pipeline {
    agent any
    tools {
        maven 'maven_3.8.7' 
    }
    stages {
        stage('Example') {
            steps {
                sh 'mvn --version'
            }
        }
    }
}

 

ui 상에선 아래 부분 수정하는 것

 

step 항목에 넣을 수 있도록 도와주는 문법 변환기

 

실습 : 파이프라인 SCM

파이프라인 아이템 생성

 

scm 으로 설정

 

실습 : secret text

관리 → Credentials → + Add Credentials → Secret text : Usename(root), Password(qwe123), ID(vmsshpw)

 

실습 : secret files

kube config 파일을 자신의 PC에 복사 → Jenkins Web에 Secret files 등록

scp root@<작업용EC2_공인IP>:/root/.kube/config .

# 아래 확인을 위해 모니터링
watch -d kubectl get pod

 

pipeline {
    agent any
    environment {
        MY_KUBECONFIG = credentials('k8sconfig')
    }

    stages {
        stage('remote k8s api') {
            steps {
                sh("kubectl --kubeconfig $MY_KUBECONFIG get pods -A")
                sh("kubectl --kubeconfig $MY_KUBECONFIG run nginx --image nginx --port=80")
            }
        }
    }
}

 

Jenkins → Credentials → Add → Secret file : File(업로드), ID(k8sconfig)

 

Jenkins with k8s

사전 준비 : 젠킨스에서 k8s 를 사용 할 수 있도록 설정

# jenkins 사용자에서 아래 작업 진행
whoami
mkdir ~/.kube

 

# root 계정에서 아래 복사 실행
cp ~/.kube/config /var/lib/jenkins/.kube/config
chown jenkins:jenkins /var/lib/jenkins/.kube/config

 

# jenkins 사용자에서 aws eks 사용(sts 호출 등)을 위한 자격증명 설정
aws configure
AWS Access Key ID [None]: ###
AWS Secret Access Key [None]: ###
Default region name [None]: ap-northeast-2

# jenkins 사용자에서 kubectl 명령어 사용 확인
kubectl get pods -A

 

파이프라인으로 디플로이먼트/서비스 배포

yaml 파일 수정 : 도커 이미지 수정 작업

 

k8s-1 아이템 생성

 

파이프라인 스크립트

pipeline {
    agent any

    tools {
        jdk 'jdk-17'
    }

    environment {
        DOCKERHUB_USERNAME = 'gasida'
        GITHUB_URL = 'https://github.com/<본인 깃헙id>/aews-cicd.git'
        // deployment-svc.yaml -> image: <도커 허브id>/myweb:v1.0.0        
        DIR_NUM = '3'
    }

    stages {
        stage('Container Build') {
            steps {	
                // 릴리즈파일 체크아웃
                checkout scmGit(branches: [[name: '*/main']], 
                    extensions: [[$class: 'SparseCheckoutPaths', 
                    sparseCheckoutPaths: [[path: "/${DIR_NUM}"]]]], 
                    userRemoteConfigs: [[url: "${GITHUB_URL}"]])

                // 컨테이너 빌드 및 업로드
                sh "docker build -t ${DOCKERHUB_USERNAME}/myweb:v1.0.0 ./${DIR_NUM}"
                sh "docker push ${DOCKERHUB_USERNAME}/myweb:v1.0.0"
            }
        }

        stage('K8S Deploy') {
            steps {
                sh "kubectl apply -f ./${DIR_NUM}/deploy/deployment-svc.yaml"
            }
        }
    }
}

 

확인

 

접속 테스트를 위한 파드 생성

# 배포
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
  name: netpod
  labels:
    app: pod
spec:
  containers:
  - name: netshoot-pod
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
EOF

 

배포 및 확인

#
kubectl exec -it netpod -- curl myweb:8080
kubectl exec -it netpod -- curl myweb:8080 | grep Web
while true; do kubectl exec -it netpod -- curl myweb:8080 | grep Web; echo; done

# 작업공간 확인
tree /var/lib/jenkins/workspace/k8s-1
cat /var/lib/jenkins/workspace/k8s-1/Dockerfile

 


참고 자료

https://wookiist.dev/155

 

[DevOps/번역글] Github Actions냐 Jenkins냐! 올바른 선택을 해봅시다

시작하기에 앞서, 본 포스트는 "Github Actions or Jenkins? Making the Right Choice for You" 를 읽고 한국어로 정리하기 위해 쓴 번역 글입니다. 오역이 있거나 미숙한 번역이 있을 수 있습니다. 많은 지적질 부

wookiist.dev

https://velog.io/@mirrorkyh/11%EC%9B%94-4%EC%A3%BC%EC%B0%A8-jenkins-Poll-scm-%EA%B8%B0%EB%8A%A5-%EC%84%A4%EC%A0%95

 

[11월 4주차] jenkins Poll scm 기능 설정

• 사용 이유• 유사기능 Build periodically• 크론 작업 형식• Poll SCM사용 이유빌드 트리거를 주로 웹훅을 사용하지만특정 상황에는 웹훅을 사용하지 못하는 경우가 발생할 수 있기 때문에웹훅을

velog.io

 

'Infra & DevOps > CICD' 카테고리의 다른 글

[ArgoCD] ArgoCD 설치 및 실습  (0) 2024.04.20