본문 바로가기
  • lakescript
스터디 이야기/AWS EKS

[AEWS] 7-2. Amazon EKS - CI/CD (ArgoCD/ArgoRollouts)

by lakescript 2024. 4. 16.

사전 준비

더보기

 

위와 같이 사전 준비가 필요합니다. 저번 글에서 설명했듯이, EKS를 배포하기 위한 VPC를 생성하고, Public Subnet, Private Subnet을 생성합니다. 그 후 EKS Cluster에 접근하기 위한 bastion EC2를 미리 생성합니다.
추가로 지난번 실습 때 진행했었던 ExternalDNS와 AWS LB Controller, EBS csi driver 설치, gp3 스토리지 클래스 생성합니다.

 

Argo

 

 

ChatGPT가 알려주는 Argo
"Argo"는 쿠버네티스(Kubernetes) 기반 워크플로우 자동화를 위한 오픈 소스 도구 모음을 지칭합니다. 이 도구 모음은 주로 DevOps와 GitOps 방식을 통해 쿠버네티스 애플리케이션의 배포 및 관리를 자동화하고 최적화하는 데 사용됩니다. Argo Project들은 쿠버네티스의 확장성과 자동화 기능을 최대한 활용하여, 개발 및 운영 팀이 보다 효율적으로 작업을 처리하고, 배포를 관리할 수 있도록 돕습니다. Argo 프로젝트는 CNCF (Cloud Native Computing Foundation)의 산하 프로젝트로, 클라우드 네이티브 환경에서 널리 사용되고 인정받고 있습니다.

 

 

Argo Project 종류

ArgoCD

쿠버네티스 리소스의 선언적 설정을 Git 저장소에 유지하면서, 지속적으로 클러스터와 동기화하여 자동 배포를 수행하는 GitOps 도구입니다.

 

Argo Rollouts

이 컴포넌트는 쿠버네티스에 고급 배포 기능을 제공합니다. 예를 들어, 카나리(canary) 릴리즈나 블루/그린(blue/green) 배포와 같은 전략을 지원하여, 애플리케이션 업데이트 시 위험을 최소화할 수 있습니다.

 

Argo Events

이벤트 기반 종속성을 관리하며, 다양한 소스로부터 이벤트를 트리거하여 Argo Workflows나 Argo CD와 같은 다른 Argo 프로젝트 도구를 활성화시킬 수 있습니다.

 

Argo Workflows

컨테이너 기반의 워크플로우를 생성하고 관리하는데 사용되며, 복잡한 작업 처리와 데이터 처리 파이프라인을 구축할 때 유용합니다.

 

 

위의 Argo Project들 중에서 CD와 연관이 있는 ArgoCD와 ArgoRollout을 살펴보겠습니다.

 

ArgoCD

ArgoCD는 이름에서 알다시피 CD(Continuous Derivery)에 관한 오픈소스 프로젝트입니다. 특히 Kubernetes를 위한 선언적 GitOps 지속적 전달 도구입니다.

 

다시 말해, gitops 방식을 차용하여 git으로 code를 관리하며 build된 결과물을 운영환경에 적용(Sync)시키는 기술입니다.

 

동작 원리

 

 

Argo CD는 kustomize, helm chart, jsonnet, YAML등 다양한 k8s 정의 파일을 토대로 사용가능합니다.

 

기본 동작은 사용자가 git에 PR Merge를 하게 되면 ArgoCD의 RepositoryService가 이를 감지합니다. 또한, Application Controller는 k8s의 리소스를 모니터링하며 Git의 소스와 비교하여 변경점을 알려줍니다.

 

 

실습

ArgoCD를 실제 cluster에 배포하기에 앞서 공식문서 를 통해 AWS Application Load Balancer일 경우 어떻게 배포하는지 확인해보겠습니다.

 

alb의 ingress 설정

global:
  domain: argocd.$MyDomain

configs:
  params:
    server.insecure: true

controller:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

server:
  ingress:
    enabled: true
    controller: aws
    ingressClassName: alb
    hostname: "argocd.$MyDomain"
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/backend-protocol: HTTP
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80}, {"HTTPS":443}]'
      alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
      alb.ingress.kubernetes.io/ssl-redirect: '443'
    aws:
      serviceType: ClusterIP
      backendProtocolVersion: GRPC
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

repoServer:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

applicationSet:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

notifications:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

 

global과 server.hostname에 host url을 입력시켜 host 연결을 해주고, 각각 metric을 수집할 수 있도록 enable 설정을 해줍니다. 또한 certificate-arn에도 발급받은 CERT_ARN을 입력시킵니다. 그 외에 중요하게 봐야할 부분은

server.ingress.aws.backendProtocolVersion의 값이 GRPC라는 것 입니다.

 

ChatGPT가 알려주는 gRPC
gRPC는 Google에서 개발한 고성능, 오픈 소스 원격 프로시저 호출 (RPC) 프레임워크로, 클라이언트와 서버 간의 통신을 위해 설계되었습니다. gRPC는 Protocol Buffers (protobuf)를 사용하여 메시지 포맷을 정의하고, HTTP/2 프로토콜을 통해 데이터를 전송합니다.
AWS에서는 ALB를 통해 gRPC 트래픽을 로드 밸런싱 할 수 있습니다. GRPC로 설정하면, ALB는 HTTP/2 프로토콜을 사용하는 gRPC 트래픽을 적절히 처리하고, 백엔드 서버에 전달합니다. 이 설정은 특히 마이크로서비스 아키텍처에서 서비스 간의 효율적인 통신을 제공하며, 높은 성능과 낮은 지연 시간을 필요로 하는 애플리케이션에 적합합니다.

 

 

namespace 생성

kubectl create ns argocd

 

argoCD 리소스들을 설치할 namespace을 생성합니다.

 

ArgoCD 설치

helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd --version 6.7.11 -f argocd-values.yaml --namespace argocd

 

ArgoCD를 설치하기 위해 helm repo를 추가해줍니다. 그 후 위에서 생성해놓은 custom value 파일을 적용시켜 argocd namespace에 배포합니다.

 

설치 확인

kubectl get ingress,pod,svc -n argocd

 

kubectl 명령을 통해 argocd namespace에 리소스가 잘 생성되었는지 확인합니다.

 

아래와 같이 AWS Managed Console에서도 ALB가 생성중임을 확인하실 수 있습니다.

 

 

일정 시간 후 ALB가 생성이 완료되면 아래의 url로 접속합니다.

 

https://argocd.${MyDomain}

 

 

 

접속 암호 확인

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo

 

배포한 ArgoCD 페이지에 접속하기 위해 비밀번호를 알아야 하는데, 위의 명령어를 통해 확인이 가능합니다.

 

 

ArgoCD 페이지 접속

ID : admin

PW : 최초 접속 암호

 

 

 

App 배포

ArgoCD Application 생성

 

Create App 버튼을 클릭하여 ArgoCD Application을 생성합니다. 아래의 값들로 설정해주세요.

 

- Application Name : first-myweb
- Project Name : default
- SYNC POLICY : Manual
    - AUTO-CREATE NAMESPACE : 클러스터에 네임스페이스가 없을 시 argocd에 입력한 이름으로 자동 생성
    - APPLY OUT OF SYNC ONLY : 현재 동기화 상태가 아닌 리소스만 배포
- PRUNE PROPAGATION POLICY
    - foreground : 부모(소유자, ex. deployment) 자원을 먼저 삭제함
    - background  : 자식(종속자, ex. pod) 자원을 먼저 삭제함
    - orphan  : 고아(소유자는 삭제됐지만, 종속자가 삭제되지 않은 경우) 자원을 삭제함
- AUTO-CREATE-NAMESPACE
- SOURCE
    - Repository URL : https://github.com/leehosu/aews-cicd.git
    - Revision : main
    - Path : 3/deploy
- DESTINATION
    - Cluster URL : https://kubernetes.default.svc
    - Namespace : first

 

생성 후 sync를 통해 Application을 배포합니다.

 

 

 

실제로 배포되었는지 확인하기 위해 kubectl 명령어로 확인해봅니다.

kubectl get po

 

 

 

 

Sync 실습

 

 

현재 aews-cicd/3/deploy/deployment-svc.yaml에서 정의된 replicas는 4개인 것을 확인하실 수 있습니다.

 

 

 

실제로 4개의 Pod가 띄어져 있습니다.

 

 

aews-cicd/3/deploy/deployment-svc.yaml에서 replicas를 3개로 변경해보겠습니다.

 

 

그 후 ArgoCD로 돌아와 REFRESH APPS 버튼을 눌러 app을 최신화시켜줍니다.

 

 

 

 

현재 application의 상태가 OutOfSync인 것을 확인하실 수 있고, sync를 통해 버전을 맞춰주도록 하겠습니다.

 

 

Sync가 완료되면 Pod의 수가 3개로 변경된 것을 확인하실 수 있습니다.

 

 

kubectl get po

 

kubectl 명령어를 통해 pod의 수를 확인해보면 위와 같이 3개의 Pod가 띄어진 것을 확인하실 수 있습니다.

 

 

ArgoCD CLI

앞서 진행한 실습은 ArgoCD를 Web에서 진행한 실습이었습니다. ArgoCD도 CLI가 존재하는데, CLI를 통해 실습을 진행해보겠습니다.

 

ArgoCD CLI 설치

curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm -f argocd-linux-amd64

 

위의 명령어를 통해 ArgoCD를 설치해줍니다.

 

설치 확인

argocd version

 

위의 명령어로 설치된 ArgoCD의 버전을 확인합니다.

 

 

 

ArgoCD CLI를 통해 접근

argocd login argocd.$MyDomain

 

 

login 명령어를 입력하신 후 Username과 Password를 입력하여 로그인합니다. 

 

Cluster 추가

kubectl config get-contexts -o name

 

현재 cluster를 ArgoCD CLI로 관리하기 위해 위의 명령어를 통해 현재 cluster의 name을 출력합니다.

 

argocd cluster add ${CLUSTER_USER}

 

argocd에 cluster를 추가하는데 ${CLUSTER_USER}의 값에 cluster name을 입력합니다.

 

 

위와 같이 일련의 작업들이 일어나고 성공적으로 add가 된 것을 확인하실 수 있습니다.

 

ArgoCD CLI를 통해 Application 생성

kubectl config set-context --current --namespace=argocd

 

먼저 argocd의 cluster로 변경합니다.

 

argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default

 

그 후 예제 저장소를 참고하여 Application을 추가합니다.

 

 

ArgoCD Web에 접속하여 확인해보시면 정상적으로 Application이 생성되었습니다.

 

argocd app list

 

list 명령어를 통해 현재 배포되어 있는 application을 확인해보겠습니다.

 

 

argocd app get guestbook

 

get 명령어를 통해 Application의 상세 정보를 확인합니다.

 

 

argocd app sync guestbook

 

sync 명령어를 통해 Application을 배포해보겠습니다.

 

위의 사진과 같이 일련의 과정들이 보여지며 Synced 상태로 변경되며 배포가 완료됩니다.

 

 

ArgoCD Web에 접속하여 해당 Application을 클릭하면 위의 사진과 같이 배포가 정상적으로 진행된 것을 확인하실 수 있습니다.

 

kubectl get po -n default

 

kubectl 명령어를 통해 deafult namespace에 배포된 Pod를 확인해보겠습니다.

 

 

guestbook-ui Pod가 정상적으로 배포된 것을 확인하실 수 있습니다.

 

ArgoCD CLI를 통해 Application 삭제

argocd app delete guestbook

 

delete 명령어를 통해 Application을 삭제합니다.

 

 

 

 

마찬가지로 ArgoCD Web에 접속하면 해당 Application이 삭제된 것을 확인하실 수 있습니다.

 

 

 

Argo Rollouts

 

ChatGPT가 알려주는 ArgoRollouts
Argo Rollouts는 Argo 프로젝트의 일부로, Kubernetes 환경에서 고급 배포 전략을 구현하기 위한 도구입니다. 기본적으로 Kubernetes는 rolling 업데이트를 지원하지만, Argo Rollouts는 더욱 세밀하고 제어가 가능한 배포 전략을 제공하여, 애플리케이션의 배포 과정에서 더 나은 가용성과 안정성을 보장합니다.

 

 

 

Argo Rollouts 구조

 

  • Argo Rollouts controller : Kubernetes API 서버로부터 이벤트를 수신하고, 배포 로직을 실행하고, 배포 상태를 업데이트
  • Rollout resource : Kubernetes의 Deployment 리소스를 확장한 것으로, Canary나 Blue/Green 배포와 배포 전략을 구성
  • Replica sets for old and new version : 배포 중에 새 버전과 이전 버전의 애플리케이션을 관리하기 위해 복수의 ReplicaSet이 생성되는데, 즉 동시에 두 버전의 애플리케이션 인스턴스를 실행
  • Ingress/Service : Ingress 또는 Service 리소스는 트래픽을 적절한 버전의 애플리케이션으로 라우팅하는 역할
  • AnalysisTemplate :  배포의 성공 여부를 평가하기 위해 사용되는 메트릭 평가 규칙을 정의
  • AnalysisRun : AnalysisTemplate에 기반한 실제 평가 작업을 수행
  • Metric providers : AnalysisTemplate에서 사용할 외부 메트릭 데이터를 제공(Prometheus, Datadog, New Relic과 같은 모니터링 도구)
  • CLI : Argo Rollouts의 상태를 조회하거나 관리할 수 있는 명령줄 도구
  • UI : 웹 기반 인터페이스로, 사용자가 그래픽 인터페이스를 통해 배포 과정을 모니터링하고 관리

 

Rollouts 배포 전략

Argo Rollouts의 대표적인 대포 전략에는 Blue/Green, Canary 2가지가 있습니다.

 

Blue/Green

 

Blue/Green 배포는 현재 버전(블루)과 새 버전(그린)을 동시에 실행하고, 트래픽을 새 버전으로 점차적으로 이동시켜 배포하는 전략입니다.

 

Canary

 

Canary 배포는 새로운 버전을 점진적으로 사용자에게 먼저 배포하여, 문제가 없는지 검증한 후 전체 사용자에게 배포합니다.

특히, Canary는 Ingress나 Istio와 긴밀하게 연결되어 live traffic을 조절할 수 있습니다.

 

 

 

ArgoRollouts 설치

namespace 생성

kubectl create ns argo-rollouts

 

ArgoRollouts를 설치할 namespace를 생성합니다.

 

helm 설치

dashboard:
  enabled: true
  ingress:
    enabled: true
    ingressClassName: alb
    hosts:
      - argorollouts.$MyDomain
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/backend-protocol: HTTP
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":80}, {"HTTPS":443}]'
      alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
      alb.ingress.kubernetes.io/ssl-redirect: '443'

 

AWS ALB 설정이 필요하여 위의 설정값을 토대로 helm 설치를 진행합니다. 

hosts 부분과 certificat-arn 부분에 유의해주세요.

helm install argo-rollouts argo/argo-rollouts --version 2.35.1 -f argorollouts-values.yaml --namespace argo-rollouts

 

 

설치 확인

kubectl get all -n argo-rollouts

 

kubectl 명령어로 argo-rollouts namespace에 설치된 리소스를 확인해보겠습니다.

 

 

 

 

 

 

AWS Managed Console에 접근하셔서 LB를 확인해보시면 위의 사진과 같이 ALB가 생성중임을 확인하실 수 있습니다.

ArgoRollouts CLI 설치

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

 

CLI를 통해 ArgoRollouts 리소스를 설정하기 위해 CLI도 설치합니다.

 

 

kubectl argo rollouts version

 

kubectl argo rollouts 명령어를 통해 version을 확인합니다.

 

 

 

ArgoRollouts Dashboard 접속

https://argorollouts.<자신의 도메인>/rollouts/

 

일정 시간이 지난 후 ALB가 생성이 완료되면 위의 url로 ArgoRollouts Dashboard에 접근이 가능해집니다.

 

 

(현재는 rollouts 관련 리소스가 없기 때문에 아무것도 안보입니다!)

 

 

 

ArgoRollouts 배포 실습

Canary 코드 확인

spec:
  replicas: 5
  strategy:
    canary:
      steps:
      - setWeight: 20
      - pause: {}
      - setWeight: 40
      - pause: {duration: 10}
      - setWeight: 60
      - pause: {duration: 10}
      - setWeight: 80
      - pause: {duration: 10}

 

Canary 배포 코드의 경우 spec.strategy에 canary를 적어줍니다. 그 후 step에 setWeight를 두어 단계별 가중치를 설정합니다.

즉, 20%(기존:80/신규:20) -> 40%(기존:60/신규:40) -> 10초 pause -> 60%(기존:40/신규:60) -> 10초 pause -> 80%(기존: 20/신규:80) -> 10초 pause로 점진적으로 가중치를 두어 완전히 배포될 수 있도록 하는 예제입니다.

 

예제 코드 배포

kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/rollout.yaml
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/service.yaml

 

위의 명령어를 통해 demo pod를 배포해보겠습니다.

 

배포 확인

kubectl get po

 

kubectl get 명령어를 통해 현재 배포된 Pod를 확인합니다.

 

rollouts-demo Pod가 5개로 잘 배포되어있는 것을 확인하실 수 있습니다.

 

ArgoRollouts Dashboard 접속

ArgoRollouts Dashboard에 접근한 후 namespace를 argocd로 변경합니다.

 

 

rollouts-demo라는 application이 생성된 것을 확인하실 수 있습니다.

 

신규 버전의 Pod 배포(Using UI)

 

해당 Application의 Container 탭에서 Image spec을 변경합니다. (argoproj/rollouts-demo:blue -> argoproj/rollouts-demo:yellow)

 

신규 버전의 Pod 배포(Using CLI)

kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow

 

kubectl argo rollouts set 명령어를 통해 배포합니다.

 

 

 

1단계를 진행 후 20%의 Pod만 변경된 후 pause 상태로 머물러있습니다. 첫번째 step에선 pause 상태의 시간을 정해두지 않아서 멈춰있게 되는데, 상단에 Promete / PromoteFull 버튼을 눌러 진행합니다.

 

 

 

Promote

 

Promote은 위의 영상처럼 설정해놓은 배포 전략의 다음 step으로 진행하는 기능입니다.

 

PromoteFull

 

PromoteFull은 위의 영상과 같이 남은 과정을 한번에 진행하는 기능입니다.

 

이렇게 ArgoRollouts으로 Canary 배포하는 방법에 대해 실습을 진행해보았습니다.

 


Reference

- https://argoproj.github.io/

- https://argoproj.github.io/cd/

- https://argoproj.github.io/argo-rollouts/