이제 CI/CD 마지막 chapter 이다.
이번 chapter에서는 Jenkins와 ArgoCD 연동하여 CI/CD를 완성시킬 것이다.
앞선 지시대로 이행하며 잘 따라왔다면, 이번 chapter 에서는 특별히 할 게 없다.
각 모듈(Jenkinsfile, GitOps, ArgoCD) 을 잘 연결해서 올바르게 동작하는 지 확인할 것이다.
아래의 CI/CD flow를 참고하면 Jenkinsfile을 이해하는데 도움이 될 것이다.
1. Jenkinsfile에 stage 추가
1) Jenkinsfile 작성
import java.text.SimpleDateFormat;
import java.util.Date;
def microServiceName = "ezapprovalg"
def packageName = "ezApprovalG"
def imgRegistry = "10.0.50.10:31110" // Kaoni Cloud NEXUS
def sonarqube = "http://10.0.50.10:31373"
def gitops = "gitlab-msa2.kaoni.com/msa1.0/gitops/ezApprovalG.git"
def today = new SimpleDateFormat("yyyyMMdd").format(new Date())
podTemplate(
containers: [
containerTemplate(name: 'jnlp', image: 'jenkins/inbound-agent:latest', resourceRequestMemory: '512Mi', resourceRequestCpu: '500m', workingDir: '/home/jenkins/agent'),
containerTemplate(name: 'docker', image: 'docker:24-dind', resourceRequestMemory: '2Gi', resourceRequestCpu: '500m', ttyEnabled: true, command: 'dockerd-entrypoint.sh', privileged: true),
containerTemplate(name: 'maven', image: 'maven:3.8.8-ibmjava-8', resourceRequestMemory: '256Mi', resourceRequestCpu: '500m', ttyEnabled: true, command: 'cat'),
containerTemplate(name: 'kustomize', image: 'alpine/git', resourceRequestMemory: '256Mi', resourceRequestCpu: '200m', ttyEnabled: true, command: 'cat'),
containerTemplate(name: 'sonarqube-scanner', image: 'sonarsource/sonar-scanner-cli:latest', resourceRequestMemory: '256Mi', resourceRequestCpu: '200m', ttyEnabled: true, command: 'cat')
],
volumes: [
persistentVolumeClaim(mountPath: '/root', claimName: 'maven-jenkins-pvc'),
secretVolume(secretName: 'docker-config', mountPath: '/etc/docker')
]
) {
node(POD_LABEL) {
stage("1. Checkout") {
checkout scm
}
stage("2. Maven build") {
container('maven') {
script {
sh "cd ${packageName} && mvn clean package -DskipTests=true"
sh "mkdir ROOT && cd ROOT && jar xvf ../${packageName}/output/ezFlow.war"
echo "Maven build completed"
}
}
}
stage("3. SonarQube Analysis and Quality Gate Check") {
container('sonarqube-scanner') {
script {
withSonarQubeEnv('SonarQube') {
withCredentials([string(credentialsId: 'sonarqubeToken', variable: 'SONARQUBE_TOKEN')]) {
sh """
sonar-scanner \
-Dsonar.projectKey=${microServiceName} \
-Dsonar.sources=${packageName} \
-Dsonar.host.url=${sonarqube} \
-Dsonar.token=${SONARQUBE_TOKEN} \
-Dsonar.java.binaries=${packageName}/output/classes \
-Dsonar.java.libraries=ROOT/WEB-INF/lib \
-Dsonar.sourceEncoding=UTF-8
"""
}
}
def qualityGate = waitForQualityGate()
echo "Status: ${qualityGate.status}"
if (qualityGate.status != 'OK') {
error "Pipeline aborted due to Quality Gate failure: ${qualityGate.status}"
} else {
echo "Quality Gate passed: ${qualityGate.status}"
}
}
}
}
stage("4. Docker build") {
container('docker') {
script {
sh "docker build -t ${microServiceName}:${today}bn${env.BUILD_NUMBER} ."
echo "Docker build completed"
}
}
}
stage("5. Push Docker Image to Kaoni Cloud Nexus") {
container('docker') {
script {
withCredentials([[$class: 'UsernamePasswordMultiBinding',
credentialsId: 'kcr-credential',
usernameVariable: 'USERNAME',
passwordVariable: 'PASSWORD'
]]) {
sh "docker login ${imgRegistry} -u ${USERNAME} -p ${PASSWORD}"
sh "docker tag ${microServiceName}:${today}bn${env.BUILD_NUMBER} ${imgRegistry}/ktg-${microServiceName}:${today}bn${env.BUILD_NUMBER}"
sh "docker push ${imgRegistry}/ktg-${microServiceName}:${today}bn${env.BUILD_NUMBER}"
echo "push to Kaoni Cloud Nexus completed"
}
}
}
}
stage("6. Update Manifest and Push to GitOps") {
container('kustomize') {
script {
withCredentials([[$class: 'UsernamePasswordMultiBinding',
credentialsId: 'gitlab-credentials',
usernameVariable: 'GIT_USERNAME',
passwordVariable: 'GIT_PASSWORD'
]]) {
sh "apk add --no-cache kustomize"
sh 'git config --global user.email "jenkins@kaoniDevops.com"'
sh 'git config --global user.name "Jenkins"'
sh "git clone http://${GIT_USERNAME}:${GIT_PASSWORD}@${gitops} gitops"
sh "cd gitops/overlays/staging && \
kustomize edit set image registry.nexus.com/ktg-${microServiceName}:${today}bn${env.BUILD_NUMBER} && \
git add . && \
git commit -m \"Update ${microServiceName} image to ${today}bn${env.BUILD_NUMBER}\" && \
git push http://${GIT_USERNAME}:${GIT_PASSWORD}@${gitops}"
echo "Update Manifest and push to GitOps completed"
}
}
}
}
}
}
|
stage("6. Update Manifest and Push to GitOps")
를 추가했다.
개발자가 Git 에 App 소스코드를 push하면 Jenkins pipeline이 CI를 진행한다.
Jenkins가 Docker Image build를 완료하면, 해당 Image로 적용해서 새롭게 Deploy를 해야할 것이다. 즉, deploy 하려는 Image의 name:tag 를 해당 Image의 것으로 변경해주어야 함을 의미한다.
따라서 Stage("6. Update Menifest and Push to GitOps")가 의미하는 바는 다음과 같다.
1. menifest repo 인 gitOps에서 menifest를 clone 받는다.
2. ./overlays/staging/kustomize.yaml 파일에서 image 의 name:tag 를 registry.nexus.com/ktg-${microServiceName}:${today}bn${env.BUILD_NUMBER}
로 수정(update) 한다.
3. update 된 menifest 를 GitOps에 push 한다.
4. GitOps의 menifest를 기반으로 ArgoCD는 deploy한다.
#GitOps 구성은 아래에서 확인할 수 있다.
[CI CD] 09. Kubernetes에 ArgoCD 로 App 배포
지난 chapter에서 Kubernetes에 ArgoCD를 설치하였다.이번 chapter에서는 GitOps menifest Repo를 구성하고, ArgoCD server Web UI 를 통해 Kubernetes cluster에 App을 배포 할 것이다. 바로 본론으로 들어가자. 1. GitOp
crea-russianblue.tistory.com
2) Jenkins에 Credentials 추가
Jenkins 접속, 로그인
Jenkins 관리 클릭
credential 클릭
system 클릭
Global credentials 클릭
Add Credentials 클릭
kind = username with password 선택
username = [GitLab ID]
passowrd = [Gitlab Password]
ID = gitlab-credentials 입력
아래 Create 클릭
Credential : gitlab-credentials 등록 완료
이로서 모든 준비가 끝났다.
CI CD 10개의 chapter에 걸쳐 Jenkins, ArgoCD, SonarQube 를 이용하여 CI/CD security 까지 구현해냈다.
GitLab에 application 소스코드를 push해서 CI/CD pipeline이 정상적으로 동작하는지 확인해 보자.
2. CI/CD for DevsOps
1) Jenkins
stage 3. SonarQube의 코드품질 검사
stage 6. GitOps repo에 Image tag를 변경시킨 menifest를 push
2) SonarQube
SonarQube 서버에서 '코드 품질 분석 결과' 확인
Quality Gate Status = passed
이므로 Jenkins pipeline - stage 3에서 CI/CD 를 계속 진행해도 된다는 응답을 보낸다.
3) ArgoCD
Jenkins pipeline - stage 6에서 GitOps의 menifest를 update 했으므로, ArgoCD는 변화를 감지하고 deploy를 새롭게 진행한다.
성공적으로 deploy 된 모습을 볼 수 있다.
여기까지 따라오느라 고생 많았다.
당신도 이제 DevsOps 엔지니어다.
건투를 빈다.
'1) Kaoni Cloud > CI CD' 카테고리의 다른 글
09. Kubernetes에 ArgoCD 로 App 배포 (0) | 2024.06.10 |
---|---|
08. Kubernetes에 ArgoCD 설치 (0) | 2024.06.08 |
07. Jenkins와 SonarQube 연동 (0) | 2024.06.08 |
06. Kubernetes에 SonarQube 설치 (1) | 2024.06.08 |
05. Jenkins Pipeline 구축 (0) | 2024.06.07 |