[GitOps] Argo Rollout 컨트롤러 기반 Canary 배포

2023. 1. 22. 16:07[ DevOps ]/[ CI-CD ]

순서

1. Argo Rollout이란

 

2. Argo Rollout 플러그인 설치

1) Argo Rollout 설치 스크립트 작성

2) 실행 확인

 

3. Argo Rollout으로 배포

1) Rollout(Canary) 배포 설정

2) Rollout Object 배포 및 확인

3) 애플리케이션 신규 배포 및 Canary 업데이트 확인

 

 


 

Argo Rollout이란

Argo Rollout은 Canary, Blue-Grean와 같은 고급 배포 기능을 위한 Argo의 CRD 및 Kubernetes 컨트롤러이다. 이를 통해 Kubernetes에선 제공되지 않는 다양한 배포 기법을 적용하고 자동화할 수 있다.

 

Canary 업데이트란

cf. Canary 배포에 대한 포스팅: https://jh-labs.tistory.com/549

 

 

Canary 업데이트란 기존 버전을 유지한 채로 일부 버전만 신규 버전으로 올려서 전체적으로 문제가 없는지 모니터링 및 배포하는 방법이다. k8s 자체적으로는 Canary 업데이트를 '자동화'할 수 있는 방식이 제공되지 않는다. 따라서 위와 같이 Manifest를 나눠서 작성하여 '수동'으로 Canary 배포를 진행하거나 Argo Rollout 컨트롤러를 사용하여 이를 자동화할 수 있다.

 

수동으로 진행할 경우, 예를 들어 신규 버전의 replicas를 작게 주어 시작하고, 모니터링을 통해 문제가 없다면 신규 버전의 replicas를 추가해 나가면 된다. 이때 중요한 것은 두 버전이 하나의 Service에 묶이도록 하는 것인데, 보통 selector로 공통된 label을 등록해 주면 된다.

 

cf. Argo Rollout 기반 Canary 배포와 k8s Deployment의 Rolling Update 차이점: https://jh-labs.tistory.com/688

 


 

Argo Rollout 플러그인 설치

필자는 Argo Rollout 설치에 대한 Manifest나 script 파일은 GitHub에서 관리중이다.

 

Argo Rollout 플러그인 설치 script 파일

- setup-argo-rollout.sh  (Argo Rollout 설치 메뉴얼 참고)

# 1. 네임스페이스 생성
kubectl create namespace argo-rollouts

# 2. Argo Rollout 설치
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

# 3. Kubectl Plugin 설치(linux)
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64

chmod +x ./kubectl-argo-rollouts-linux-amd64

sudo mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts

# 4. Argo Rollout Dashboard 기동 (http://localhost:3100)
kubectl argo rollouts dashboard

* For Linux dist, replace darwin with linux

 

cf. Argo Rollout 공식문서의 설치가이드를 보면 두 가지 방식의 Argo Rollout 설치를 제안하고 있다.

- 표준 설치: https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

- 네임스페이스에서만 설치: https://github.com/argoproj/argo-rollouts/blob/master/manifests/namespace-install.yaml

(동일한 클러스터의 서로 다른 네임스페이스에서 여러 Argo Rollout 컨트롤러 인스턴스를 실행할 때 사용)

 

 

 

- 설치 실행

// GitOps Management repo pull 과정 생략

chmod +x setup-argo-rollout.sh && ./setup-argo-rollout.sh

// INFO[0000] Argo Rollouts Dashboard is now available at http://localhost:3100/rollouts

Argo Rollout 대시보드(Web UI)는 3100 포트로 접속 가능하다.

 

 

- Argo Rollout 설치 확인

 

 

 

- 플러그인 설치 확인

kubectl argo rollouts -h

Argo Rollout은 kubectl의 플러그인으로 설치된다.

 

 

 


 

 

Argo Rollout으로 배포

1. Rollout(Canary) 배포 설정

1) Application Manifest

Rollout 오브젝트를 배포하기 위해 역시 ArgoCD가 관리하는 Application이 정의되어야 한다. 기존 k8s의 Deployment 컨트롤러로 배포할 경우, Application의 source가 deployment와 service의 manifest가 위치한 경로였지만, 지금은 k8s의 Deployment 컨트롤러 대신에 Rollout 컨트롤러를 사용하는 것이기 때문에 지금 작성할 Application Manifest의 source는 Rollout과 service의 manifest가 위치한 경로가 되어야 한다.

 

- application-rollout.yaml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: offer-be
  namespace: argocd
spec:
  destination:
    namespace: offer-be
    server: https://kubernetes.default.svc
  project: default
  source:
    path: services/offer-be-rollout
    repoURL: git@github.com:price-offer/application-manifests.git
    targetRevision: HEAD
  syncPolicy:
    automated:
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

 

 

2) Rollout Manifest

- rollout.yaml

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: offer-be
spec:
  replicas: 3
  strategy:
    canary:
      steps:
      - setWeight: 33
      - pause: {duration: 10}
      - setWeight: 66
      - pause: {duration: 10}
      - setWeight: 100
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: offer-be
  template:
    metadata:
      labels:
        app: offer-be
    spec:
      containers:
      - name: offer-be
        image: goharrm/offer-dev:old
        ports:
        - name: http
          containerPort: 7070
          protocol: TCP
        resources:
          requests:
            memory: 32Mi
            cpu: 5m

수동적인 방식의 Canary 업데이트에서 Argo Rollout을 사용하면 Canary 업데이트를 자동화할 수 있다. 

 

 

[Rollout 컨트롤러 Manifest 분석]

1) Argo Rollout의 Manifest kind는 'Rollout'이다.

 

2) spec의 strategy에는 Rollout 컨트롤러가 Pod를 배포할 배포 방식을 정의한다. canary 외에도 blueGrean이 제공된다.

 

3) setWeight를 통해 트래픽에 가중치를 설정하며 duration에서 가중치 변경을 줄 시간(초)을 설정한다. 즉, 위 Rollout의 경우 10초마다 트래픽 가중치를 33에서 66, 그 후 100으로 증가시키면서 신규 버전(canary)에 대한 트래픽을 점진적으로 증가시키는 것이다. Rollout이 초기 실행되면 가장 처음에는 구 버전이 80% 트래픽을 가져가고 신규 버전이 20% 트래픽을 가진다. 참고로 duration의 단위의 기본은 s (초)이다. 이 외에도 m(분), h(시간)이 제공된다. (ex. duration: 5m)

 

6) template.spec.containers.image에 등록된 컨테이너 이미지 태그 변경을 통해 Rollout 컨트롤러가 구동된다.(신규 Canary 배포가 진행된다.) GitOps 기반으로 tag 변경을 자동화하려면 Jenkins와 같은 CI 툴에서 신규 버전에 대한 태그를 자동으로 생성하고 Rollout Manifest가 정의된 레포지토리 상에서 이를 변경해 주면 된다. (cf. Jenkins 연동 및 Rollout Manifest의 컨테이너 이미지 태그 변경 자동화: https://jh-labs.tistory.com/673)

 

 

 

2) Service(NodePort) Manifest

Service는 기존 k8s Deployment를 사용했을 때의 서비스와 같은 서비스를 사용한다. Canary 배포가 정상적으로 동작하는지 확인하기 위해 기존 Application(k8s Deployment, k8s Service)는 중지시켰다.

 

- service.yaml

apiVersion: v1
kind: Service
metadata:
  name: offer-be
spec:
  type: NodePort
  ports:
    - name: http
      port: 7070
      targetPort: 7070
      protocol: TCP
      nodePort: 32667
  selector:
    app: offer-be
  externalTrafficPolicy: Cluster
  sessionAffinity: None

 

 

 

2. Rollout Object 배포 및 확인

1) Application 배포

kubectl apply -f application-rollout.yaml

 

- 배포 확인

replicas를 3으로 설정한 Pod가 Rollout 컨트롤러에 의해 정상 실행되었다.

 

 

- Rollout 목록 확인

kubectl argo rollouts list rollout -n offer-be

 

 

- Rollout 상세 확인

kubectl argo rollouts get rollout offer-be -n offer-be

 

Rollout 컨트롤러에 대한 상세정보를 확인할 수 있다. 현재 Healthy 상태이며 배포 전략은 Canary이다. 그리고 step은 5단계로 되어 있으며 현재 상태의 weight는 100이다.

 

cf. 대시보드에서 UI 상으로 확인하려면 http 3100번 포트로 접속하여 네임스페이스를 변경하면 확인 가능하다.

 

 

 

3. 애플리케이션 신규 배포 및 확인

1) Rollout Manifest 변경 발생

  . . .
  
  template:
    metadata:
      labels:
        app: offer-be
    spec:
      containers:
      - name: offer-be
        image: goharrm/offer-dev:latest
        ports:
 
 . . .

기존 컨테이너 이미지 태그를 old에서 latest로 변경하고 GIt에 커밋, 푸시를 발생시킨다. 그리고 아래와 같이 Rollout이 실시간으로 변경되는 현황을 확인한다.

 

cf. CI 툴 연동 및 컨테이너 이미지 태그 생성 자동화: https://jh-labs.tistory.com/676

 

 

 

2) Rollout 상태 실시간 확인

kubectl argo rollouts get rollout offer-be -n offer-be --watch

# 출력 로그를 쌓지 않고 실시간 확인
# watch kubectl argo rollouts get rollout offer-be -n offer-be

 

 

 

 

 

위와 같이 Pod가 하나씩 업데이트되면서 최종적으로 모두 latest 태그를 가진 컨테이너로 변경되었음을 확인할 수 있다. 즉, Argo Rollout을 사용하면 GitOps를 기반으로 Git 상에서 커밋을 통해 빠르게 서비스를 업그레이드할 수 있게 된다.

 

 

 

 

 

 

Reference

- Argo Docs, https://argo-cd.readthedocs.io/en/stable/

- Argo Rollout Docs, https://argo-rollouts.readthedocs.io/en/stable/

- Argo Rollout Docs(install), https://argoproj.github.io/argo-rollouts/installation/

- Argo Rollout GitHub, https://github.com/argoproj/argo-rollouts/tree/master/manifests

- Argo Rollout Manifest format, https://argoproj.github.io/argo-rollouts/features/specification/