안녕하세요. HYEN입니다.
지난 글에서는 CI/CD Pipeline에 대한 전체 Flow와 Pipeline을 구성하기 전에 필요한 설정들에 대해 다뤄보았습니다.
지난 글 바로 가기 : https://with-cloud.tistory.com/19.
이어서 이번 글에서는 본격적으로 Jenkinsfile을 사용하여 Jenkins 내에서 Job을 생성하고 테스트 하는 과정에 대해 적어보도록 하겠습니다. 😝
Contents
※ Jenkins와 ArgoCD 등 CI/CD Pipeline 구성에 필요한 모든 리소스는 사전에 배포해 두었습니다.※
4. Jenkins에서 Job 생성 (1) Push the image to ACR
4.1 Project 생성
- [+ New Item] > [Pipeline] 선택 > [Ok] 클릭
4.2 Project Configuration - General
- Build Triggers 중 [GitHub hook trigger for GITScm polling] 옵션을 선택합니다.
- 이를 통해 GitHub Repository에 코드 변경 사항이 push될 때마다 Jenkins Job이 자동으로 트리거 됩니다.
4.3 Project Configuration - Pipeline
Jenkinsfile을 작성하기에 앞서 Jenkinsfile에 대해 간략하게 알아보겠습니다.
Jenkinsfile이란?
- Jenkins Pipeline의 정의를 포함하는 텍스트파일로 Jenkinsfile을 사용하면 CI/CD Pipeline의 구성, 실행, 관리를 코드 형식으로 수행할 수 있습니다.
- 선언형 파이프라인과 스크립트형 파이프라인의 두 가지 방식으로 정의될 수 있습니다.
- 선언형 파이프라인 : 파이프라인 block으로 시작하여 stages, steps, environment 등의 지시어를 포함하는 방식으로 구조가 명확하고, 각 단계를 쉽게 이해할 수 있게 해줍니다. ← 이번 글에서 사용한 방식입니다.
- 스크립트형 파이프라인 : Groovy 기반의 구문을 사용하며, node block 내 로직을 작성하여 더 복잡한 파이프라인을 구현할 수 있습니다. 선언형 파이프라인보다 더 고급 기능과 더 많은 제어 구조를 제공하지만 작성하거나 이해하기가 보다 어려운 방식입니다.
- 선언형 파이프라인 : 파이프라인 block으로 시작하여 stages, steps, environment 등의 지시어를 포함하는 방식으로 구조가 명확하고, 각 단계를 쉽게 이해할 수 있게 해줍니다. ← 이번 글에서 사용한 방식입니다.
앞서 말씀 드렸듯이, 이번 글에서는 선언형 파이프라인을 사용하여 Jenkinsfile을 작성하였습니다.
Jenkinsfile 작성 내용은 하기와 같습니다.
pipeline {
agent any
environment {
BUILD_NUMBER = "v5"
WEB_IMAGE_NAME = "${ACR_LOGINSERVER}/{respository 명}:${BUILD_NUMBER}"
}
stages {
stage('Login to ACR') {
steps {
script {
sh "az login -i"
echo "Login to Azure Success"
sh "az acr login --name ${ACR_LOGINSERVER}"
echo "Login to Azure Container Registry Success"
}
}
}
stage('Build Docker Image') {
steps {
script {
echo "Start to Build the Image"
sh "docker build -t ${ACR_LOGINSERVER}/{respository 명}:${BUILD_NUMBER} ."
echo "Build Success"
}
}
}
stage('Push Image to ACR') {
steps {
script {
// Docker 이미지를 ACR에 푸시
echo "Push to ACR"
sh "docker push ${ACR_LOGINSERVER}/{respository 명}:${BUILD_NUMBER}"
echo "Push Success"
}
}
}
}
}
- environment block
- BUILD_NUMBER : Tag에 대한 변수로 GitHub에 변경 사항이 반영될 때마다 바꿔주어야 합니다.
- WEB_IMAGE_NAME : image를 build할 때 사용할 이름으로 이미지와 태그를 지정해 주는 변수입니다.
- 'Login to ACR' stage
- script block : Managed Identity를 사용하여 Azure에 로그인하고 ACR에 로그인 합니다.
- script block : Managed Identity를 사용하여 Azure에 로그인하고 ACR에 로그인 합니다.
- 'Build Docker Image' stage
- Github Repository에 있는 Dockerfile을 사용하여 변수로 지정한 이름:태그로 이미지를 build 합니다.
- Github Repository에 있는 Dockerfile을 사용하여 변수로 지정한 이름:태그로 이미지를 build 합니다.
- 'Push Image to ACR' stage
- build가 완료된 후 docker push 명령어를 사용하여 이미지를 ACR로 push 합니다.
Jenkinsfile 어렵지 않으시죠? 🤗🤗
다음은 Jenkins에서 Pipeline 정의하는 부분에 대해 알아보겠습니다.
- Definition의 경우 [Pipeline script from SCM]을 선택합니다.
- Repository URL에 GitHub Repository의 URL을 입력합니다.
- Credentials
- GitHub Repository가 Private Repository일 경우 [+ Add] 버튼을 클릭하여 User name과 PAT(Personal Access Token)에 대한 값이 저장된 Credentials을 생성해야 합니다.
- GitHub Repository가 Private Repository일 경우 [+ Add] 버튼을 클릭하여 User name과 PAT(Personal Access Token)에 대한 값이 저장된 Credentials을 생성해야 합니다.
- Script Path를 Jenkinsfile로 지정합니다. (default)
- GitHub Repository에서 Jenkinsfile이 있는 위치를 명시해 주어야 합니다.
- Repository 가장 상위에 존재할 경우 위와 같이 Jenkinsfile이라고 명시해 주면 되고 특정 directory 내 존재한다면 directory명/Jenkins로 명시해 주면 됩니다.
4.3 GitHub 코드 수정 후 Job이 자동으로 trigger 되는지 확인
Local에서 코드를 수정한 후 GitHub에 변경 사항을 push 해 보았습니다.
이후 Jenkins에서 Build가 자동으로 Trigger 되는 것을 확인할 수 있습니다. (하기 이미지 참조)
이렇게 첫 번째 job을 생성해 보았는데요.
첫 번째 job의 flow를 간단하게 정리하고 넘어가 보도록 하겠습니다.
➡️ 코드를 수정한 후 GitHub에 변경 사항을 push하면 Jenkins는 GitHub webhook에 의해 변경 사항이 발생했다는 것을 감지합니다. 그 후, Jenkins는 자동으로 job을 실행하여 ACR에 변경 사항이 적용된 이미지를 push합니다.
5. Jenkins에서 Job 생성 (2) Update the manifest file
5.1 Project 생성
- [+ New Item] > [Pipeline] 선택 > [Ok] 클릭
5.2 Project Configuration - General
두 번째 job은 첫 번째 job이 성공적으로 완료된 이후 자동으로 trigger 되어야 합니다.
이 부분은 첫 번재 job에서 추후 구성할 예정이기 때문에 해당 job에서는 별도로 구성해 주어야 할 것이 없습니다. 🎶🎶
5.3 Project Configuration - Pipeline
첫 번째 job과 마찬가지로 두 번째 job에서 사용될 Jenkinsfile도 선언형 파이프라인 방식을 사용하였습니다.
Jenkinsfile 작성 내용은 하기와 같습니다.
pipeline {
agent any
environment {
IMAGE_TAG = 'initial'
}
stages {
stage('Clone repository') {
steps {
checkout scm
}
}
stage('Update deploy.yaml') {
steps {
script {
IMAGE_TAG=sh(script: "az acr repository show-tags --name {acr명} --repository {repository명} --orderby time_desc --top 1 --output tsv", returnStdout: true).trim()
echo "Image Tag: ${IMAGE_TAG}"
sh "sed -i 's|image: .*|image: {acr server 주소}/{respository}:${IMAGE_TAG}|' deploy.yaml"
}
}
}
stage('Commit and Push') {
steps {
script {
withCredentials([string(credentialsId: 'sundls', variable: 'GIT_CREDENTIALS_ID')]){
sh 'git config user.email "user email 입력"'
sh 'git config user.name "user name 입력"'
sh 'git add .'
sh 'git commit -m "Update image tag in deploy.yaml"'
sh 'git push https://${GIT_CREDENTIALS_ID}@github.com/{user name 입력}/Manifest.git HEAD:main'
}
}
}
}
}
}
- environment block
- IMAGE_TAG의 경우, 초기 값을 지정해 줍니다.
- 이후 하기 ‘Update deploy.yaml’ stage에서 변수 값을 update 하게 됩니다.
- IMAGE_TAG의 경우, 초기 값을 지정해 줍니다.
- 'Clone repository' stage
- Jenkins Project 내 Pipeline 정의 탭에서 설정할 SCM(이 경우 GitHub Repository)으로부터 소스 코드를 체크아웃하는 단계를 의미합니다.
- 해당 pipeline은 project 내 정의된 GitHub Repository를 바라보고 있습니다.
- Jenkins Project 내 Pipeline 정의 탭에서 설정할 SCM(이 경우 GitHub Repository)으로부터 소스 코드를 체크아웃하는 단계를 의미합니다.
- 'Update deploy.yaml' stage
- IMAGE_TAG라는 변수에 ACR에 push된 image 중 가장 최신 버전인 값이 할당되도록 합니다.
- orderby라는 매개변수의 값을 time_desc으로 하여 가장 최근에 push된 image의 값부터 출력되도록 정렬합니다.
- top이라는 매개변수의 값을 1로 하여 정렬한 값들 중 가장 첫 번째 값만 출력되도록 합니다.
- returnStdout는 Jenkins 파이프라인 스크립트에서 사용되는 특정 옵션입니다. 일반적으로 script block 내에서 쉘 명령어를 실행할 경우 명령어의 출력값은 문자열 형태로 터미널 또는 콘솔에 직접 출력됩니다. 하지만 returnStdout:true 옵션을 사용하면 Jenkins가 이 출력을 캡처하여 Jenkins script 내의 변수에 저장하게 됩니다.
- trim() 함수를 통해 문자열의 앞뒤 공백을 제거합니다. (혹시 모를 오인식을 방지하기 위함입니다.)
- orderby라는 매개변수의 값을 time_desc으로 하여 가장 최근에 push된 image의 값부터 출력되도록 정렬합니다.
- IMAGE_TAG라는 변수에 ACR에 push된 image 중 가장 최신 버전인 값이 할당되도록 합니다.
- 'Commit and Push' stage
- withCredentials
- Jenkins Credentials에 정의한 GitHub PAT와 관련된 값을 사용하기 위한 선언을 하는 field입니다.
- credentialsId 값에 Credentials ID 값을 입력하고 variable 값에는 하기 명령어에서 사용할 변수 값을 입력합니다. ← Credentials 값이 variable에 선언한 값에 저장됩니다.
- Jenkins Credentials에 정의한 GitHub PAT와 관련된 값을 사용하기 위한 선언을 하는 field입니다.
- git 명령어
- git 명령어들을 통해 변경된 값을 GitHub repository에 push 합니다.
- withCredentials
다음은 Jenkins에서 Pipeline 정의하는 부분에 대해 알아보겠습니다.
첫 번째 job과 동일한 방식으로 정의해 주시면 됩니다!
5.4 Job이 trigger 되었을 때 이미지 값이 자동으로 변경되는지 확인
- 현재 이미지 값을 확인합니다. (tag가 v5 임을 확인할 수 있습니다.)
- Pipeline Project에서 [Build Now]를 클릭합니다.
- Job이 정상적으로 종료된 것을 Jenkins에서 확인할 수 있습니다.
- Github에서 버전 값이 변경되었는지 확인합니다. (tag 값이 v5에서 v6으로 변경된 것을 확인할 수 있습니다.)
이렇게 Jenkins에서 job을 2개 생성하고 각각의 job들이 목적에 맞게 잘 돌아가는지 확인해 보았습니다.
아직까지는 두 개의 job을 연결하는 부분을 추가해 주지 않았기 때문에 두 개의 job이 연결되어 돌아가지는 않는다는 점 다시 한번 말씀드리며, 이번 글을 마무리하도록 하겠습니다.
job들이 시나리오 대로 잘 돌아가는 것을 확인했으니
다음 글에서는 ① 두 번째 job에 의해 update 될 deploy.yaml file이 있는 GitHub Repository와 AKS 간 sync를 위해 ArgoCD에서 어떤 구성을 해 주어야 하는지 알아보고 ② CI/CD Pipeline 전 과정을 자동화 해 보도록 하겠습니다. 😜
'TOPIC > DevOps' 카테고리의 다른 글
Jenkins - GitHub Private하게 연결하기 (2) (0) | 2024.04.10 |
---|---|
Jenkins - GitHub Private하게 연결하기 (1) (0) | 2024.04.10 |
Windows에 Jenkins 설치하기 (0) | 2024.04.02 |
Jenkins, ArgoCD로 CI/CD Pipeline 구성하기 (3) (2) | 2024.02.05 |
Jenkins, ArgoCD로 CI/CD Pipeline 구성하기 (1) (0) | 2024.01.31 |