반응형

Argo Rollout 은 new version pods 와 old version pods 를 어떻게 구분하는 것일까? Rollout 리소스로 생성하면 ReplicaSet 의 형태인 Pod 템플릿 영역인 (spec.template) 과 동일하다. 즉 ReplicaSet 이 Selector 로 지정한 label 로 Pod 를 찾아가는 것이다.

아래 Rollout 1개와 Service 2개를 가지는 sample 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

---
kind: Service
apiVersion: v1
metadata:
  name: rollout-bluegreen-preview
spec:
  selector:
    app: rollout-bluegreen
  ports:
  - protocol: TCP
    port: 80

Rollout 은 strategy 만 제외하면 ReplicaSet 혹은 Deployment 와 동일하다. 그래서 Rollout 을 배포하면 ReplicaSet 과 Pod 는 Kubernetes Core Resource 타입으로 동일하게 생성되고 조회할 수 있다.

 

.spec.selector.matchLabels 와 .spec.template.metadata.labels 에서 지정한 label 은 동일해야 한다. 이 부분은 ReplicaSet 에서 요구하는 spec 과 같다.

 

strategy 의 blueGreen 에는 rollout-bluegreen-active 와 rollout-bluegreen-preview 라는 service 가 2개가 지정되어 있다. Service 는 DNS 명 처럼 이름으로 IP 를 매칭하는 값을 가지는 기능과 Pod 를 연결하여 load balancing 해주는 대표적인 기능이 있다. rollout-bluegreen-active Service 에는 selector 로 "app: rollout-bluegreen" 값이 지정되어 있는데 이는 Rollout Template 에서 지정된 Pod 의 labels 를 가리킨다.

 

그런데 rollout-bluegreen-active Service 와 rollout-bluegreen-preview 2개 모두 같은 selector 로 같은 Pod 를 보고 있는데 어떻게 new version 과 old version 을 구분할까?

 

배포한 후에 설정들이 어떻게 바뀌는지 살펴보자.

$ kubectl apply -f rollout-blue-green.yaml
$ kubectl argo rollouts get rollout rollout-bluegreen --watch

 

 

rollout 명이 rollout-bluegreen-[해시코드값] 으로 되어 있는데 여기서 해시코드 값이 6565b74f44 은 ReplicaSet 의 해시코드와 동일하다.

$ kubectl get rs rollout-bluegreen

 

 

이 해시코드 값은 Service 에서도 찾아 볼 수 있다.

$ kubectl get svc rollout-bluegreen-active -o yaml
...
apiVersion: v1
kind: Service
metadata:
  name: rollout-bluegreen-active
  namespace: default
spec:
  clusterIP: 10.233.59.133
  clusterIPs:
  - 10.233.59.133
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: rollout-bluegreen
    rollouts-pod-template-hash: 6565b74f44
  sessionAffinity: None
  type: ClusterIP
...

selector 의 label 에 자동으로 rollouts-pod-template-hash: 6565b74f44 이 추가되어 rollout-bluegreen-active Service 는 현재 version 의 rollout 으로 생성된 Pod 를 가리키는 것을 알 수 있다.

이제 이미지를 업데이트 하여 upgrade 배포를 해보자.

$ kubectl argo rollouts set image rollout-bluegreen rollouts-demo=argoproj/rollouts-demo:yellow
$ kubectl argo rollouts get rollout rollout-bluegreen --watch

 

 

revision:2 아래에 rollout-bluegreen-6b5dc99488 이라는 새로운 해시코드 값으로 ReplicaSet 이 생성되었다.

rollout-bluegreen-preview Service 의 selector 로 지정된 labels 을 보면 rollouts-pod-template-hash:6b5dc99488 가 생성되어 new version 의 pod 를 가리키는 것을 알 수 있다.

$ kubectl get svc rollout-bluegreen-preview -o yaml
...
apiVersion: v1
kind: Service
metadata:
  name: rollout-bluegreen-preview
  namespace: default
spec:
  clusterIP: 10.233.44.227
  clusterIPs:
  - 10.233.44.227
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: rollout-bluegreen
    rollouts-pod-template-hash: 6b5dc99488
  sessionAffinity: None
  type: ClusterIP
...

배포를 완료하고 ReplicaSet 을 조회해 보면 이전 해시코드 값을 갖는 ReplicaSet 의 DESIRED, CURRENT, READY 가 0 으로 세팅되어 있는 것을 알 수 있다.

$ kubectl argo rollouts promote rollout-bluegreen
$ kubectl get rs -l app=rollout-bluegreen
NAME                           DESIRED   CURRENT   READY   AGE
rollout-bluegreen-6565b74f44   0         0         0       5h35m
rollout-bluegreen-6b5dc99488   2         2         2       10m

이 방식을 응용하면 Deployment 로도 쉽게 배포 전략을 활용할 수 있다.

반응형
Posted by seungkyua@gmail.com
,
반응형

Argo rollout 은 Progressive Delivery 를 지원하는 툴이다.

아래의 그림에서 보듯이 Canary 배포를 진행할 때 일시적으로 배포를 홀딩한 상태에서 new version 에 대한 배포가 성공되었는지를 Metric 으로 판단하여 안전하게 배포를 완료할 수 있다. (metric 수집과 쿼리는 Prometheus 를 포함하여 다양한 모니터링 툴을 지원한다.)

 

 

Metric 을 통해 배포의 성공 여부를 판단하여 rollback 할 것인지, 계속 진행할 것인지를 결정할 수 있다는 것이 중요한 키 포인트다. 왜냐하면 쿠버네티스의 롤링 업데이트는 readiness 로 배포 성공여부를 판단하는데 이는 Metric 보다 판단하기에 부족할 수 있고, 중간에 에러가 발생하면 멈출 수 는 있지만 자동으로 rollback 되지는 않기 때문이다. 

Argo Quick 설치하기

# kubectl create namespace argo-rollouts
# kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

 

kubectl plugin 설치하기

# curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/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

 

 

Basic rollout 설치하기

# cd ~/argo-rollout-demo
# curl -Lo basic-rollout-blue.yaml https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/rollout.yaml
# curl -Lo basic-service.yaml https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/service.yaml

# kubectl apply -f basic-rollout-blue.yaml
# kubectl apply -f basic-service.yaml

# kubectl patch svc rollouts-demo --patch \
'{"spec": { "type": "NodePort", "ports": [ { "nodePort": 31080, "port": 80, "protocol": "TCP", "targetPort": "http", "name": "http" } ] } }'

 

 

화면 접속

http://k2-master01:31080

콘솔 보기

# kubectl argo rollouts get rollout rollouts-demo --watch

 

Basic rollout Canary 업그레이드

# kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow

rollout 전략이 처음 step 은 20% 만 변경하는 것이기 때문에 5개의 replica 중에 1개만 old version(blue) 이고 4 개는 new version(yellow) 이다. 그리고 현재는 pause (일시멈춤) 상태로 더이상 rollout 배포가 진행되지 않고 있다.

 

 

Basic rollout Canary 업그레이드 계속 진행

# kubectl argo rollouts promote rollouts-demo

 

promote 로 계속 rollout 업그레이드를 진행하면 점차 new version 이 revision:2 영역인 canary 로 replica 개수를 증가시키는 것을 볼 수 있다. duration 을 10으로 주었기 때문에 10 초 단위로 20% 씩 자동으로 올려준다.

 

일정 시간이 다 지나면 전체가 전부 다 업그레이드 된다.

 

argo rollout 은 metric 으로 정의한 성공 여부에 따라 배포를 계속 진행할 것인지 아니면 abort 시킬 것인지를 자동으로 결정할 수 있다.

 

출처: https://argoproj.github.io/argo-rollouts

반응형
Posted by seungkyua@gmail.com
,