-
Notifications
You must be signed in to change notification settings - Fork 1
4) Canary Deployment using Argo Rollouts
2022.04. 이장재 📧 cine0831@gmail.com 📂 https://github.com/jangjaelee 📒 http://www.awx.kr
Argo Rollouts를 사용하여 Canary 배포 설정과 내장된 Traffic Management 기능에서 지원하는 Ingress Controller 및 Service Mesh 중 하나인 Nginx Ingress를 통해 새 버전과 이전 버전사이에 트래픽 비율 조정을 통해 트래픽을 점진적으로 새 애플리케이션으로 이동하는 방법을 알아봅니다.
- kubectl command-line tool
- kustomize command-line tool
- argocd command-line tool
- Argo Rollouts Kubectl Plugin
- NGINX Ingress Controller
-
Argo CD - Declarative GitOps CD for Kubernetes
-
Rollout
resource를 Argo CD Application CRD(Custom Resource Definition)를 사용하여 배포하기 위해서는 Argo CD의 설치가 필요
-
Argo CD Application
resource를 사용하여 Rollout
resouce 배포하며, 이번 예제를 위해 *Argo Rollouts Demo Application*을 사용하겠습니다.
Demo Application에서는 Ingress의 API를 networking.k8s.io/v1beta1
을 사용있으며, Kubernetes v1.22 이후로 extensions/v1beta1
과 networking.k8s.io/v1beta1
은 더 이상 사용되지 않아 networking.k8s.io/v1
으로 마이그레이션 하여 사용했습니다.
🔗 https://github.com/jangjaelee/tutorials-argo-rollouts/tree/main/demo/canary
진행하기에 앞서 Argo CD에 로그인 합니다.
$ argo login argocd.awx.kr --grpc-web
Username: admin
Password:
'admin:login' logged in successfully
Context 'argocd.awx.kr' updated
Argo CD Application
resource를 사용하여 Rollout
resource를 배포 합니다.
$ cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: argo-rollouts-demo-canary
namespace: argocd
spec:
destination:
name: in-cluster
namespace: default
project: default
source:
path: demo/canary
repoURL: https://github.com/jangjaelee/tutorials-argo-rollouts.git
targetRevision: HEAD
syncPolicy: {}
EOF
application.argoproj.io/argo-rollouts-demo-canary created
$ argocd app list | egrep 'NAME|rollouts-demo-canary'
NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET
argo-rollouts-demo-canary default default OutOfSync Missing <none> <none> https://github.com/jangjaelee/tutorials-argo-rollouts.git demo/canary HEAD
Demo Application을 배포하고 Application의 상태를 확인하면 OutOfSync 상태로 아직 배포가 진행되지 않고 있습니다.
Sync를 진행하여 리소스들이 배포될 수 있게 합니다.
$ argocd app sync argo-rollouts-demo-canary
만약, Argo CD를 설치하지 않았거나 또는 사용하지 않는 다면 이 단계는 건너띄고 Step 1.2. using Kustomize
를 진행하시기 바랍니다.
Demo Application 저장소에서 파일들을 clone 합니다.
$ git clone https://github.com/jangjaelee/tutorials-argo-rollouts.git
$ cd tutorials-argo-rollouts/demo/canary
kustomize를 사용하여 Rollout
resource를 배포 합니다.
$ kustomize build . | kubectl apply -f -
service/canary-demo created
service/canary-demo-preview created
rollout.argoproj.io/canary-demo created
ingress.networking.k8s.io/canary-demo created
ingress.networking.k8s.io/canary-demo-preview created
만약, kustomize를 사용하지 않는다면 Manifest를 사용하면 됩니다.
$ kubectl apply -f canary-ingress.yaml -f canary-preview-ingress.yaml -f canary-preview-service.yaml -f canary-rollout.yaml -f canary-service.yaml
또는
$ for i in $(ls); do if [ "${i}" != "kustomization.yaml" ]; then kubectl apply -f ${i}; fi; done
kustomization.yaml
파일은 kustomize를 사용할 때 필요하므로 사용하지 않습니다.
필자는 애플리케이션 접속을 위한 canary-demo와 canary-demo-review Ingress
resource에서 canary-demo.awx.kr, canary-preview.awx.kr 호스트를 지정하여 사용하였습니다. 본인의 환경에 맞게 호스트를 변경하여 사용하시기 바랍니다.
-
canary-ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: canary-demo annotations: ingress.kubernetes.io/proxy-body-size: 100M ingress.kubernetes.io/app-root: / nginx.ingress.kubernetes.io/backend-protocol: HTTP spec: ingressClassName: nginx rules: - host: canary-demo.awx.kr http: paths: - path: / pathType: Prefix backend: service: name: canary-demo port: number: 80
-
canary-preview-ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: canary-demo-preview annotations: ingress.kubernetes.io/proxy-body-size: 100M ingress.kubernetes.io/app-root: / nginx.ingress.kubernetes.io/backend-protocol: HTTP spec: ingressClassName: nginx rules: - host: canary-preview.awx.kr http: paths: - path: / pathType: Prefix backend: service: name: canary-demo-preview port: number: 80
다음은 배포된 애플리케이션의 resources 입니다.
$ kubectl get all,ing,rollouts
NAME READY STATUS RESTARTS AGE
pod/canary-demo-6f8b8d584-dpfp6 1/1 Running 0 34s
pod/canary-demo-6f8b8d584-hn6h7 1/1 Running 0 34s
pod/canary-demo-6f8b8d584-ltthv 1/1 Running 0 34s
pod/canary-demo-6f8b8d584-rzmz4 1/1 Running 0 34s
pod/canary-demo-6f8b8d584-xppkk 1/1 Running 0 34s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/canary-demo ClusterIP 10.101.254.186 <none> 80/TCP 34s
service/canary-demo-preview ClusterIP 10.104.57.203 <none> 80/TCP 34s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 34d
NAME DESIRED CURRENT READY AGE
replicaset.apps/canary-demo-6f8b8d584 5 5 5 34s
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/canary-demo nginx canary-demo.awx.kr 192.168.1.181 80 34s
ingress.networking.k8s.io/canary-demo-preview nginx canary-preview.awx.kr 192.168.1.181 80 34s
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
rollout.argoproj.io/canary-demo 5 5 5 5 34s
Argo Rollouts Kubectl Plugin을 사용하면 release에 대한 세부정보와 시각적 표현을 트리 보기로 확인할 수 있습니다.
$ kubectl argo rollouts get rollout canary-demo -w
Name: canary-demo
Namespace: default
Status: ✔ Healthy
Strategy: Canary
Step: 8/8
SetWeight: 100
ActualWeight: 100
Images: argoproj/rollouts-demo:blue (stable)
Replicas:
Desired: 5
Current: 5
Updated: 5
Ready: 5
Available: 5
NAME KIND STATUS AGE INFO
⟳ canary-demo Rollout ✔ Healthy 6m14s
└──# revision:1
└──⧉ canary-demo-6f8b8d584 ReplicaSet ✔ Healthy 6m14s stable
├──□ canary-demo-6f8b8d584-qbzv9 Pod ✔ Running 6m14s ready:1/1
├──□ canary-demo-6f8b8d584-rbt6b Pod ✔ Running 6m14s ready:1/1
├──□ canary-demo-6f8b8d584-rtqtt Pod ✔ Running 6m14s ready:1/1
├──□ canary-demo-6f8b8d584-tww9q Pod ✔ Running 6m14s ready:1/1
└──□ canary-demo-6f8b8d584-vdkjr Pod ✔ Running 6m14s ready:1/1
Argo CD UI와 Argo Rollout UI에서도 배포된 resources와 Network Traffic이 Pod까지 어떻게 전달되는지 볼 수 있습니다.
- Argo CD UI 접속 화면
- Argo Rollouts UI 접속 화면
- Demo Application (Blue) 접속 화면
Demo Application을 업데이트 하면 Rollout이 어떻게 Canary 배포를 진행하는지 알아보겠습니다.
다음은 Rollout
resource에 명시한 canary strategy 이며, 4단계로 진행 됩니다.
strategy:
canary:
canaryService: canary-demo-preview
steps:
- setWeight: 20
- pause: {}
- setWeight: 40
- pause: {duration: 10}
- setWeight: 60
- pause: {duration: 10}
- setWeight: 80
- pause: {duration: 10}
-
strategy.canary.steps
의 첫번째setWeight: 20
필드지시에 따라 트래픽의 20%는 새 버전으로 리다이렉션 합니다.setWeight
필드는 Canary로 보내야 하는 트래픽의 비율을 나타냅니다. -
pause
구조체 지시에 따라 Rollout이 일시 중지되며, 관리자(또는 사용자)가 수동으로 해제를 하여야 다음 단계로 진행할 수 있습니다. 일시 중지 해제는 argo kubectl plugin의promote
명령을 사용하게 됩니다. - 세번째
setWeight: 40
필드지시에 따라 트래픽의 40%를 새 버전으로 리다이렉션 합니다. - Pause Duration 필드지시에 따라 10초간 일시 중지후 다음 단계로 자동으로 진행하게 됩니다. 유효한 시간 단위는 “s”, “m”, “h” 이며, 지정하지 않으면 기본값은 “s” 입니다.
- 다음으로 setWeight 필드 지시에 따라 60% 그리고 80%를 새 버전으로 리다이렉션 하게 됩니다.
- 마지막으로 지정하지 되어 있지 않지만 암시적 단계로 트래픽의 100%를 새 버전으로 리다이렉션하여 Canary Update를 종료합니다.
다음과 같이 컨테이너 이미지를 새 이미지 태그(blue에서 yellow로 변경)로 업데이트 해보겠습니다.
$ kubectl argo rollouts set image canary-demo "*=argoproj/rollouts-demo:yellow"
rollout "canary-demo" image updated
argo kubectl plugin을 사용하여 업데이트 상황을 시각적으로 확인 할 수 있습니다.
$ kubectl argo rollouts get rollout canary-demo -w
Name: canary-demo
Namespace: default
Status: ॥ Paused
Message: CanaryPauseStep
Strategy: Canary
Step: 1/8
SetWeight: 20
ActualWeight: 20
Images: argoproj/rollouts-demo:blue (stable)
argoproj/rollouts-demo:yellow (canary)
Replicas:
Desired: 5
Current: 5
Updated: 1
Ready: 5
Available: 5
NAME KIND STATUS AGE INFO
⟳ canary-demo Rollout ॥ Paused 8m51s
├──# revision:2
│ └──⧉ canary-demo-689684c976 ReplicaSet ✔ Healthy 19s canary
│ └──□ canary-demo-689684c976-c6947 Pod ✔ Running 19s ready:1/1
└──# revision:1
└──⧉ canary-demo-6f8b8d584 ReplicaSet ✔ Healthy 8m51s stable
├──□ canary-demo-6f8b8d584-qbzv9 Pod ✔ Running 8m51s ready:1/1
├──□ canary-demo-6f8b8d584-rbt6b Pod ✔ Running 8m51s ready:1/1
├──□ canary-demo-6f8b8d584-tww9q Pod ✔ Running 8m51s ready:1/1
└──□ canary-demo-6f8b8d584-vdkjr Pod ✔ Running 8m51s ready:1/1
canary-demo의 rollout이 revision: 2가 새로 생긴 것이 보이시죠?
strategy.canary.steps.setWeight: 20
필드지시에 따라 새 애플리케이션이 생성되고 트래픽의 20%는 새 버전으로 유입되게 됩니다.
새 애플리케이셔 Pod는 새 replicaset
resource에 생성이 되며, 트래픽의 분할은 metadata.labels
의 pod-template-hash
필드 지시어를 사용하여 기존 애플리케이션과 새 애플리케이션에 전달하게 됩니다.
Pod Template Hash
에 대해서는 다음에 자세하게 다루기로 하겠습니다.
$ kubectl get rollouts,replicaset
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
rollout.argoproj.io/canary-demo 5 5 1 5 9m
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/canary-demo-689684c976 1 1 1 3m canary-demo argoproj/rollouts-demo:yellow app=canary-demo,rollouts-pod-template-hash=689684c976
replicaset.apps/canary-demo-6f8b8d584 4 4 4 9m canary-demo argoproj/rollouts-demo:blue app=canary-demo,rollouts-pod-template-hash=6f8b8d584
- Argo Rollouts UI 접속 화면
- Argo CD UI 접속 화면
- canary-preview-demo 접속 화면
- canary-demo trafficWeight 20% 적용후 접속 화면
Weight 20% 적용후 일시 중단 되어 있는 현 상태를 Promote 명령어를 사용하여 new ReplicaSet을 stable 버전으로 승격 될수 있게 중단된 업데이트를 계속 진행합니다.
$ kubectl argo rollouts promote canary-demo
rollout 'canary-demo' promoted
모든 업데이트가 잘 완료 되었는지 확인합니다.
$ kubectl argo rollouts get rollout canary-demo -w
Name: canary-demo
Namespace: default
Status: ✔ Healthy
Strategy: Canary
Step: 8/8
SetWeight: 100
ActualWeight: 100
Images: argoproj/rollouts-demo:yellow (stable)
Replicas:
Desired: 5
Current: 5
Updated: 5
Ready: 5
Available: 5
NAME KIND STATUS AGE INFO
⟳ canary-demo Rollout ✔ Healthy 28m
├──# revision:2
│ └──⧉ canary-demo-689684c976 ReplicaSet ✔ Healthy 19m stable
│ ├──□ canary-demo-689684c976-c6947 Pod ✔ Running 19m ready:1/1
│ ├──□ canary-demo-689684c976-f5zkc Pod ✔ Running 60s ready:1/1
│ ├──□ canary-demo-689684c976-hzgmv Pod ✔ Running 47s ready:1/1
│ ├──□ canary-demo-689684c976-6ffxx Pod ✔ Running 34s ready:1/1
│ └──□ canary-demo-689684c976-97q4d Pod ✔ Running 21s ready:1/1
└──# revision:1
└──⧉ canary-demo-6f8b8d584 ReplicaSet • ScaledDown 28m
canary-demo Rollout이 revision: 2 새 버전의 ReplicaSet으로 모두 업데이트 되면서 기존의 ReplicaSet은 ScaleDown 상태로 변경되었습니다. ScaleDown에 대해서는 다루지 않으며 아래의 링크에서 확인하시기 바랍니다.
🔗 https://argoproj.github.io/argo-rollouts/features/scaledown-aborted-rs/
Argo CD UI와 Argo Rollouts UI에서 Pod가 new ReplicaSet으로 업데이트 되는 상황을 시각화를 통해 확인할 수 있습니다.
- Argo CD UI
- Argo Rollouts UI
- canary-demo trafficWeight 20 ~ 80% 적용후 접속화면
- new Demo Application (yellow) 접속 화면
지금까지 Argo Rollouts을 사용한 Canary Deployment에 대해서 알아 보았습니다.
Rollout resource에 대한 추가적인 옵션과 설명은 다음 링크에서 확인하여 고급 배포 전략을 구현해보시기 바랍니다.
- Website
- GitHub
- Artifact Hub
- Slack
END