본문 바로가기
WIKI 기술 지식 베이스

KEDA ScaledObjects로 카나리아 분석

원문 보기 위키 갱신

이 가이드에서는 Flagger를 KEDA ScaledObjects와 함께 사용해 Canary 분석 실행 중 워크로드를 자동 스케일링하는 방법을 보여드립니다. 이 튜토리얼에서는 Kubernetes 프로바이더와 블루/그린 배포 전략을 사용하지만, 어떤 배포 전략이든 지원되는 프로바이더와 조합해 사용할 수 있습니다.

출처: 문서

본문

이 가이드에서는 Flagger를 KEDA ScaledObjects와 함께 사용해 Canary 분석 실행 중 워크로드를 자동 스케일링하는 방법을 보여드립니다. 이 튜토리얼에서는 블루/그린 배포 전략과 Kubernetes 프로바이더를 사용하겠지만, 어떤 배포 전략이든 지원되는 프로바이더와 조합해 사용할 수 있습니다.

사전 요구사항 (Prerequisites)

Flagger는 Kubernetes 클러스터 v1.16 이상이 필요합니다. 이 튜토리얼에서는 KEDA 2.7.1 이상이 필요합니다.

KEDA를 설치합니다:

helm repo add kedacore https://kedacore.github.io/charts
kubectl create namespace keda
helm install keda kedacore/keda --namespace keda

Flagger를 설치합니다:

helm repo add flagger https://flagger.app

kubectl create namespace flagger
helm upgrade -i flagger flagger/flagger \
--namespace flagger \
--set prometheus.install=true \
--set meshProvider=kubernetes

부트스트랩 (Bootstrap)

Flagger는 Kubernetes deployment와 그 deployment를 대상으로 하는 KEDA ScaledObject를 받습니다. 그런 다음 일련의 오브젝트(Kubernetes deployments, ClusterIP services, 그리고 생성된 Deployment를 대상으로 하는 또 다른 KEDA ScaledObject)를 만듭니다. 이 오브젝트들은 메시 내부에서 애플리케이션을 노출하고 Canary 분석과 블루/그린 승격을 구동합니다.

테스트 네임스페이스를 만듭니다:

kubectl create ns test

podinfo라는 이름의 deployment를 만듭니다:

kubectl apply -n test -f https://raw.githubusercontent.com/fluxcd/flagger/main/kustomize/podinfo/deployment.yaml

분석 중 트래픽을 생성할 부하 테스트 서비스를 배포합니다:

kubectl apply -k https://github.com/fluxcd/flagger//kustomize/tester?ref=main

podinfo 배포를 대상으로 하고 Prometheus를 트리거로 사용하는 ScaledObject를 만듭니다:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: podinfo-so
  namespace: test
spec:
  scaleTargetRef:
    name: podinfo
  pollingInterval: 10
  cooldownPeriod: 20
  minReplicaCount: 1
  maxReplicaCount: 3
  triggers:
  - type: prometheus
    metadata:
      name: prom-trigger
      serverAddress: http://flagger-prometheus.flagger:9090
      metricName: http_requests_total
      query: sum(rate(http_requests_total{ app="podinfo" }[30s]))
      threshold: '5'

podinfo 배포용 canary 커스텀 리소스를 만듭니다:

apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  provider: kubernetes
  # deployment reference
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  # Scaler reference
  autoscalerRef:
    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    # ScaledObject targeting the canary deployment
    name: podinfo-so
    # Mapping between trigger names and the related query to use for the generated 
    # ScaledObject targeting the primary deployment. (Optional)
    primaryScalerQueries:
      prom-trigger: sum(rate(http_requests_total{ app="podinfo-primary" }[30s]))
    # Overriding replica scaling configuration for the generated ScaledObject
    # targeting the primary deployment. (Optional)
    primaryScalerReplicas:
      minReplicas: 2
      maxReplicas: 5
  # the maximum time in seconds for the canary deployment
  # to make progress before rollback (default 600s)
  progressDeadlineSeconds: 60
  service:
    port: 80
    targetPort: 9898
    name: podinfo-svc
    portDiscovery: true
  analysis:
    # schedule interval (default 60s)
    interval: 15s
    # max number of failed checks before rollback
    threshold: 5
    # number of checks to run before promotion
    iterations: 5
    # Prometheus checks based on 
    # http_request_duration_seconds histogram
    metrics:
      - name: request-success-rate
        interval: 1m
        thresholdRange:
          min: 99
      - name: request-duration
        interval: 30s
        thresholdRange:
          max: 500
    # load testing hooks
    webhooks:
      - name: load-test
        url: http://flagger-loadtester.test/
        timeout: 5s
        metadata:
          type: cmd
          cmd: "hey -z 2m -q 20 -c 2 http://podinfo-svc-canary.test/"

위 리소스를 podinfo-canary.yaml로 저장한 뒤 적용합니다:

kubectl apply -f ./podinfo-canary.yaml

몇 초 후 Flagger가 canary 오브젝트를 생성합니다:

# applied
deployment.apps/podinfo
scaledobject.keda.sh/podinfo-so
canary.flagger.app/podinfo

# generated
deployment.apps/podinfo-primary
horizontalpodautoscaler.autoscaling/podinfo-primary
service/podinfo
service/podinfo-canary
service/podinfo-primary
scaledobject.keda.sh/podinfo-so-primary

canary 배포용 ScaledObject는 .spec.autoscalerRef로 참조합니다. Flagger는 이를 사용해 primary 배포를 스케일링할 ScaledObject를 생성합니다. 기본적으로 Flagger는 모든 트리거에 대해 .spec.targetRef.Name과 {.spec.targetRef.Name}-canary의 모든 언급을 {.spec.targetRef.Name}-primary로 바꿔 primary ScaledObject에 사용할 쿼리를 추측하려 시도합니다. 예를 들어 ScaledObject의 트리거 쿼리가 sum(rate(http_requests_total{ app="podinfo" }[30s])) 또는 sum(rate(http_requests_total{ app="podinfo-primary" }[30s]))로 정의되어 있다면, primary ScaledObject는 sum(rate(http_requests_total{ app="podinfo-primary" }[30s]))로 정의된 쿼리를 가진 동일한 트리거를 갖게 됩니다.

생성된 쿼리가 요구 사항을 충족하지 않는다면 .spec.autoscalerRef.primaryScalerQueries로 primary 배포 자동 스케일링용 쿼리를 명시적으로 지정할 수 있으며, 이를 통해 각 트리거별 쿼리를 정의할 수 있습니다. ScaledObject의 .spec.triggers[@].name은 비어 있으면 안 됩니다. Flagger가 각 트리거를 고유하게 식별하는 데 필요하기 때문입니다.

canary와 primary 배포 ScaledObject 사이에 다른 스케일링 복제본 구성을 원할 경우 .spec.autoscalerRef.primaryScalerReplicas를 사용해 생성되는 primary ScaledObject의 값을 재정의할 수 있습니다.

부트스트랩 후 podinfo 배포는 0으로 스케일되고 podinfo.test로 가는 트래픽은 primary 파드로 라우팅됩니다. podinfo 배포를 0 복제본으로 유지하고 자동 스케일링을 일시 중지하기 위해 Flagger는 ScaledObject에 autoscaling.keda.sh/paused-replicas: 0 애노테이션을 추가합니다. 카나리아 분석 중에는 이 애노테이션이 제거되어 podinfo 배포의 자동 스케일링이 활성화됩니다. podinfo-canary.test 주소로 canary 파드를 직접 대상으로 삼을 수 있습니다. 카나리아 분석이 시작되면 Flagger는 트래픽을 canary로 라우팅하기 전에 pre-rollout 웹훅을 호출합니다. 블루/그린 배포는 매 15초마다 HTTP 메트릭과 롤아웃 훅을 검증하면서 5회 반복으로 실행됩니다.

자동 블루/그린 승격 (Automated Blue/Green promotion)

컨테이너 이미지를 업데이트해 배포를 트리거합니다:

kubectl -n test set image deployment/podinfo \
podinfod=ghcr.io/stefanprodan/podinfo:6.0.1

Flagger는 배포 리비전이 변경되었음을 감지하고 새 롤아웃을 시작합니다:

kubectl -n test describe canary/podinfo

Events:

New revision detected podinfo.test
Waiting for podinfo.test rollout to finish: 0 of 1 updated replicas are available
Pre-rollout check acceptance-test passed
Advance podinfo.test canary iteration 1/10
Advance podinfo.test canary iteration 2/10
Advance podinfo.test canary iteration 3/10
Advance podinfo.test canary iteration 4/10
Advance podinfo.test canary iteration 5/10
Advance podinfo.test canary iteration 6/10
Advance podinfo.test canary iteration 7/10
Advance podinfo.test canary iteration 8/10
Advance podinfo.test canary iteration 9/10
Advance podinfo.test canary iteration 10/10
Copying podinfo.test template spec to podinfo-primary.test
Waiting for podinfo-primary.test rollout to finish: 1 of 2 updated replicas are available
Promotion completed! Scaling down podinfo.test

참고 카나리아 분석 중에 배포에 새 변경 사항을 적용하면 Flagger가 분석을 다시 시작합니다.

모든 canary는 다음과 같이 모니터링할 수 있습니다:

watch kubectl get canaries --all-namespaces

NAMESPACE   NAME      STATUS        WEIGHT   LASTTRANSITIONTIME
test        podinfo   Progressing   100      2019-06-16T14:05:07Z

배포의 스케일링은 다음과 같이 모니터링할 수 있습니다:

watch kubectl -n test get deploy podinfo
NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
flagger-loadtester   1/1     1            1           4m21s
podinfo              3/3     3            3           4m28s
podinfo-primary      3/3     3            3           3m14s

Flagger가 ScaledObject의 애노테이션을 편집하는 모습은 다음과 같이 모니터링할 수 있습니다:

watch "kubectl get -n test scaledobjects podinfo-so -o=jsonpath='{.metadata.annotations}'"

더 알아보기 (Learn more)