Skip to content

7) How to keep traffic to pod during update (Rollouts Pod Template Hash)

Alex, Lee edited this page Apr 27, 2022 · 5 revisions

2022.04. 이장재 📧 cine0831@gmail.com 📂 https://github.com/jangjaelee 📒 http://www.awx.kr


 

Overview

Argo Rollouts의 Rollout resource로 애플리케이션(Pods)를 생성하고 새 애플리케이션(new Pods)을 업데이트 하게 되었을때 새 애플리케이션(new Pods)과 이전 애플리케이션(old Pods)을 찾아가는 원리(mechanism)는 어떻게 되는지 알아봅니다.

 

Rollout Specification Configuration

Rollout vs Deployment

Rollout resource(object)는 대부분이 Deployment resource 규격과 구성이 동일하며, strategy 부분에 차이가 있습니다.

Rollout_vs_Deployment-01.png

또한, Rollout은 Deployment와 마찬가지로 Rollout을 생성하면 Kubernetes Core Resource의 ReplicaSet과 Pod가 배포되며, source를 열어보면 ReplicaSet와 Pod의 생성과 MatchLabels을 위해 metav1.LabelSelector([https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#LabelSelector](https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#LabelSelector))corev1.PodTemplate([https://pkg.go.dev/k8s.io/api/core/v1#PodTemplateSpec](https://pkg.go.dev/k8s.io/api/core/v1#PodTemplateSpec)) 를 사용하고 있다는 것을 알 수 있습니다.

📄 https://github.com/argoproj/argo-rollouts/blob/master/pkg/apis/rollouts/v1alpha1/types.go

argo_rollouts-Rollout_spec_type-go-source-01.png

 

Kubernetes Deployment도 source를 열어 보면 new Deployment를 생성할 때 metav1.LabelSelector([https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#LabelSelector](https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#LabelSelector))corev1.PodTemplate([https://pkg.go.dev/k8s.io/api/core/v1#PodTemplateSpec](https://pkg.go.dev/k8s.io/api/core/v1#PodTemplateSpec)) 를 사용하고 있습니다.

📄 https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/apps/types.go

Compre type.go between Rollout and Deployment of Specification

다음은 Rollout와 Deployment의 Specification에 대한 type.go soruce code 구조체 입니다.

Rollout_vs_Deployment-02.png

 

Look at Rollout Pod Template Hash

그렇다면 Rollout에 의해 Blue/Green 그리고 Canary 배포 전략으로 새 애플리케이션의 업데이트가 진행되면 어떻게 새 애플리케이션과 이전 애플리케이션를 구분하여 트래픽이 라우팅 될까요?

해답은 rollouts-pod-templat-hash 필드에 정의한 해시(hash) 레이블에 있습니다.

Rollout도 Deployment와 비슷하게 Service, ReplicaSet 그리고 Pod에 metadata.labelsspec.selector.matchLabelsrollouts-pod-templat-hash필드 지시자에 해시(hash) 레이블을 주입하여 Pod를 찾아가게 됩니다.

Rollouts-Pod-Template-Hash.png

Rollout Pod Template Hash (Rollout) vs Pod Template Hash (Deployment)

Deployment도 ReplicaSet에 Pod를 찾기 위해 Pod Template Hash 레이블을 사용 하며, RollingUpdate 배포 전략을 통해 애플리케이션을 업데이트 할 때도 사용됩니다.

Rollout의 rollout-pod-template-hash와 Deployment의 pod-template-hash가 Selector와 Labels에 어떻게 적용 되어 있는지 살펴 보겠습니다.

여기 nginx-demo 이름의 rollout과 deployment 리소스가 각각 있습니다.

replicaset.apps/nginx-demo-7fccd77ccb는 rollout에 의해 생성 되었으며, replicaset.apps/nginx-demo-679fcb9b68는 deployment에 의해 생성 된 것 입니다.

$ kubectl get deployment,rollout,replicaset
NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-demo   3/3     3            3           15m

NAME                             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
rollout.argoproj.io/nginx-demo   3         3         3            3           5h13m

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-demo-679fcb9b68   3         3         3       15m
replicaset.apps/nginx-demo-7fccd77ccb   3         3         3       5h7m

각 ReplicaSet을 describe 해보면 다음과 같습니다.

# from Rollout
$ kubectl describe replicaset.apps/nginx-demo-7fccd77ccb | head -n5
Name:           nginx-demo-7fccd77ccb
Namespace:      default
Selector:       app=nginx-demo,rollouts-pod-template-hash=7fccd77ccb
Labels:         app=nginx-demo
                rollouts-pod-template-hash=7fccd77ccb

# from Deployment
$ kubectl describe replicaset.apps/nginx-demo-679fcb9b68 | head -n5
Name:           nginx-demo-679fcb9b68
Namespace:      default
Selector:       app=nginx-demo,pod-template-hash=679fcb9b68
Labels:         app=nginx-demo
                pod-template-hash=679fcb9b68

describe로 보는 바와 같이 Selector와 Labels에 각각 ReplicaSet를 구분 할 수 있는 rollout-pod-template-hashpod-template-hash가 각각 주입된 것을 알 수 있습니다.

Pod 리스트를 출력하면 Rollout와 Deployment로 배포된 ReplicaSet에 묶어진 Pods의 이름은 다음의 규칙으로 배포 됩니다.

  • Rollout로 생성된 Pods는 --
  • Deployment로 생성된 Pods는 --
$ kubectl get pod
NAME                          READY   STATUS    RESTARTS   AGE
nginx-demo-679fcb9b68-hjvbh   1/1     Running   0          37m
nginx-demo-679fcb9b68-nqpz7   1/1     Running   0          37m
nginx-demo-679fcb9b68-qpzpn   1/1     Running   0          37m
nginx-demo-7fccd77ccb-2rx56   1/1     Running   0          5h28m
nginx-demo-7fccd77ccb-62f9x   1/1     Running   0          5h29m
nginx-demo-7fccd77ccb-lgpqw   1/1     Running   0          5h28m

그러면 Pod의 Lebels을 통해 차이점을 확인 해보겠습니다.

# pod from Rollout
$ k describe pod/nginx-demo-7fccd77ccb-lgpqw | head -n10
Name:         nginx-demo-7fccd77ccb-lgpqw
Namespace:    default
Priority:     0
Node:         k8s-w2-dragon/192.168.1.112
Start Time:   Wed, 27 Apr 2022 13:08:42 +0900
Labels:       app=nginx-demo
              rollouts-pod-template-hash=7fccd77ccb
Annotations:  cni.projectcalico.org/containerID: 2d06be944bb3e27ecccc0d1ba9f7da3f9c5fdf31cdcad7ec56fa653cdd21bbc7
              cni.projectcalico.org/podIP: 172.16.10.104/32
              cni.projectcalico.org/podIPs: 172.16.10.104/32

# pod from Deployment
$ kubectl describe pod/nginx-demo-679fcb9b68-hjvbh | head -n10
Name:         nginx-demo-679fcb9b68-hjvbh
Namespace:    default
Priority:     0
Node:         k8s-w2-dragon/192.168.1.112
Start Time:   Wed, 27 Apr 2022 18:00:06 +0900
Labels:       app=nginx-demo
              pod-template-hash=679fcb9b68
Annotations:  cni.projectcalico.org/containerID: 5fdfbcedf1792a4263528665ea798694033a899fa1170ee2611ec3c8d7fa3520
              cni.projectcalico.org/podIP: 172.16.10.112/32
              cni.projectcalico.org/podIPs: 172.16.10.112/32

Pod 또한 ReplicaSet와 마찬가지로 Selector와 Labels에 각각 rollout-pod-template-hashpod-template-hash가 주입된 것을 알 수 있습니다.

 

Source Code로 보는 Rollouts의 rollouts-pod-template-hash

rollouts-pod-template-hash필드가 Argo Rollouts의 어느 Source Code에 의해서 제어가 되는지 아주 간략하게 알아보겠습니다.

rollouts-pod-template-hash 필드는 pkg/apis/rollouts/v1alpha1/types.goDefaultRolloutUniqueLabelKey 상수의 value로 선언 되어지며,

📄 https://github.com/argoproj/argo-rollouts/blob/master/pkg/apis/rollouts/v1alpha1/types.go

argo_rollouts_source-types_go-01.png

Rollout의 배포 전략 Blue/Green과 Canary으로 업데이트가 진행 될 때 Service resource의 selector에 labels 삽입 할 때 rollouts-pod-template-hash와 hash를 함께 삽업하여, 트래픽 라우팅이 Pod를 찾아갈 수 있게 정의 하게 됩니다.

rollout/service.go Source Code는 Rollout이 생성될 때 Service resource에 selector의 삽입과 변경하는 로직이 구현되어 있습니다.

📄 https://github.com/argoproj/argo-rollouts/blob/master/rollout/service.go

argo_rollouts_source-rollout-service_go-01.png

service/service.go Source Code는 Service resource에서 삽입된 selector를 제거하는 로직이 구현되어 있습니다.

📄 https://github.com/argoproj/argo-rollouts/blob/master/service/service.go

argo_rollouts_source-service-service_go-01.png

지금까지 Rollout이 어떻게 Pod까지 트래픽 라우팅을 결정하고 유지하는지 그리고 Rollout와 Deployment에 대한 차이점을 알오 보았습니다.

 

Official Website

 

References

 

Kubernetes Source

 

END