새소식

기술/Application

Argo CD를 이용한 Blue/Green 배포 (3)

  • -

안녕하세요. 이번에는 Argo CD를 이용한 Blue/Green 배포 방법에 대해서 알아보겠습니다.

 

 

Blue/Green 배포란?

Blue-Green 배포는 애플리케이션 또는 마이크로서비스의 이전 버전에 있던 사용자 트래픽을 이전 버전과 거의 동일한 새 버전으로 점진적으로 이전하는 애플리케이션 릴리스 모델입니다. 이때 두 버전 모두 프로덕션 환경에서 실행 상태를 유지합니다.

이전 버전을 blue 환경으로, 새 버전은 green 환경으로 부를 수 있습니다. 프로덕션 트래픽이 blue에서 green으로 완전히 이전되면, blue는 롤백에 대비하여 대기 상태로 두거나 프로덕션에서 가져온 후 업데이트하여 다음 업데이트의 템플릿으로 삼을 수 있습니다.

이와 같은 지속적 배포 모델에는 단점이 있습니다. 환경에 따라서는 업타임 요구 사항이 다르거나 blue-green과 같은 CI/CD 프로세스를 제대로 수행할 리소스가 없을 수도 있습니다. 그러나 애플리케이션을 지원하는 기업의 디지털 트랜스포메이션이 본격화되면서 많은 애플리케이션이 이러한 지속적 제공을 지원하도록 진화하고 있습니다.

RedHat 공식 홈페이지의 Blue-Green 배포란? 페이지 발췌

(출처 : www.redhat.com/ko/topics/devops/what-is-blue-green-deployment )

 

그런데, Argo CD를 사용하지 않더라도 Kubernetes 상에서 blue/green 전략을 가져가는 방법이 있습니다.

 

Deployment를 2개 운영하고, Service에서 Selector를 변경하는 방법이 있는데, 해당 방법에는 Deployment를 2개를 운영해야 하기 때문에 실수할 경우가 있습니다.

 

고객들에게 서비스를 제공하는 입장인 만큼 사소한 실수를 줄이기 위해, 또 Argo CD라는 툴을 사용하면서 좀 더 편리한 기능을 사용하고자 본 가이드를 작성하는 목적입니다. :)

 

 

먼저, ArgoCD에서 Blue/Green을 사용하기 위해선 Plugin을 추가해야 합니다.

 

Argo Rollouts

Github : github.com/argoproj/argo-rollouts

Document : argoproj.github.io/argo-rollouts

 

먼저 Argo Rollouts에서 사용할 Namespace를 생성 후 공시적으로 지원하는 manifest를 이용하여 설치를 진행합니다.

 

설치 시 service account와 rbac, crd 등이 생성이 됩니다.

# 최신 버전의 Argo Rollouts 설치
root@node1:~# kubectl create namespace argo-rollouts
root@node1:~# kubectl apply -n argo-rollouts -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/manifests/install.yaml

Warning: apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
customresourcedefinition.apiextensions.k8s.io/analysisruns.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/analysistemplates.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/clusteranalysistemplates.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/experiments.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/rollouts.argoproj.io created
serviceaccount/argo-rollouts created
role.rbac.authorization.k8s.io/argo-rollouts-role created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-admin created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-edit created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-view created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-clusterrole created
rolebinding.rbac.authorization.k8s.io/argo-rollouts-role-binding created
clusterrolebinding.rbac.authorization.k8s.io/argo-rollouts-clusterrolebinding created
service/argo-rollouts-metrics created
deployment.apps/argo-rollouts created

# stable 버전으로 설치 시
kubectl apply -n argo-rollouts -f https://raw.githubusercontent.com/argoproj/argo-rollouts/stable/manifests/install.yaml

 

설치 완료 후 kubectl 용 plugin을 설치 합니다.

Mac 사용자의 경우
brew install argoproj/tap/kubectl-argo-rollouts

Ubuntu(linux) 사용자의 경우

다운로드
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64

권한 변경
chmod +x ./kubectl-argo-rollouts-linux-amd64

파일 이동
sudo mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts

설치 완료 후
root@node1:~# kubectl argo rollouts version
kubectl-argo-rollouts: v0.9.1+3e25fa3
  BuildDate: 2020-09-28T21:50:53Z
  GitCommit: 3e25fa3dfc1788a4a00222d8cd020971d77d72a8
  GitTreeState: clean
  GoVersion: go1.13.1
  Compiler: gc
  Platform: linux/amd64

 

이제 Argo Rollouts 사용할 준비를 마쳤습니다.

 

아래 예제를 이용하여 테스트를 진행해보겠습니다.

 

Source Code : https://github.com/teichae/gitops/blob/main/rollout/test.yaml

---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-bluegreen
spec:
  replicas: 2
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: rollout-bluegreen
  template:
    metadata:
      labels:
        app: rollout-bluegreen
    spec:
      containers:
      - name: rollouts-demo
        image: argoproj/rollouts-demo:blue
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
  strategy:
    blueGreen: 
      activeService: rollout-bluegreen-active
      previewService: rollout-bluegreen-preview
      autoPromotionEnabled: false

---
kind: Service
apiVersion: v1
metadata:
  name: rollout-bluegreen-active
spec:
  selector:
    app: rollout-bluegreen
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
    nodePort: 30081
  type: NodePort

---
kind: Service
apiVersion: v1
metadata:
  name: rollout-bluegreen-preview
spec:
  selector:
    app: rollout-bluegreen
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
    nodePort: 30082
  type: NodePort

해당 예제로 잠깐 알아보면, Service를 2개를 만들었습니다.

 

Active와 Preview인데요. Active는 Live에서 현재 운영 중인 Blue가 보이고, Preview에서는 새로 배포할 Green의 배포가 보입니다.

 

또 눈여겨봐야 하는 옵션은 아래인데요.

  strategy:
    blueGreen: 
      activeService: rollout-bluegreen-active
      previewService: rollout-bluegreen-preview
      autoPromotionEnabled: false

Blue/Green 방식의 배포를 사용하고 어느 Service를 Active(Blue)로 어느 Service를 Preview(Green)로 사용할지 지정할 수 있습니다.

 

그리고 autoPromotionEnabled: false 옵션은 자동으로 Blue/Green이 변경되지 않고 사용자가 승인을 해줘야 교체가 발생되게 하는 옵션입니다.

 

옵션에 따라 특정 시간이 지난 후 자동으로 교체되도록 하는 옵션도 지원됩니다.

 

본 가이드에서는 kubectl plugin을 설치했으니, 승인 과정까지 보여드리기 위해 autoPromotionEnabled: false로 진행했습니다.

 

이제 Argo CD를 이용하여 배포해보도록 하겠습니다.

 

 

 

옵션은 지난번에 설명했기 때문에 생략하도록 하겠습니다.

 

저는 rollout이란 Namespace를 만들고 거기에 Blue를 배포하도록 하겠습니다.

 

 

 

배포 완료 후의 모습입니다.

 

 

 

배포 후 Active Page의 모습입니다.

 

아직 Preview(Green)을 배포하지 않았기 때문에 Preview 역시도 Active Page와 같습니다.

 

이제 위 Manifest를 수정해서 Green을 배포해보겠습니다.

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-bluegreen
spec:
  replicas: 2
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: rollout-bluegreen
  template:
    metadata:
      labels:
        app: rollout-bluegreen
    spec:
      containers:
      - name: rollouts-demo
        #여기서 blue를 green으로 수정
        #image: argoproj/rollouts-demo:blue -> image: argoproj/rollouts-demo:green
        image: argoproj/rollouts-demo:green
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
  strategy:
    blueGreen: 
      activeService: rollout-bluegreen-active
      previewService: rollout-bluegreen-preview
      autoPromotionEnabled: false

 

 

Manifest 변경 후 Preview(Green)이 배포된 모습입니다.

 

 

 

Service 부분만 추려서 보았을 때 좀 더 직관적으로 볼 수 있습니다.

 

 

 

왼쪽이 Active, 오른쪽이 Preview입니다.

 

이제 정상적으로 Blue/Green이 배포된 것을 확인했으니 교체 승인 과정을 진행해보겠습니다.

 

다시 CLI 환경으로 돌아갑니다.

root@node1:~# kubectl argo rollouts list rollout -n rollout
NAME               STRATEGY   STATUS        STEP  SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE
rollout-bluegreen  BlueGreen  Paused        -     -           2/4    2        2           2

현재 autoPromotionEnabled 옵션이 false이기 때문에 Pause 상태로 멈추어 있는 것을 확인할 수 있습니다.

 

이제 Promote 해보겠습니다.

#promote 진행
root@node1:~# kubectl argo rollouts promote -n rollout rollout-bluegreen
rollout 'rollout-bluegreen' promoted

#promote 진행 후
root@node1:~# kubectl argo rollouts list rollout -n rollout
NAME               STRATEGY   STATUS        STEP  SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE
rollout-bluegreen  BlueGreen  Healthy       -     -           2/2    2        2           2

상태가 Healthy로 변경된 것을 확인할 수 있습니다.

 

이제 Argo CD에서 확인하면 기존 Blue Pod들이 삭제된 것을 확인할 수 있습니다.

 

 

Active Page에서도 Green으로 교체되면서 변경된 것을 확인할 수 있습니다.

 

이상으로 Argo CD를 이용한 Blue/Green 배포 가이드 글을 마치겠습니다.

 

해당 가이드 글에서 사용한 소스 코드는 아래에 공개하고 있습니다. :)

 

https://github.com/teichae/gitops

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.