반응형
Canary 배포
이전 광부들이 광산에 들어갈 때 이 canary 새를 풀어봐 광산이 안전한지 위험도 테스트를 진행했다.
유래와 같이 Canary 배포는 새로운 애플리케이션 버전을 점진적으로 배포하여, 작은 사용자 그룹에게 먼저 제공한 뒤 안정성이 확인되면 전체로 확대하는 배포 방식이다. 이 방식은 배포 시 위험을 줄이고, 문제가 발생했을 때 신속히 롤백할 수 있다는 장점이 있다.
Canary 배포
- Canary 릴리즈: 새로운 버전의 애플리케이션을 소수의 Pod 또는 인스턴스에 배포합니다. 초기에는 전체 트래픽 중 일부만 새로운 버전에 전달한다.( EX. 회사 내부 인력, 베타 테스트 등..) header, cookie로 트래픽을 조절할 수 있어 베타테스트 등에 유용하다.
- 모니터링 및 검증: 새로운 버전이 소수의 사용자에게 제공되는 동안 시스템의 성능, 오류율, 메트릭 등을 모니터링하여 문제가 없는지 검증한다.
- 점진적 확대: 검증이 완료되고 안정성이 확인되면 Canary 버전으로 전환되는 트래픽 비율을 점진적으로 높입니다. 예를 들어, 처음에는 10%로 시작하여 점차 25%, 50%, 100%로 증가시킬 수 있습니다.
- 완료 또는 롤백: 모든 트래픽이 새로운 버전으로 전환되면 기존 버전은 종료된다.
이 또한 구버전/새버전에 대한 인프라를 모두 운용해야하여 비용적인 단점이 있다.
실습
- Rollout.yaml
기존 helm chart에서 strategy를 canary로 변경한다.
처음엔 20%만 트래픽을 보내다, 30초동안 대기 후 전체 트래픽을 신규로 보내도록 설정한다.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: {{ include "hellospring.name" . }}-rollout
labels:
app: {{ .Values.labels.app }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.labels.app }}
template:
metadata:
labels:
app: {{ .Values.labels.app }}
spec:
containers:
- name: {{ include "hellospring.name" . }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- name: http
containerPort: 8080
protocol: TCP
imagePullPolicy: {{ .Values.image.pullPolicy }}
strategy:
canary:
steps:
- setWeight: 20 # 첫 번째 배포 시 20%의 트래픽을 새 버전으로 전환
- pause: { duration: 30 } # 30초 동안 대기
- setWeight: 100 # 나머지 80%의 트래픽을 새 버전으로 전환
activeService: {{ include "hellospring.name" . }}-blue
previewService: {{ include "hellospring.name" . }}-green
autoPromotionEnabled: false
scaleDownDelaySeconds: 30
- Service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ include "hellospring.name" . }}-active
labels:
app: {{ .Values.labels.app }}
spec:
type: {{ .Values.service.type }}
ports:
- port: 3000
targetPort: 8080
selector:
app: {{ .Values.labels.app }}
---
# preview Service
apiVersion: v1
kind: Service
metadata:
name: {{ include "hellospring.name" . }}-canary
labels:
app: {{ .Values.labels.app }}
spec:
type: {{ .Values.service.type }}
ports:
- port: 3000
targetPort: 8080
selector:
app: {{ .Values.labels.app }}
- Ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "hellospring.name" . }}-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: {{ .Values.ingress.path }}
pathType: Prefix
backend:
service:
name: {{ include "hellospring.name" . }}-active
port:
number: {{ .Values.service.port }}
- canary배포에서도 배포 전에는 모두 같은 endpoint를 가지고 있는 것을 볼 수 있다.
- 신기한 것은, 내가 canary에 대한 ingress를 설정하지 않아도, canary ingress가 생성된다. 아직은 배포를 하지 않아서 연결된 service의 endpoint가 동일한 것을 알 수 있다.
- helm values에서 version을 변경하여 배포하면, canary pod가 점점 생기는 것을 볼 수 있다. service의 endpoint가 1개 생성되었다. ( 처음엔, 20%로 30s 동안 유지하는 것이니, replica가 5개 이므로 1개의 endpoint가 생긴 것을 볼 수 있다. )
- 브라우저를 무한 새로고침하면, v2.0와 v3.0(canary) 가 동시에 보인다.
- 먼저 생긴 pod가 생성된지 30s 가 지나면 canary pod 나머지 4개가 동시에 생긴다. 30s 이후 100% 트래픽을 canary로 보내기 위해서이다. 옆 ingress에 할당된 service에서, canary에 대한 endpoint가 늘어난 것을 볼 수 있다.
- 이후 나머지 active pod들은 terminate된다. 이때 active ingress의 endpoint는 canary endpoint를 바라보게 된다.
반응형
'사이드 프로젝트' 카테고리의 다른 글
[CI/CD 프로젝트] Ansible을 통한 인프라 관리의 자동화 (0) | 2024.11.20 |
---|---|
[CI/CD 프로젝트] Prometeus + Grafana 를 통한 모니터링 가시성 높이기 (1) | 2024.11.20 |
[CI/CD 프로젝트] ArgoRollout로 Blue/Green 배포하기 (1) | 2024.11.20 |
[CI/CD 프로젝트] ArgoCD를 통한 CD 구성 (2) | 2024.11.20 |
[CI/CD 프로젝트] GitAction을 통한 CI 구성 (0) | 2024.11.20 |