Argo Rollouts 설치하기
ArgoCD와 ArgoCD Image Updater 설치와 마찬가지로 helm 레포와 차트를 다운받는다.
이후 차트 내부에 values-dev.yaml 파일을 생성해 아래 내용을 추가한다.
controller:
replicas: 1
dashboard:
enabled: true
service:
type: NodePort
portName: dashboard
port: 3100
targetPort: 3100
nodePort: 30003
이후 아래 helm 명령어로 설치를 수행한다. 마찬가지로 kubeconfig는 제외 가능.
helm upgrade argo-rollouts ./argo/helm/argo-rollouts
-f ./argo/helm/argo-rollouts/values-dev.yaml
-n argo --install --kubeconfig ${KUBECONFIG}
--wait --timeout=10m
설치가 완료되면 kubectl로 파드가 정상작동 중인지 확인한다.
k get pod -n argo
# rollouts 파드 확인
...
argo-rollouts-cc78c958-p79k8 1/1 Running 0 3d23h
argo-rollouts-dashboard-57f4d4c44f-94rhl 1/1 Running 0 3d23h
Argo Rollouts로 Blue-Green 배포하기
먼저 Blue/Green 배포의 특징을 정리해보자.
- 배포 시 롤백이 빠르다.
- 배포 중 v1과 v2의 동시호출이 발생하지 않는다.
- Script를 통해 자동 배포가 가능하다.
- v2에 과도한 트래픽 유입시 문제가 발생할 수 있다.
Kubernetes를 사용해 Blue/Green 배포를 진행하면 다음 과정을 거친다.
- v2 Deployment 생성
- Service의 Selector를 v2로 변경
- v1 Deployment 삭제.
반면 Rollouts를 이용하여 Blue/Green 배포를 수행하면 다음과 같은 과정으로 진행된다.
- Rollouts는 2개의 service를 지정한다.
- active: 사용자가 접속하는 실제 서비스 v1
- preview: 업데이트 중에 v2로 들어가 볼 수 있는 서비스
- 처음에는 active와 preview 모두 v1 파드로 트래픽을 전달한다.
- rollout에서 v2로 태그를 변경하고 argo에서 sync를 하거나 쿠버네티스에서 자원을 변경하면 업그레이드가 수행된다.
- v2 버전의 ReplicaSet이 생성되며 v2 pod가 생성된다
- 이 때 preview service가 v1에서 v2 pod로 트래픽 대상을 변경한다.
- QA 담당자가 preview에서 테스트를 완료한 후 promote 명령어를 날리면 active service 또한 v2 pod로 변경된다.
- v1 pod를 삭제한다.
과정을 보면 자칫 복잡해보이지만 서비스를 2개 생성하여 유동적으로 타겟을 변경하는 점만 기억하면 된다.
이제 실제로 Argo Rollout을 이용하여 업데이트 배포를 해보자.
Argo Rollout을 사용하기 위해 기존의 Deployment가 아닌 Rollout이라는 새로운 리소스로 배포를 해야한다.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api-tester-2233
labels:
part-of: k8s-anotherclass
...
spec:
replicas: 2
strategy:
blueGreen:
activeService: api-tester-2233-active
previewService: api-tester-2233-preview
autoPromotionEnabled: false
...
template:
metadata:
labels:
part-of: k8s-anotherclass
component: backend-server
name: api-tester
instance: api-tester-2233
version: 1.0.0
spec:
containers:
- name: api-tester-2233
image: 1pro/api-tester:1.0.0
imagePullPolicy: Always
...
apiVersion과 kind:Rollout에 주목하면 된다. yaml 파일의 내용은 기존 Deployment과 거의 동일하다.
spec.strategy 속성을 blueGreen으로 지정하고 active, preview 서비스의 이름만 지정하면된다.
- previewService : 업그레이드 중간에 새로 만들어지는 RepliaSet의 Pod에 먼저 연결되는 서비스
- activeService : 주 서비스 (업그레이 시 트래픽이 Blue에서 Green으로 변경됨)
- autoPromotionEnabled : 새 RepliaSet이 활성화 되면 바로 트래픽을 전환 = 자동 업그레이드 (default : true)
active와 preview 두 서비스의 정의 예시는 다음과 같다.
apiVersion: v1
kind: Service
metadata:
name: api-tester-2233-active
labels:
part-of: k8s-anotherclass
component: backend-server
name: api-tester
instance: api-tester-2233
version: 1.0.0
managed-by: kubectl
spec:
selector:
part-of: k8s-anotherclass
component: backend-server
name: api-tester
instance: api-tester-2233
ports:
- port: 80
targetPort: http
nodePort: 32233
type: NodePort
preview service도 위 active service 정의와 동일하게 하되, 이름과 nodePort 번호만 변경하면 될것이다.
이제 ArgoCD 대시보드로 접속해 NEW APP > EDIT AS YAML을 클릭하고. 아래같이 application yaml 내용을 작성한다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: api-tester-2233
spec:
destination:
name: ''
namespace: anotherclass-223
server: 'https://kubernetes.default.svc'
source:
path: 2233/deploy/argo-rollouts
repoURL: 'https://github.com/EBEL21/kubernetes-anotherclass-sprint2.git'
targetRevision: main
sources: []
project: default
이전에 ArgoCD 포스팅에서 작성했던 내용을 yaml 파일로 대체한다고 생각하면 된다.
destination은 배포하고자 하는 클러스터이고, source는 app release 파일들이 위치한 git 저장소이다.
저장 후 Sync를 눌러 배포를 하면 active, preview 2개의 서비스가 생성된 것을 확인할 수 있다.
각 서비스에 트래픽을 날려보면 두 서비스 모두 v1 파드에서 결과를 가져옴을 확인할 수 있다.
# Active Service
[root@k8s-master ~]# while true; do curl http://192.168.56.30:32233/version; sleep 2; echo ''; done;
[App Version] : Api Tester v1.0.0
[App Version] : Api Tester v1.0.0
# Preview Service
[root@k8s-master ~]# while true; do curl http://192.168.56.30:32243/version; sleep 2; echo ''; done;
[App Version] : Api Tester v1.0.0
[App Version] : Api Tester v1.0.0
이제 release 저장소에서 app 버전을 2.0.0으로 변경하고 배포해보자.
Rollout 객체의 live manifest나 git 저장소에서 image의 tag를 변경하게되면 v2의 ReplicaSet과 Pod가 생성된다.
# Active Service
[App Version] : Api Tester v1.0.0
[App Version] : Api Tester v1.0.0
# Preview Service
[App Version] : Api Tester v2.0.0
[App Version] : Api Tester v2.0.0
트래픽을 확인해보면 preview 서비스가 v1에서 v2로 트래픽을 전환한 것을 확인할 수 있다.
이 상태에서 Rollout 객체를 클릭해 Promote-Full 버튼을 눌러보자.
# Active Service
[App Version] : Api Tester v2.0.0
[App Version] : Api Tester v2.0.0
# Preview Service
[App Version] : Api Tester v2.0.0
[App Version] : Api Tester v2.0.0
Promote가 끝나면 v1 파드가 제거되고 v2 파드만 남게 된다. 또한 active service의 트래픽이 v2로 전환된것을 확인할 수 있다.
이미지상으로는 현재 app이 outofsync 상태로 되어있는데 이는 live manifest에서 이미지 태그를 변경하여 git 저장소와 버전이 일치하지 않기 때문일 뿐 문제가 발생한 것은 아니다.
Argo Rollouts로 Canary 배포하기
이번엔 Canary 배포를 진행해보겠다. 먼저 Canary 배포의 특징은 다음과 같다.
- 특정 IP, 사용자만 v2를 호출할 수 있게 설정할 수 있다.
- 콜드 스타트를 방지하고 두 버전을 비교하는 A/B 테스트 용도로 쓰인다.
Kubernetes 사용 시 Canary 배포는 다음과 같이 진행된다.
- v2 Deployment, Ingress, Service 생성
- v1 / v2 Ingress 가중치 변경
- v1 Deployment, Ingress, Service 제거
반면 Rollut 사용 시 Canary 배포는 다음과 같다.
- Canary 배포를 사용하는 rollout controller를 생성하고 이번엔 service를 하나만 생성한다.
- 버전을 변경하고 ArgoCD에서 sync를 수행한다. 그럼 v2 버전의 새로운 ReplicaSet이 생성된다.
- rollout에서 canary 배포를 사용하면 steps라는 설정이 존재하고 이 설정에 의해 다음 순서가 진행된다.
- setWeights: 33
- pause: {}
- setWeight: 66
- pause: {duration: 2m}
위 steps 설정을 line by line으로 진행과정을 설명하면 다음과 같다.
- seWeights 33: 전체 파드에서 canary 파드가 차지하는 비율. 만약 v1 파드가 2개라면 v2 파드는 처음에 1개가 생성된다.
- pause {}: promote 명령어가 올때까지 대기한다.
- setWeight 66: promote가 수행되면 전체 파드에서 v2파드가 66%가 되도록 한다. 그러면 v1 파드가 1개 삭제되고 v2 파드가 1개 생성된다.
- pause {duration 2m}: 이후 2분동안 대기한 후 나머지 pod 1개를 삭제한다.
이러한 과정을 보면 deployment의 rollingupdate와 유사한 기능을 수행하고 있다.
이제 실제로 ArgoCD에 배포해볼텐데, Blue/Green 배포와 동일하게 rollout 객체로 배포한다.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api-tester-2234
labels:
part-of: k8s-anotherclass
...
spec:
replicas: 2
strategy:
canary:
steps:
- setWeight: 33
- pause: {}
- setWeight: 66
- pause: { duration: 2m }
template:
metadata:
labels:
part-of: k8s-anotherclass
spec:
containers:
- name: api-tester-2234
image: 1pro/api-tester:1.0.0
imagePullPolicy: Always
역시 spec.strategy를 canary로 설정하고 active/preview service 이름을 지정하는 대신 위에서 설명한 steps 설정을 정의하면 된다.
ArgoCD에서 앱을 배포한 뒤, 이번에는 argo rollouts 대시보드로 접속하여 canary 배포를 이어가보자.
http://<YOUR_SERVER_IP>:30003/rollouts/rollout/anotherclass-223/api-tester-2234
대시보드로 접속하면 위와 같은 화면이 나온다.
이 상태에서 Containers -> Edit -> image tag를 2.0.0으로 변경하게 되면 steps에 정의한 설정대로 canary 배포가 진행된다.
맨 먼저 "Set Weight: 66% "에 의해 전체 파드의 33%, 즉 1개의 v2 파드가 생성되었다.
이후 "pause {}" 구문에 의해 promote 명령을 기다리는 상태이고, 오른쪽 위에 Promote, PromoteFull 버튼이 활성화 되었다.
Promote는 step을 하나씩 수행한다는 의미이고, PromoteFull은 전체 step을 자동진행한다는 의미이다.
Promote 버튼을 눌러보면 "Set Weight: 66%" 단계가 실행되며 v1 파드가 하나 삭제됨과 동시에 v2 파드 1개가 생성된다.
이후 "Pause: 2m" 이 작동되며 2분 후에 나머지 v1 파드가 삭제되며 최종 결과는 다음과 같다.
Argo Rollout CLI 사용
위 과정처럼 대시보드를 이용해 배포할 수도 있지만, Rollout CLI를 이용해 kubectl 명령어로 배포를 진행할 수 있다.
Argo Rollout CLI 설치는 다음과 같다.
// root 계정
curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v1.6.4/kubectl-argo-rollouts-linux-amd64
chmod +x ./kubectl-argo-rollouts-linux-amd64
mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
// 설치 확인
[root@k8s-master ~]# kubectl argo rollouts version
kubectl-argo-rollouts: v1.6.4+a312af9
BuildDate: 2023-12-11T18:31:15Z
GitCommit: a312af9f632b985ec13f64918b918c5dcd02a15e
GitTreeState: clean
GoVersion: go1.20.12
Compiler: gc
Platform: linux/amd64
설치 후 위 canary 배포를 cli 명령어로 진행하면 다음과 같다.
// Rollout 조회 하기
kubectl argo rollouts get rollout api-tester-2233 -n anotherclass-223 -w
// Rollout 리소스 수정하기
// kubectl argo rollouts edit <ROLLOUT_NAME> -n <NAMESPACE_NAME>
kubectl argo rollouts edit api-tester-2234 -n anotherclass-223
// 이미지 태그 변경
// kubectl argo rollouts set image <ROLLOUT_NAME> <CONTAINER_NAME>=<IMAGE>:<TAG> -n <NAMESPACE_NAME>
kubectl argo rollouts set image api-tester-2234 api-tester-2234=1pro/api-tester:2.0.0 -n anotherclass-223
// Promote 명령어
// kubectl argo rollouts promote <ROLLOUT_NAME> -n <NAMESPACE_NAME>
kubectl argo rollouts promote api-tester-2234 -n anotherclass-223
'DevOps' 카테고리의 다른 글
Ubuntu 서버에 Nexus Repository 구축하기 (1) | 2025.01.30 |
---|---|
[ArgoCD] ArgoCD Image Updater를 이용해 쿠버네티스에서 App 버전 업그레이드 자동화하기 (4) | 2024.10.20 |
[ArgoCD] ArgoCD로 쿠버네티스 클러스터에 App 배포하기 (4) | 2024.10.18 |
[ArgoCD] ArgoCD 아키텍처에 대한 이해 (0) | 2024.10.17 |
[Helm] Helm 패키지 생성하고 배포하기 (2) | 2024.10.07 |