ARGO CD Canary/bluegreen 배포 적용하기

이언철·2023년 3월 3일
0

GitOps

목록 보기
2/2
post-thumbnail

Goal

application 무중단 배포 방식은 다음과 같다.

  • rolling
  • blue/green
  • canary

쿠버네티스에서 지원하는 기본적인 방식은 rolling 업데이트 방식으로 새로운 pod이 정상 Running되면 기존의 pod을 evicted(closed) 하는 방식으로 적용된다.

서비스의 목적에 따라 원하는 배포 방식 제공을 위해 ArgoCD에서 공식적으로 지원하는 Progressive delivery Controller 기능을 사용하고자 한다.


Proposed Method

"Argo Rollouts"

Argo Rollouts installation

  • argo-rollouts는 별도의 네임스페이스로 설치하는 것이 기본적인 방법이나 편의상 default 네임스페이스에 설치하고자 한다.

    kubectl apply -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
  • 효과적인 IaC 관리를 위해 해당 yaml파일을 다운로드하여 코드를 분할해 manifest repo에서 .yaml로 관리한다.

    • crd.yaml
    • deployment.yaml
    • rbac.yaml
    • secret.yaml
    • service.yaml

Getting Started

  • rolling update 방식을 제외한 blue/green, canary 배포를 위한 rollout yaml 파일을 작성한다.

서비스 pod 추가 설정

  • 활동성 확보를 위한 설정 중 Sample에서는 정상 실행여부만 확인하면 되기에 startupProbe로 설정한다.
  • tolerations과 affinity는 클러스터에서 설정한 운영을 위한 worker node group으로 지정한다.

pod의 배포를 위한 kind를 Deployment가 아닌 Rollout로 설정한다.

bluegreen-rollout.yaml

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: backend-bluegreen
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend-bluegreen
  template:
    metadata:
      labels:
        app: backend-bluegreen
    spec:
      containers:
        - name: backend-bluegreen
          image: XXXXXXXXXXXX.dkr.ecr.{AWS-REGION}.amazonaws.com/backend:latest
          ports:
            - name: liveness-port
              containerPort: 8080
          resources:
            limits:
              cpu: 1
              memory: 256Mi
            requests:
              cpu: 1
			  memory: 256Mi
          startupProbe:
            httpGet:
              path: /actuator/health
              port: liveness-port
            failureThreshold: 18
            periodSeconds: 10
      tolerations:
        - effect: NoSchedule
          key: subnettype
          operator: Equal
          value: private
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: subnettype
                    operator: In
                    values:
                      - private
  strategy:
    blueGreen:
      autoPromotionEnabled: false
      activeService: backend-active
      previewService: backend-preview

---
apiVersion: v1
kind: Service
metadata:
  name: backend-active
  labels:
    app: backend-active
spec:
  selector:
    app: backend-bluegreen
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: backend-preview
  labels:
    app: backend-preview
spec:
  selector:
    app: backend-bluegreen
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

canary-rollout.yaml

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: backend-canary
spec:
  replicas: 10
  selector:
    matchLabels:
      app: backend-canary
  template:
    metadata:
      labels:
        app: backend-canary
    spec:
      containers:
        - name: backend-canary
          image: XXXXXXXXXXXX.dkr.ecr.{AWS-REGION}.amazonaws.com/backend:latest
          ports:
            - name: liveness-port
              containerPort: 8080
          resources:
            limits:
              cpu: 1
              memory: 256Mi
            requests:
              cpu: 1
              memory: 256Mi
          startupProbe:
            httpGet:
              path: /actuator/health
              port: liveness-port
            failureThreshold: 18
            periodSeconds: 10
      tolerations:
        - effect: NoSchedule
          key: subnettype
          operator: Equal
          value: private
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: subnettype
                    operator: In
                    values:
                      - private
  strategy:
    canary:
      maxSurge: "30%"
      maxUnavailable: 0
      steps:
        - setWeight: 30
        - pause: {}

이후 latest 버전 변경 감지를 위해 일전에 적용한 ArgoCD + kustomize 적용하기 (+ argocd-image-updater)를 참고하여 변경된 sha256를 감지하도록 kustomize화 하도록 한다.

버전을 업데이트했다면 다음 명령어를 통해 canary promote를 진행 할 수 있다.

kubectl argo rollouts promote backend-canary

해당 명령어 실행을 통해 업데이트된 배포본을 30% surge로 배포되어 운영되던 canary에서 남은 70%도 업데이트된 배포본으로 배포되도록 할 수 있다.

Result & Analysis

  • 샘플을 통해 argocd + kustomize 환경에서 argo rollouts controller를 활용한 rolling 외의 추가적인 배포방식을 사용할 수 있다.

Conclusion

  • argo rollouts controller만 설치하고 Rollout kind YAML만 생성하면 되는 간단한 작업이지만 서비스의 명확한 목적성에 맞추어 적절한 배포방식을 선정 할 필요가 있다.
  • 새로운 배포방식을 적용한 서비스의 D/W/M AU를 고려하여 적절한 weight를 설정하여 트래픽을 관리할 필요가 있다.
    • 이를 위한 Distributed tracing이 되어 있다면 좀 더 안정적이고 효율적인 이슈 대응 체계를 가져올 수 있을 것이다.
profile
Soomgo, DevOps

0개의 댓글