본문 바로가기
CSP (Cloud Service Provider)/GCP

GKE로 배포 관리하기 (2)Canary 배포

by BTC_yljo 2022. 5. 20.

안녕하세요 BTC Hallo 팀입니다. 이번 주에는 저번 주의 '지속적 배포'에 이어서 GKE로 배포 관리하는 방법 중 'Canary 배포'에 대해 이어서 진행해보도록 하겠습니다.

 

Canary 배포

프로덕션 환경에서 일부 사용자를 대상으로 새 배포를 테스트하려면 Canary 배포를 사용할 수 있다. Canary 배포를 사용하면 작은 규모의 일부 사용자에게만 변경 사항을 릴리스하여 새로운 릴리스와 관련된 위험을 완화할 수 있습니다.

Canary 배포 만들기

Canary 배포는 새 버전의 별도 배포와 함께 기존 안정화 배포 및 Canary 배포를 동시에 대상으로 삼는 서비스로 구성됩니다.

 

cat deployments/hello-canary.yaml

(출력 내용)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      labels:
        app: hello
        track: canary
        # 2.0.0 버전을 사용하여 서비스 선택기의 버전과 일치시킨다
        version: 2.0.0
    spec:
      containers:
        - name: hello
          image: kelseyhightower/hello:2.0.0
          ports:
            - name: http
              containerPort: 80
            - name: health
              containerPort: 81
...

Canary 배포 생성

kubectl create -f deployments/hello-canary.yaml

Canary 배포를 만들면 hello  hello-canary의 두 가지 배포가 생깁니다.

kubectl get deployments

hello 서비스에서 선택기는 프로덕션 배포 및 Canary 배포의 pod에 모두 맞는 app:hello 선택기를 사용하지만, Canary 배포가 포드 수가 더 적기 때문에 더 적은 수의 사용자에게 표시됩니다.

Canary 배포 확인하기

요청에서 제공되는 hello 버전을 확인할 수 있다.

curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version

이 명령어를 여러 번 실행하면, 일부 요청은 hello 1.0.0에서 제공하고 소규모 하위 집합(1/4=25%)은 2.0.0에서 제공함을 알 수 있습니다.

 

프로덕션 환경의 Canary 배포 - 세션 어피니티

이 실습의 사례에서는 Nginx 서비스로 전송된 모든 요청이 Canary 배포에서 처리될 가능성이 있었다. 어떤 사용자가 Canary 배포를 통해 서비스를 받지 못하도록 하려면 다른 접근 방식이 필요합니다. 예를 들어, 애플리케이션의 UI가 변경되어 특정 사용자에게 혼동을 주지 않으려는 경우가 있을 수 있다. 이와 같은 경우에는 해당 사용자를 한 배포 또는 다른 배포에 '고정'해야 합니다.

서비스와 함께 세션 어피티니를 만들면 동일한 사용자에게 항상 동일한 버전을 제공할 수 있습니다. 아래 예제에서 서비스는 이전과 동일하지만 새로운 sessionAffinity 필드가 추가되어 ClientIP로 설정됩니다. IP 주소가 동일한 모든 클라이언트는 동일한 버전의 hello 애플리케이션으로 요청을 보내게 됩니다.

kind: Service
apiVersion: v1
metadata:
  name: "hello"
spec:
  sessionAffinity: ClientIP
  selector:
    app: "hello"
  ports:
    - protocol: "TCP"
      port: 80
      targetPort: 80

댓글