-
Notifications
You must be signed in to change notification settings - Fork 1
7) How to keep traffic to pod during update (Rollouts Pod Template Hash)
2022.04. 이장재 📧 cine0831@gmail.com 📂 https://github.com/jangjaelee 📒 http://www.awx.kr
Argo Rollouts의 Rollout resource로 애플리케이션(Pods)를 생성하고 새 애플리케이션(new Pods)을 업데이트 하게 되었을때 새 애플리케이션(new Pods)과 이전 애플리케이션(old Pods)을 찾아가는 원리(mechanism)는 어떻게 되는지 알아봅니다.
Rollout resource(object)는 대부분이 Deployment resource 규격과 구성이 동일하며, strategy 부분에 차이가 있습니다.
또한, 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://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#LabelSelector
- https://pkg.go.dev/k8s.io/api/core/v1#PodTemplateSpec
📄 https://github.com/argoproj/argo-rollouts/blob/master/pkg/apis/rollouts/v1alpha1/types.go
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
다음은 Rollout와 Deployment의 Specification에 대한 type.go soruce code 구조체 입니다.
그렇다면 Rollout에 의해 Blue/Green 그리고 Canary 배포 전략으로 새 애플리케이션의 업데이트가 진행되면 어떻게 새 애플리케이션과 이전 애플리케이션를 구분하여 트래픽이 라우팅 될까요?
해답은 rollouts-pod-templat-hash
필드에 정의한 해시(hash) 레이블에 있습니다.
Rollout도 Deployment와 비슷하게 Service, ReplicaSet 그리고 Pod에 metadata.labels
와 spec.selector.matchLabels
의 rollouts-pod-templat-hash
필드 지시자에 해시(hash) 레이블을 주입하여 Pod를 찾아가게 됩니다.
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-hash
와 pod-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-hash
와 pod-template-hash
가 주입된 것을 알 수 있습니다.
rollouts-pod-template-hash
필드가 Argo Rollouts의 어느 Source Code에 의해서 제어가 되는지 아주 간략하게 알아보겠습니다.
rollouts-pod-template-hash
필드는 pkg/apis/rollouts/v1alpha1/types.go
에 DefaultRolloutUniqueLabelKey
상수의 value로 선언 되어지며,
📄 https://github.com/argoproj/argo-rollouts/blob/master/pkg/apis/rollouts/v1alpha1/types.go
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
service/service.go Source Code는 Service resource에서 삽입된 selector를 제거하는 로직이 구현되어 있습니다.
📄 https://github.com/argoproj/argo-rollouts/blob/master/service/service.go
지금까지 Rollout이 어떻게 Pod까지 트래픽 라우팅을 결정하고 유지하는지 그리고 Rollout와 Deployment에 대한 차이점을 알오 보았습니다.
- Website
- GitHub
-
https://github.com/argoproj/argo-rollouts
- for AppMesh
- https://github.com/argoproj/argo-rollouts/tree/master/rollout/trafficrouting/appmesh
- https://github.com/argoproj/argo-rollouts/pull/1606https://github.com/argoproj/argo-rollouts/pull/1606
- https://github.com/argoproj/argo-rollouts/commit/5f0f8b4558467f5a1a09e7d08057ccf9973c01c7https://github.com/argoproj/argo-rollouts/commit/5f0f8b4558467f5a1a09e7d08057ccf9973c01c7
- DefaultRolloutUniqueLabelKey string = "rollouts-pod-template-hash”
- https://github.com/argoproj/argo-rollouts/blob/master/pkg/apis/rollouts/v1alpha1/generated.proto
- for AppMesh
-
https://github.com/argoproj/argo-rollouts
- Artifact Hub
- Slack
- https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#pod-template-hash-label
- https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#canary-deployment
- https://velog.io/@gentledev10/kubernetes-deployment
- https://baeji77.github.io/dev/book/9.deployment/
- https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/apps/types.go
- https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/deployment/sync.go
- https://github.com/kubernetes/api/blob/master/apps/v1/generated.proto
- https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#LabelSelector
- https://pkg.go.dev/k8s.io/api/core/v1#PodTemplateSpec
END