일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Pulumi
- knative
- blue/green
- xdp
- CANARY
- Kubernetes 인증
- Kubernetes
- serving
- mlops
- gitops
- nginx ingress
- CI/CD
- Litmus
- argocd
- Model Serving
- Argo
- 카오스 엔지니어링
- operator
- Kopf
- Continuous Deployment
- opentelemetry
- keda
- eBPF
- seldon core
- opensearch
- MLflow
- tekton
- kubernetes operator
- Kubeflow
- 오퍼레이터
- Today
- Total
Kubernetes 이야기
Argo rollout을 통한 CD (Continuous Deployment) 구축하기 (1) - Canary 배포 본문
Argo rollout을 통한 CD (Continuous Deployment) 구축하기 (1) - Canary 배포
kmaster 2022. 2. 25. 22:37
Argo Rollout 이란
argo rollout은 Kubernetes에 Blue/Green, Canary 등 배포를 지원하기 위한 Kubernetes controller 와 CRD의 집합체이다.
argo rollout은 Ingress Controller, Service Mesh 와 통합되어 업데이트 중에 트랙픽을 새 버전으로 전환시킬 수 있다.
또한 점진적인 배포 조건을 메트릭 쿼리를 사용하여 자동화된 배포/롤백을 구축할 수 있다.
주요기능
- Blue/Green 배포
- Canary 배포
- 자동화된 롤백 및 배포
- 맞춤형 메트릭 쿼리를 이용한 점진적 배포
- Ingress Controller 통합 : Nginx, ALB
- Service Mesh 통합 : Istio, Linkerd, SMI
- 메트릭 공급자 통합 : Prometheus, Graphite, Datadog, Kubernetes Jobs
설치
# kubectl create namespace argo-rollouts
# kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
kubectl 플러그인 설치
kubectl 플러그인은 선택 사항이지만 kubect cli 에서 롤아웃을 관리하고 시각화하는데 편리한 플러그인이다.
# curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v1.2.0-rc2/kubectl-argo-rollouts-linux-amd64
# chmod +x ./kubectl-argo-rollouts-linux-amd64
# mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
# kubectl argo rollouts version
kubectl-argo-rollouts: v1.2.0-rc2+7b69058
BuildDate: 2022-02-24T22:32:47Z
GitCommit: 7b690580f69fd491f40c15b3ff4031f13bdae332
GitTreeState: clean
GoVersion: go1.17.6
Compiler: gc
Platform: linux/amd64
시작하기
argo rollout은 다양한 트랙픽 라우팅 솔루션들 ( Nginx, Istio, ALB 등 ) 과 통합된다. 이번에는 Nginx Ingress Controller 와 Canary 배포 연동되는 방법을 테스트해보자.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-demo
spec:
replicas: 1
strategy:
canary:
canaryService: hello-v2
stableService: hello-v1
trafficRouting:
nginx:
stableIngress: prod-ingress
steps:
- setWeight: 5
- pause: {}
revisionHistoryLimit: 2
selector:
matchLabels:
app: rollouts-demo
template:
metadata:
labels:
app: rollouts-demo
spec:
containers:
- name: rollouts-demo
image: ghcr.io/kmaster8/hello:v1
ports:
- name: http
containerPort: 5000
protocol: TCP
resources:
requests:
memory: 32Mi
cpu: 5m
이제 실제 hello-v1 서비스를 위한 Ingress를 생성해 보자.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prod-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: test.prod.10.60.200.121.sslip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-v1
port:
number: 5000
이제 service를 생성해 보자.
apiVersion: v1
kind: Service
metadata:
name: hello-v1
spec:
type: ClusterIP
selector:
app: rollouts-demo
ports:
- protocol: TCP
port: 5000
targetPort: 5000
---
apiVersion: v1
kind: Service
metadata:
name: hello-v2
spec:
type: ClusterIP
selector:
app: rollouts-demo
ports:
- protocol: TCP
port: 5000
targetPort: 5000
배포된 상태를 확인해 보면 아래와 같다.
# kubectl get ro -n test
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
rollouts-demo 1 1 1 1 59s
# kubectl get svc -n test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-v1 ClusterIP 10.111.83.68 <none> 5000/TCP 56s
hello-v2 ClusterIP 10.97.143.51 <none> 5000/TCP 56s
# kubectl get ing -n test
NAME CLASS HOSTS ADDRESS PORTS AGE
prod-ingress <none> test.prod.10.60.200.121.sslip.io 10.109.32.60 80 62s
rollouts-demo-prod-ingress-canary <none> test.prod.10.60.200.121.sslip.io 80 49s
여기서 ingress를 확인해야 한다. prod-ingress라는 이름으로 한개를 생성했지만, rollout-demo-prod-ingress-canary라는 Canary ingress controller가 자동으로 복제된다. 이 ingress는 카나리아 트래픽 분할 역활을 하는 ingress 이다. 이 ingress의 이름 규칙은 <ROLLOUT-NAME>-<INGRESS-NAME>-canary 라는 이름으로 생성된다.
rollout-demo-prod-ingress-canary의 상세정보를 보면 아래와 같다.
k describe ing -n test rollouts-demo-prod-ingress-canary
Name: rollouts-demo-prod-ingress-canary
Namespace: test
Address: 10.109.32.60
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
test.prod.10.60.200.121.sslip.io
/ hello-v2:5000 (172.32.139.179:5000)
Annotations: kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: true
nginx.ingress.kubernetes.io/canary-weight: 0
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 21m (x2 over 22m) nginx-ingress-controller Scheduled for sync
Normal Sync 21m (x2 over 22m) nginx-ingress-controller Scheduled for sync
Normal Sync 21m (x2 over 22m) nginx-ingress-controller Scheduled for sync
위와 같이 실제 호출되는 domain ( http://test.prod.10.60.200.121.sslip.io/ )은 prod-ingress와 동일하지만 canary-weight: 0으로 설정됨에 따라 해당 ingress는 실제 호출 시 연결되지 못한다.
# kubectl argo rollouts get rollout rollouts-demo -n test
Name: rollouts-demo
Namespace: test
Status: ✔ Healthy
Strategy: Canary
Step: 2/2
SetWeight: 100
ActualWeight: 100
Images: ghcr.io/kmaster8/hello:v1 (stable)
Replicas:
Desired: 1
Current: 1
Updated: 1
Ready: 1
Available: 1
NAME KIND STATUS AGE INFO
⟳ rollouts-demo Rollout ✔ Healthy 20m
└──# revision:1
└──⧉ rollouts-demo-6c75c64f5 ReplicaSet ✔ Healthy 20m stable
└──□ rollouts-demo-6c75c64f5-ltm7c Pod ✔ Running 20m ready:1/1
우선 v1 의 앱을 브라우저 통해서 호출해보자.
자, 이제 v2 앱을 배포해 보자.
# kubectl argo rollouts set image rollouts-demo rollouts-demo=ghcr.io/kmaster8/hello:v2 -n test
rollout "rollouts-demo" image updated
# kubectl argo rollouts get rollout rollouts-demo -n test
Name: rollouts-demo
Namespace: test
Status: ॥ Paused
Message: CanaryPauseStep
Strategy: Canary
Step: 1/2
SetWeight: 5
ActualWeight: 5
Images: ghcr.io/kmaster8/hello:v1 (stable)
ghcr.io/kmaster8/hello:v2 (canary)
Replicas:
Desired: 1
Current: 2
Updated: 1
Ready: 2
Available: 2
NAME KIND STATUS AGE INFO
⟳ rollouts-demo Rollout ॥ Paused 27m
├──# revision:2
│ └──⧉ rollouts-demo-56f4f7dc9b ReplicaSet ✔ Healthy 26s canary
│ └──□ rollouts-demo-56f4f7dc9b-8l72h Pod ✔ Running 25s ready:1/1
└──# revision:1
└──⧉ rollouts-demo-6c75c64f5 ReplicaSet ✔ Healthy 27m stable
└──□ rollouts-demo-6c75c64f5-ltm7c Pod ✔ Running 27m ready:1/1
배포 후 rollout-demo-prod-ingress-canary의 상세정보를 보면 아래와 같다.
# kubectl describe ing -n test rollouts-demo-prod-ingress-canary
Name: rollouts-demo-prod-ingress-canary
Namespace: test
Address: 10.109.32.60
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
test.prod.10.60.200.121.sslip.io
/ hello-v2:5000 (172.32.139.180:5000)
Annotations: kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: true
nginx.ingress.kubernetes.io/canary-weight: 5
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 64s (x3 over 28m) nginx-ingress-controller Scheduled for sync
Normal Sync 64s (x3 over 28m) nginx-ingress-controller Scheduled for sync
Normal Sync 64s (x3 over 28m) nginx-ingress-controller Scheduled for sync
canary-weight: 5로 변경됨을 확인할 수 있다. 실제 브라우저를 통해 호출해 보면 v1과 v2 가 95% 대 5% 비율로 보일 것이다.
Kubernetes의 일반적인 canary배포는 pod 개수로 비율을 조절하지만, nginx ingress를 통한 canary배포는 pod의 개수와 상관없이 비율을 조정할 수 있다.
이제, v2버전으로 모두 이전해 보자.
# kubectl argo rollouts promote rollouts-demo -n test
rollout 'rollouts-demo' promoted
# kubectl argo rollouts get rollout rollouts-demo -n test
# kubectl argo rollouts get rollout rollouts-demo -n test
Name: rollouts-demo
Namespace: test
Status: ✔ Healthy
Strategy: Canary
Step: 2/2
SetWeight: 100
ActualWeight: 100
Images: ghcr.io/kmaster8/hello:v2 (stable)
Replicas:
Desired: 1
Current: 1
Updated: 1
Ready: 1
Available: 1
NAME KIND STATUS AGE INFO
⟳ rollouts-demo Rollout ✔ Healthy 35m
├──# revision:2
│ └──⧉ rollouts-demo-56f4f7dc9b ReplicaSet ✔ Healthy 8m12s stable
│ └──□ rollouts-demo-56f4f7dc9b-8l72h Pod ✔ Running 8m11s ready:1/1
└──# revision:1
└──⧉ rollouts-demo-6c75c64f5 ReplicaSet • ScaledDown 35m
└──□ rollouts-demo-6c75c64f5-ltm7c Pod ◌ Terminating 35m ready:1/1
이제 v1을 모두 terminaing 되고 v2가 승격됨을 확인할 수 있다. 브라우저에서 실제 호출하면 이제 v2 앱만 보이게 된다.
'Kubernetes > devops' 카테고리의 다른 글
Argo rollout을 통한 Blue/Green CD (Continuous Deployment) 구축하기 (2) - Blue/Green 배포 (0) | 2022.02.27 |
---|---|
Docker 없이 Docker Image 만들기 ( Kaniko ) (2) | 2022.02.27 |
Flagger를 사용한 CD ( Continuous Deployment ) 구축하기 (0) | 2022.02.23 |
Kubernetes의 다양한 배포방식 (3) Canary 배포 (0) | 2022.02.20 |
Kubernetes의 다양한 배포방식 (2) Blue/Green 배포 (0) | 2022.02.19 |