Argo Rollouts이란
Argo rollouts는 blue/green 배포와 canary 배포를 쉽게 구현할 수 있도록 도와주고 roll back을 쉽게 만들어주는, deployment의 확장 버전과 같은 역할을 하는 custom resource입니다.
ReplicaSet과 Pod에 hash값을 label로 추가하여 신규 배포 버전과 기존 배포 버전을 구분하고, 기존 버전 ReplicaSet의 Pod들과 연결된(label selector) Active ClusterIP가 다른 버전의 ReplicaSet의 Pod와 연결되도록 바꾸거나, ReplicaSet의 Pod의 개수를 버전마다 다르게 조절하는 방식으로 배포 전략을 구현합니다.
Argo rollout 설치 및 세팅
# namespace 생성
kubectl create namespace argo-rollouts
# apply argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
# install kubectl plugin for argo rollout & 설치 확인
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
sudo install -o root -g root -m 0755 kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
kubectl argo rollouts version
Argo Rollouts 예시
Blue/Green
Rollout
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: service-user
namespace: service
spec:
replicas: 1
selector:
matchLabels:
type: service
for: user
template:
metadata:
labels:
type: service
for: user
spec:
containers:
- name: user
image: { imageURL }
ports:
- containerPort: 8080
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 200m
memory: 512Mi
strategy:
blueGreen:
activeService: service-user-active
previewService: service-user-preview
autoPromotionEnabled: false
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: service-products
namespace: service
spec:
replicas: 5
selector:
matchLabels:
type: service
for: products
template:
metadata:
labels:
type: service
for: products
spec:
containers:
- name: products
image: { imageURL }
ports:
- containerPort: 8080
resources:
requests:
cpu: 1
memory: 1024Mi
limits:
cpu: 1
memory: 1024Mi
strategy:
blueGreen:
activeService: service-products-active
previewService: service-products-preview
autoPromotionEnabled: false
service
---
apiVersion: v1
kind: Service
metadata:
name: service-user-active
namespace: service
spec:
ports:
- port: 8080
protocol: TCP
selector:
for: user
type: service
---
apiVersion: v1
kind: Service
metadata:
name: service-user-preview
namespace: service
spec:
ports:
- port: 8080
protocol: TCP
selector:
for: user
type: service
---
apiVersion: v1
kind: Service
metadata:
name: service-products-active
namespace: service
spec:
ports:
- port: 8080
protocol: TCP
selector:
for: products
type: service
---
apiVersion: v1
kind: Service
metadata:
name: service-products-preview
namespace: service
spec:
ports:
- port: 8080
protocol: TCP
selector:
for: products
type: service
동작 과정
blue와 green 버전 별로 clusterIP를 만들면(active, preview) 해당 버전에 맞는 replicaSet과 pod가 생성되어 각각 active와 preview service(clusterIP)에 연결되고, green 버전의 pod가 정상적으로 뜨는 것을 확인 후 argocd web condole에서 promote-Full 버튼을 누르면 자동으로 green으로의 배포가 완료됩니다.
이는 preview에 연결되었던 ReplicaSet을 active service에 연결하고, 기존에 active에 연결되었던 ReplicaSet의 Pod 개수를 0으로 바꾸는 방식으로 구현됩니다.
roll back의 경우는 roll back하기 원하는 revision에 맞는 ReplicaSet을 hash값을 통해 찾아내고, hash값이 value로 설정된 label을 이용해 preview service에 연결하는 방식으로 구현됩니다.
Canary
Rollout
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: service-user
namespace: service
spec:
replicas: 1
selector:
matchLabels:
type: service
for: user
template:
metadata:
labels:
type: service
for: user
spec:
containers:
- name: user
image: { imageURL }
ports:
- containerPort: 8080
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 200m
memory: 512Mi
strategy:
canary:
maxSurge: '25%'
maxUnavailable: 0 # 업데이트 될 때 사용할 수 없는 pod의 최대 수
steps:
- setWeight: 25 # 카나리로 배포된 서버로 전송해야될 트래픽 비율
- pause: { duration: 1h } # AutoPromotion Time
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: service-products
namespace: service
spec:
replicas: 5
selector:
matchLabels:
type: service
for: products
template:
metadata:
labels:
type: service
for: products
spec:
containers:
- name: products
image: { imageURL }
ports:
- containerPort: 8080
resources:
requests:
cpu: 1
memory: 1024Mi
limits:
cpu: 1
memory: 1024Mi
strategy:
canary:
maxSurge: '25%'
maxUnavailable: 0 # 업데이트 될 때 사용할 수 없는 pod의 최대 수
steps:
- setWeight: 25 # 카나리로 배포된 서버로 전송해야될 트래픽 비율
- pause: { duration: 1h } # AutoPromotion Time
service
---
apiVersion: v1
kind: Service
metadata:
name: service-user
namespace: service
spec:
ports:
- port: 8080
protocol: TCP
selector:
for: user
type: service
---
apiVersion: v1
kind: Service
metadata:
name: service-products
namespace: service
spec:
ports:
- port: 8080
protocol: TCP
selector:
for: products
type: service
동작 과정
blue/green과는 달리 하나의 clusterIP에 2개의 ReplicaSet이 연결되는 방식으로 canary가 구현됩니다.
replica가 16일 때, setWeight가 25이므로 25%의 트래픽만이 신규 버전으로 전송될 수 있도록 4개의 신규 버전 pod와 12개의 기존 버전 pod가 실행되는 것을 볼 수 있으며, istio와 같은 서비스 메시를 연동하지 않으면 argo rollout은 clusterIP에 연결된 2개의 replicaSet의 replica 수를 적절히 조절하여 canary를 구현합니다.
즉, istio를 사용하는 것처럼 완벽하게 원하는대로 트래픽의 양과 방향을 조작할 수는 없습니다.
Roll back
또한 다음과 같이 cli 서버에서 명령어 하나만 입력하면 원하는 revision으로의 롤백이 가능합니다.
추가
Deployments가 rolling update로 롤 아웃/백 할 때도 Deployments가 신규 버전을 위한 ReplicaSet을 추가로 만들고, maxSurge와 maxUnavailable 설정에 맞게 신규 ReplicaSet의 replicas를 늘리고 기존 ReplicaSet의 replicas를 줄이는 방식으로 동작합니다.
예를 들어, 기존 ReplicaSet의 replicas=3이고 maxSurge=1, maxUnavailable=0인 경우:
Pod가 3개 떠있는 상태에서 시작해서 Roll out 과정에서 최대 Pod 4개까지 늘어날 수 있고, available 상태인 Pod가 3개 미만으로 줄어들 수 없습니다.
1. maxSurge가 1이므로, 신규 ReplicaSet의 replicas=1이 되고 1개의 Pod가 생성됩니다.
2. 신규 Pod가 생성이 완료되면, 기존 ReplicaSet의 replicas=2가 되고 기존 Pod가 하나 줄어듦과 동시에 신규 ReplicaSet의 replicas=2가 되고 신규 Pod가 하나 생성됩니다.
3. 신규 Pod가 생성이 완료되면, 기존 ReplicaSet의 replicas=1이 되고 기존 Pod가 하나 줄어듦과 동시에 신규 ReplicaSet의 replicas=3이 되고 신규 Pod가 하나 생성됩니다.
3. 신규 Pod가 생성이 완료되면, 기존 ReplicaSet의 replicas=0이 되고 기존 Pod가 하나 줄어들어 신규 ReplicaSet의 replicas=3이 되고, 신규 Pod가 3개 떠있는 상태로 roll out이 완료됩니다.
Kubernetes에서 Deployment가 롤아웃을 끝낸 후 기본적으로 남는 ReplicaSet의 개수는 10개입니다. (Argo Rollouts도 동일)
즉, 최신 ReplicaSet을 포함하여 총 11개의 ReplicaSet이 Deployment와 연관되어 남아있을 수 있습니다. 이는 롤백 기능을 지원하고 필요한 경우 빠르게 이전 버전으로 되돌릴 수 있도록 하기 위함입니다.
만약 이전 ReplicaSet을 유지할 필요가 없거나 저장 공간을 절약하고 싶다면, Deployment의 .spec.revisionHistoryLimit 필드를 0으로 설정하여 이전 ReplicaSet을 모두 삭제하도록 설정할 수 있습니다.
'Cloud engineering' 카테고리의 다른 글
부하테스트를 통한 상품 조회 서비스 1.5배 성능 개선(ElastiCache, HPA) (0) | 2024.09.01 |
---|---|
Karpenter 활용하기 (6) | 2024.09.01 |
ArgoCD 설치 및 설정 (1) | 2024.09.01 |
Terraform 이용해 EKS Cluster 구축하기 (0) | 2024.09.01 |
올리브영 온라인 쇼핑몰 public cloud(AWS) 인프라 구축 프로젝트 (3) | 2024.08.31 |