ArgoCD 빠르게 레벨업 하기

appti·2024년 4월 21일
0

쿠버네티스 인강

목록 보기
15/15

서론

해당 글은 일프로 님의 인프런 강의 쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2의 내용을 정리한 글입니다.

해당 글에 사용된 내용, 사진 및 그림은 모두 강의와 강의 자료에 포함된 내용입니다.

ArgoCD 아키텍처

  • ArgoCD
    • 쿠버네티스 배포 툴
    • 변경 관리 저장소로 반드시 git 사용
  • Image Updater
    • ArgoCD의 확장 기능
    • DockerHub에서 컨테이너 이미지에 대한 변경 감지를 통해 배포 파이프라인 작성 가능
  • Rollouts
    • 고급 배포 지원
  • Events
    • 이벤트 버스 구조 아키텍처
  • Workflow
    • 워크플로우 매니지먼트 도구
  • ArgoCD 아키텍처
    • Events를 통해 이벤트를 주고받음
    • Workflow가 받은 이벤트에 따라 작업 수행
    • 배포 작업시 CD 시작
    • Rollouts을 통해 쿠버네티스 리소스 생성
  • ArgoCD 컴포넌트
    • Server
      • API 서버 + 대시보드 역할
      • Nodeport로 ArgoCD UI 접근 가능
      • argocd 툴을 통해 CLI 실행 가능
    • Repo Servcer
      • git 연결
      • 배포할 yaml 메니패스트 생성
    • Application Controller
      • 쿠버네티스 리소스 모니터링
      • Git과 비교
        • 다를 경우 Git 내용으로 배포
    • Kube API
      • 쿠버네티스로 리소스 관련 명령 실행
    • Notification
      • ArgoCD에서 발생하는 이벤트를 외부로 트리거
    • Dex
      • 외부 인증 관리
      • Grafana와 같은 대시보드들에 대한 IAM 솔루션 제공(SSO)
    • Redis
      • Git 연동 및 Kube API의 요청을 줄이기 위한 캐시 역할
    • ApplicationSet Controller
      • 멀티 클러스터를 위한 애플리케이션 패키징 관리

Argo 애플리케이션 설치 및 배포

Argo 애플리케이션

  • ArgoCD에서 CD/Image Updater/Rollouts 설치
    • Helm + 젠킨스를 통해 설치
  • 배포 준비 과정
    • ArgoCD 애플리케이션 생성
    • 연동할 Git에 대한 정보 Source 명시
    • 연동한 쿠버네티스 클러스터 정보 Destination 명시
    • 기본 정보 및 배포 시 지정할 옵션 General 명시

ArgoCD 설치

  • 파이프라인 생성

  • Github Project URL 추가

  • Pipeline 설정

  • 젠킨스를 통해 ArgoCD 설치
https://192.168.56.30:30002/login
  • ArgoCD 대시보드 접속
kubectl get -n argo secret argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d
  • ArgoCD 임시 비밀번호 확인

  • 로그인 완료

설정 파일 확인

## Server
server:
  service:
    type: NodePort
    nodePortHttps: 30002
  • ArgoCD 포트 값 지정
pipeline {
    agent any

    parameters {
        choice(choices: ['option', 'namespace_create', 'namespace_delete', 'helm_upgrade', 'helm_uninstall'], name: 'DEPLOY_TYPE', description: '배포 타입 선택')
        choice(choices: ['option', 'argo-cd', 'argocd-image-updater', 'argo-rollouts'], name: 'TARGET_ARGO', description: 'Argo 대상 선택')
    }

    environment {
        DOCKERHUB_USERNAME = '1pro'
        GITHUB_URL = 'https://github.com/k8s-1pro/install.git'
        INSTALL_PATH = 'ground/cicd-server/argo'
    }

    stages {
        stage('네임스페이스 관리') {
            steps {
                script{
                    if (params.DEPLOY_TYPE == "namespace_create") {
                        withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
                            sh "kubectl apply -f ./${INSTALL_PATH}/kubectl/namespace.yaml --kubeconfig " + '${KUBECONFIG}'
                        }
                    } else if (params.DEPLOY_TYPE == "namespace_delete") {
                        withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
                            sh "kubectl delete -f ./${INSTALL_PATH}/kubectl/namespace.yaml --kubeconfig " + '${KUBECONFIG}'
                        }
                    } else {
                        echo "skip namespace"
                    }
                }
            }
        }

        stage('헬름 배포 관리') {
            steps {
                script{
                    if (params.DEPLOY_TYPE == "helm_upgrade") {
                        withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
                            HELM_DEPLOY_COMMAND =  "helm upgrade ${params.TARGET_ARGO} ./${INSTALL_PATH}/helm/${params.TARGET_ARGO} " +
                                " -f ./${INSTALL_PATH}/helm/${params.TARGET_ARGO}/values-mac.yaml" +
                                " -n argo --install --kubeconfig " + '${KUBECONFIG}' +
                                " --wait --timeout=10m "   // 최대 10분으로 설정

                            // image-updater일 경우 도커허브 credentials 주입
                            if (params.TARGET_ARGO == "argocd-image-updater") {
                                // https://argocd-image-updater.readthedocs.io/en/stable/basics/update-methods/
                                withCredentials([usernamePassword(credentialsId: 'docker_password', passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) {
                                    HELM_DEPLOY_COMMAND += " --set config.registries[0].credentials=env:DOCKER_HUB_CREDS="+ '${USERNAME}' + ":" + '${PASSWORD}'
                                }
                            }

                            sh "eval ${HELM_DEPLOY_COMMAND}"
                            // sh "helm update argo-cd -n argo --kubeconfig " + '${KUBECONFIG}' + " --wait --timeout=10m "
                        }

                    } else if (params.DEPLOY_TYPE == "helm_uninstall") {
                        withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
                            sh "helm uninstall ${params.TARGET_ARGO} -n argo --kubeconfig " + '${KUBECONFIG}'

                            // CRD 삭제
                            if (params.TARGET_ARGO == "argo-cd") {
                                sh "kubectl delete crd applications.argoproj.io applicationsets.argoproj.io appprojects.argoproj.io --kubeconfig " + '${KUBECONFIG}'
                            }
                            if (params.TARGET_ARGO == "argo-rollouts") {
                                sh "kubectl delete crd analysisruns.argoproj.io analysistemplates.argoproj.io clusteranalysistemplates.argoproj.io --kubeconfig " + '${KUBECONFIG}'
                                sh "kubectl delete crd experiments.argoproj.io rollouts.argoproj.io --kubeconfig " + '${KUBECONFIG}'
                            }
                        }
                    } else {
                        echo "skip deploy"
                    }
                }
            }
        }
    }
}

App 배포하기 (kubectl)

  • NEW APP 선택

  • 애플리케이션 설정

  • 애플리케이션 생성 확인

  • SYNC를 통해 배포 시작

  • 배포 완료

  • manifest 확인

App 배포하기 (Helm)

  • 애플리케이션 설정

  • SYNC를 통해 배포

ArgoCD Image Updater

  • 배포를 해야 하는 상황
    1. 리소스 스펙 변경
    2. App 버전 업그레이드(컨테이너 이미지 변경)
      2-1. 자동화 가능 작업
  • Image Updater 사용 전
    • 컨테이너 빌드가 끝난 이후 자동 배포를 하기 어려워짐
    • 별도로 yaml을 수정해 업데이트 수행
  • Image Updater 사용 후
    • 컨테이너 빌드가 끝나면 이를 감지해 자동 배포하기 편함

실습

  • 젠킨스를 통해 Image Updater 설치

  • ArgoCD Helm App ANNOTATIONS 추가

  • 자동 SYNC 활성화

  • 파이프라인 추가

  • 파이프라인 설정

  • 빌드 수행

  • 자동으로 변경되어 Sync 시점이 변경된 것을 확인할 수 있음

Argo Rollouts를 이용한 배포

Blue/Green

  • ArgoCD 없이도 Argo Rollouts를 통해 Blue/Green 배포 가능
  • Rollouts 사용 시
    • 쿠버네티스 내부적으로 Rollout 컨트롤러 생성
    • Rollout이 ReplicaSet 생성
    • ReplicaSet이 파드 생성
    • Rollout 태그 v1 -> v2 변경
    • v2 버전 ReplicaSet, 파드 생성
    • 액티브 서비스는 v1, 프리뷰 서비스는 v2를 가리키게 됨
      • Rollout이 서비스 셀렉터 등 필요한 데이터 변경
    • QA 담당자가 프리뷰 서비스를 통해 테스트
    • 테스트가 완료되면 Promote 명령어 수행
    • 트래픽을 프리뷰 서비스로 변경하고 액티브 서비스에 있던 파드를 삭제

실습

  • Argo Rollouts 설치

  • yaml을 통해 Argo 애플리케이션 추가

  • 정상적으로 배포되었는지 확인
while true; do curl http://192.168.56.30:32233/version; sleep 2; echo '';  done;

while true; do curl http://192.168.56.30:32243/version; sleep 2; echo '';  done;

  • 액티브/프리뷰 서비스에 트래픽 발생
    • 모두 버전 1이 출력되고 있는 상태
    • github에서 이미지 버전을 v2.0.0으로 변경해 테스트
http://192.168.56.30:30003/rollouts/anotherclass-223

  • Argo Rollout을 통해서도 수행 가능
curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v1.6.4/kubectl-argo-rollouts-linux-amd64
chmod +x ./kubectl-argo-rollouts-linux-amd64
mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
  • Argo Rollout CLI 설치
kubectl argo rollouts version
  • Argo Rollout CLI 확인
kubectl argo rollouts get rollout api-tester-2233 -n anotherclass-223 -w
  • Argo Rollout 조회(모니터링)

  • 리소스 정리

Canary

  • Rollouts 사용 시
    • 쿠버네티스 내부적으로 Rollout 컨트롤러 생성
    • ReplicaSet, 파드, 서비스 생성
    • Rollout 태그 v1 -> v2 변경
    • v2 버전 ReplicaSet 생성
    • Rollout 배포 전략으로 Canary 선택
      • 내부적으로 steps 속성을 통해 진행
      • Canaray 파드 하나 생성 후 트래픽을 33%까지 유지
    • 테스트 진행
    • 테스트 종료 후 Promote 명령어 수행해 다음 단계인 weight 66% 설정 적용

실습

kubectl apply -f https://raw.githubusercontent.com/k8s-1pro/kubernetes-anotherclass-sprint2/main/2234/deploy/argo-rollouts/rollout.yaml -n anotherclass-223
kubectl apply -f https://raw.githubusercontent.com/k8s-1pro/kubernetes-anotherclass-sprint2/main/2234/deploy/argo-rollouts/configmap.yaml -n anotherclass-223
kubectl apply -f https://raw.githubusercontent.com/k8s-1pro/kubernetes-anotherclass-sprint2/main/2234/deploy/argo-rollouts/secret.yaml -n anotherclass-223
kubectl apply -f https://raw.githubusercontent.com/k8s-1pro/kubernetes-anotherclass-sprint2/main/2234/deploy/argo-rollouts/service.yaml -n anotherclass-223
  • 배포
kubectl argo rollouts get rollout api-tester-2234 -n anotherclass-223 -w
  • 배포 모니터링
while true; do curl http://192.168.56.30:32234/version; sleep 2; echo '';  done;
  • 트래픽 발생
kubectl argo rollouts set image api-tester-2234 api-tester-2234=1pro/api-tester:2.0.0 -n anotherclass-223
  • 이미지 변경

  • 다음 단계 수행(Promote 명령어를 통해 다음 Step 진행)
    • Step1. Set Weight: 33% : Stable 2 pod, Canary 1 pod 상태로 만듦
    • Step2. Pause : Promote 클릭 때까지 정지
    • Step3. Set Weight: 66% : Stable 1 pod, Canary 2 pod 상태로 만듦
    • Step4. Pause (2m) : 2분 동안 정지
    • Step5. : Canary 2 pod 상태로 만듦
profile
안녕하세요

0개의 댓글