TOPIC/DevOps

Jenkins, ArgoCD로 CI/CD Pipeline 구성하기 (3)

H-Y-E-N 2024. 2. 5. 13:43

 안녕하세요. HYEN입니다.

 

지난 글에서는 Jenkins에서 Jenkinsfile을 사용하여 Job을 구성하는 과정에 대해 알아보았는데요. 

지난 글 바로 가기 : https://with-cloud.tistory.com/20 

 

Jenkins, ArgoCD로 CI/CD Pipeline 구성하기 (2)

안녕하세요. HYEN입니다. 지난 글에서는 CI/CD Pipeline에 대한 전체 Flow와 Pipeline을 구성하기 전에 필요한 설정들에 대해 다뤄보았습니다. 지난 글 바로 가기 : https://with-cloud.tistory.com/19. Jenkins, ArgoCD

with-cloud.tistory.com

이번 글에서는 CI/CD Pipeline 구성의 마지막 부분인 Github와 ArgoCD 간 연결, 그리고 전체 CI/CD Pipeline을 자동화 하는 부분에 대해 다뤄보겠습니다. 😸


Contents

     

    ※ Jenkins와 ArgoCD 등 CI/CD Pipeline 구성에 필요한 모든 리소스는 사전에 배포해 두었습니다.※

     

    6. GitHub와 ArgoCD 연결 

    두 번째 Job에 의해 Github Repository의 deploy.yaml이 업데이트 되면 해당 Repository를 주기적으로 체크하는 ArgoCD에 의해 해당 변경 사항이 감지되도록 GitHub와 ArgoCD를 연결해 보도록 하겠습니다. 

     

    6.1 ArgoCD에 GitHub Repository 등록

    • ArgoCD 로그인 > 좌측 상단의 [Settings] 탭 > [Repositories] 

     

    • [+ Content Repo] 버튼을 클릭합니다. 

     

    • Connection을 위한 세부 정보를 입력합니다. 
      • HTTPS를 사용하여 연결하기 위해 [VIA HTTPS] 옵션을 선택합니다.

      • Repository URL을 입력합니다. 

      • Username에는 Github의 User 명을 입력하고 Password에는 발급해 놓은 PAT를 입력합니다.

      • 상단의 [Connect] 버튼을 클릭하여 연결을 완료합니다. 

     

    • 연결 상태를 확인한 결과 Successful이 뜨는 것을 알 수 있습니다.  

     

    6.2 ArgoCD에서 Application 생성 

    6.1에서 연결한 Repository에 대한 정보를 확인할 수 있는 페이지에서 우측의 점 세 개를 클릭한 후, [Create application]을 선택하여 Application을 생성할 수 있습니다. 

     

    • [General] 탭
      • Sync Policy를 설정합니다. (현재는 테스트를 위해 Manual로 구성하였으나 뒤에서 Automatic으로 변경할 예정입니다.)

     

    • [Source] 탭
      • GitHub Repository에 대해 설정합니다. 
        • Repository URL을 입력합니다.

        • Path : 해당 Repository에서 manifest file이 위치하고 있는 경로를 입력합니다. (가장 상위일 경우 .를 입력합니다.)

     

    • [Destination] 탭
      • Azure Kubernetes Service(AKS) 내 Application이 배포될 위치에 대해 설정합니다. 
        • Namespace : Application이 배포될 namespace를 입력합니다. 

     

    • 상단의 [Create] 버튼을 클릭하여 Application 생성을 완료합니다. 

     

    7. ArgoCD와 Azure Kubernetes Service(AKS) Sync

    ArgoCD는 연결된 AKS 내 Deployment의 현재 상태와 Github Repository의 deploy.yaml의 상태를 확인하고 Sync하는 작업을 수행합니다. 

     

    7.1 생성된 Application 확인

    • [Applications] 탭에서 생성된 Application을 확인할 수 있습니다.

    • Status 부분을 보면 해당 Application의 상태가 OutOfSync 임을 알 수 있습니다.

     

    • 생성된 Application을 클릭한 후 Out of Sync가 떠 있는 Deployment를 클릭합니다. 

     

    • 세부 정보 창 하단의 [DIFF] 탭을 클릭하여 Out of Sync인 부분을 확인할 수 있습니다. 
      • 현재 AKS 상에 배포된 Deployment가 바라보는 Image의 tag와 Github 상에 업데이트된 deploy.yaml file에 정의된 Image의 tag가 일치하지 않기 때문임을 알 수 있음

     

    • 현재 Web Page는 하기와 같습니다. 😜

     

    • 상단의 Sync 버튼을 클릭하여 Sync를 수행합니다. 
      • Out of Sync 상태인 모든 Object에 대해 Synchronize를 수행합니다. 

     

    • Sync 수행 시 ArgoCD에서 GUI를 통해 Sync가 진행되는 과정을 확인할 수 있습니다. 

     

    • kubectl get po 명령어를 사용하여 Sync가 진행되는 과정을 확인할 수 있습니다. 

     

    • 변경 사항이 적용된 Web Page는 하기와 같습니다. 

     

    8. 전체 CI/CD Pipeline 자동화 

    지금까지는 Jenkins에서의 Job들도, GitHub에 변경 사항이 생겼을 때 ArgoCD가 Sync를 하는 것도 모두 따로따로 진행되도록 구성을 하였습니다. 

    테스트를 할 때 불필요하게 모든 과정이 반복되는 것을 막기 위함이었는데요. 

    각각의 단계에 대해 테스트를 성공적으로 마무리 하였기 때문에 마지막으로 전체 CI/CD Pipeline을 자동화 해 보도록 하겠습니다. 

     

     

    그 전에 간단하게 전체 CI/CD Pipeline에 대해 Flow를 정리해 보도록 하겠습니다. 

     

    1️⃣ 첫 번째 GitHub Repository, 즉, Web Page를 위한 image에 대한 코드가 존재하는 Repository에 변경 사항이 발생할 경우 첫 번째 Jenkins Job에 의해 변경 사항이 반영된 새로운 이미지가 build되고 ACR로 push됩니다. 

     

    2️⃣ 첫 번째 Jenkins Job의 마지막 stage에서 두 번째 Jenkins Job을 트리거합니다. 

     

    3️⃣ 두 번째 Jenkins Job은 변경 사항이 적용된 이미지를 두 번째 GitHub Repository, 즉, manifest file이 업로드 되어 있는Repository에 대해 이미지 버전을 변경합니다. (deploy.yaml file의 이미지 버전을 변경)  

     

    4️⃣ 두 번째 GitHub Repository를 바라보고 있는 ArgoCD는 이러한 변경 사항을 감지한 후 자동으로 GitHub Repository에 정의된 deploy.yaml file과 실제로 AKS 내에 배포되어 있는 Deployment Object 간 Sync를 수행합니다. 

     

    여기서 두 번째 step과 네 번째 step에 대해 추가적인 구성이 필요해집니다.

    구성은 어렵지 않습니다. 

     

    먼저 첫 번째 Job과 두 번째 Job을 연결해 보도록 하겠습니다. 

     

    8.1 첫 번째 Job 완료 후 두 번째 Job을 Trigger하도록 구성 

    • 첫 번째 Job의 Jenkinsfile에 Stage를 추가해야 합니다. 
    pipeline {
        agent any
    
        environment {
            BUILD_NUMBER = "v6"
            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}/sundls:${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"
                    }
                }
            }
    	stage('Trigger 2nd Job') {
                steps {
                    echo 'Trigger 2nd Job...'
                    build job: 'pipeline-for-manifest', wait: true
                }
            }
        }
    }
    • 'Trigger 2nd Job' stage를 제외한 stage들과 environment block은 이전 글에서 설명하였으므로 추가적으로 설명하지는 않겠습니다. 

    • 'Tigger 2nd Job' stage
      • 이 stage에서는 다음 Job을 명시해 주기만 하면 됩니다. 

      • build job: 이라는 항목에 대해 두 번째 Job의 project 이름만 기입해 주면 됩니다 .

     

    위와 같이 기존 Jenkinsfile에 stage 하나만 더 추가하면 두 Job을 연결할 수가 있습니다. 

     

    단, Jenkinsfile을 업데이트 해도 GitHub Repository에서는 이를 Jenkins로 Trigger하기 때문에 이 점 참고하시어 CI를 수행하시길 바랍니다. 

     

    8.2 이미지 관련 코드 수정 후 Git push를 통해 첫 번째 Job Trigger 

    두 Job을 연결하였으니 이번에는 이미지 관련 코드를 수정할 때 자동으로 deply.yaml file까지 변경되는지 확인해 보겠습니다. 

     

    • 먼저 코드를 수정한 후 git push 명령어를 통해 GitHub Repository를 업데이트합니다. 

     

    • GitHub Update가 완료되면 첫 번째 Job이 자동으로 trigger되고 첫 번째 Job의 마지막 stage에서 두 번째 Job이 자동으로 trigger 됩니다. 

     

    • 두 번째 Jenkins Project를 클릭하면 별도의 사용자 개입 없이 두 번째 Job이 자동으로 trigger 되는 것을 확인할 수 있습니다. 

     

    와! 성공적으로 연결된 것을 확인할 수가 있습니다. 😂

     

    다음은 ArgoCD로 가보겠습니다. 

    현재는 ArgoCD의 Sync Policy가 manual이기 때문에 자동으로 Kubernetes에 배포된 Deployment의 Image의 tag가 v6에서 v7로 변경되지 않습니다. 

     

    아직까지는 상단의 [Sync] 버튼을 클릭하여야 수정 사항이 반영됩니다. 

     

    • 기존 Web Page는 하기와 같습니다. 

     

    • 변경 사항이 적용된 Web Page는 하기와 같습니다. 

     

    8.3 ArgoCD의 Sync Policy 수정 (Manual → Auto)

    • ArgoCD 상단의 [Details] 버튼을 클릭한 후 하단의 [Sync Policy] 탭에서 [Enable Auto-Sync]를 클릭합니다. 

     

    Auto-Sync 세부 정보는 하기와 같습니다. 

    • Prune Resources
      • 이를 활성화 할 경우 연결된 Github Repository에서 manifest file이 삭제될 경우 Kubernetes Cluster에서도 해당 리소스가 삭제됩니다. 

      • Github Repository와 Kubernetes Cluster를 완전히 동기화 할 수 있어 둘 간의 상태 불일치를 방지할 수 있으나 예기치 않은 리소스가 삭제될 수 있음에 유의해야 합니다. 

    • Self Heal
      • Kubernetes Cluster의 상태를 지속적으로 Github Repository와 비교하고 둘 간에 Out of Sync가 발생할 경우 Cluster의 상태를 Github Repository의 상태로 자동으로 복구하는 기능입니다. 

     

    8.4 CI/CD Pipeline 전체 자동화 테스트 

    ArgoCD의 Sync Policy까지 Automatic으로 변경하였으니 정말 마지막으로 CI/CD Pipeline 전체를 자동화하는 테스트를 진행해 보도록 하겠습니다. 👍👍

     

    • 코드를 수정한 후 git push 명령어를 통해 GitHub Repository에 변경 사항을 적용합니다. 

     

     

    • Github Update가 완료되면 첫 번째 Job이 자동으로 Trigger되고 첫 번째 Job의 마지막 Stage에서 두 번째 Job이 자동으로 Trigger 됩니다. 

     

     

    • 두 번째 Job이 자동으로 trigger 되는 것을 확인할 수 있습니다. 

     

    • ArgoCD에서 자동으로 Sync가 이루어집니다. (deploy.yaml file의 image tag가 v7에서 v8로 변경됩니다.)

     

    • 변경된 Web Page는 하기와 같습니다. 

     


    이렇게 긴 시간에 걸쳐 CI/CD Pipeline을 구성하는 과정에 대해 테스트하고 글로 기록해 보았습니다. 😉

    다음에는 또 다른 재밌고 유익한 글로 돌아오도록 하겠습니다 :) 

    728x90
    320x100
    SMALL