[미완성] AWS Loadbalancer 와 argo rollout 의 내부동작
argo rollout 의 canary 배포는 Rollout 오브젝트에서 canary service와 stable service 를 지정하여 stable -> canary 로 트래픽 %를 시간대별로 상세하게 지정하는 방식으로 rollout 을 지원한다. 이러한 내용이 현실적으로 구현되려면 AWS의 Loadbalancer와 Target Group에서 해당 구현이 가능해야 하는데, Loadbalancer의 weighted-target-group 이라고 하는 기능으로 실제 구현된다!(argo rollout 이 해당 기능을 실제로 사용하여 구현)
aws load balancer 에는 listener 와 rule, action 으로 구성되어있고. 특정 rule 의 action중에 복수의 target groups 사이에 트래픽분배 %를 지정하여 트래픽분배하는 기능이 있다 - https://aws.amazon.com/ko/blogs/aws/new-application-load-balancer-simplifies-deployment-with-weighted-target-groups/
어떻게 이 기능이 수행되는지에 대해서는..
1. rollout이 진행될 때, steps의 각 단계에 맞춰 argo rollout controller가 해당 pod의 트래픽에 관여하는 ingress의 annotation을 동적으로 변경시켜 canary service, stable service 간에 트래픽 분배% 설정을 적용한다
2. 이 설정값은 aws loadbalancer controller에 의해 포착되어 실제 ALB에 반영 된다(weighted-target-groups)
3. 결과적으로 실시간으로 완만하게 트래픽을 이동시키는 기능이 정상 수행된다
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/actions.{{service}}-game-root-svc: '{
"Type": "forward",
"ForwardConfig": {
"TargetGroups": [
{
"ServiceName": "{{service}}-game-canary-svc",
"ServicePort": "443",
"Weight": 1
},
{
"ServiceName": "{{service}}-game-stable-svc",
"ServicePort": "443",
"Weight": 99
}
],
"TargetGroupStickinessConfig": {
"Enabled": true,
"DurationSeconds": 120
}
}
}'
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:431124633566:certificate/628a9f72-235d-4795-a0b7-8b9762a80b21
~~~
~~~
위 ingress manifest는 실제 rollout 이 진행될때 ingress의 설정 스냅샷이다. 2가지를 관찰할 수 있다.
1. {{service}}-game-canary-svc 에는 weight 가 1, {{service}}-game-stable-svc 에는 weight가 99 인 것 -> 즉, 카나리엔 1% 스테이블엔 99%의 traffic 배분설정 되어있음
2. TargetGroupStickinessConfig true 설정 -> 두 타겟그룹단위로 스티키세션 설정
위 1,2번 설정은 aws-load-balancer-controller에 의해 실제 ALB에 적용되어 rollout 구현된다.
1번에 대해 더 상세하게 이야기 해보자면..
이때 rollout 의 배포란에 적용된 canary service에 새로운 pod들이 배치되게 되며, alb를 동적으로 조작하여 기술한 %만큼의 트래픽이 새로운 service(target group)으로 흘러가도록 수정한다. argo rollout 이 rollout 기능을 수행할때 alb에 실제로 해당 기능을 수행하게 하기 위해
alb.ingress.kubernetes.io/actions.${actionName} 어노테이션에 상세한 트래픽 분산 설정을 해놓는다.(service.port.name은 use-annotation으로 해야 위 설정을 먹임) https://guide-fin.ncloud-docs.com/docs/k8s-k8suse-albingress#alb-ingress-controller-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98
1번의 annotation 부분의 설정은, “해당 ingress의 rule중에{{service}}-game-root-svc를 서비스로 갖는 rule의 action을 수정하라. 수정내용은 ~~ 게 하라” 는 의미이다.
실제 Target Group 간에 트래픽 변경되는 과정
rollout이 진행되면, Rollout 오브젝트에 기술한 canary, stable service간에 실질적인 트래픽 분산이 이루어진다. EKS에서 service는 AWS의 target group으로 구현되기에, 실제로 AWS의 target group 간에 트래픽이 옮겨가게 되는 것이다. 우선 steps가 아래와 같다고 가정한다.
1. setWeight: 1
2. pause: {}
3. setWeight: 100
각 과정의 전후에서 canary와 stable service의 트래픽 %는 아래처럼 된다
1 시작 전
카나리service: 0%
스테블service: 100%
1 끝난 후
카나리service: 1%
스테블service: 99%
3 끝난 직후
카나리service: 100%
스테블service: 0%
3 끝난 후
카나리service: 0%
스테블service: 100%
3 끝난 직후 까지는 매우 예측가능하며 정상적이다. steps의 3번을 보면 setWeight 이 100이므로, canary 서비스가 100%를 가져가는것이 맞으니. 그런데 3이 끝나고 살짝 시간이 지나면, 스테블 service가 어느새 트래픽을 100% 먹고 있다. 즉, rollout이 끝났으니 정상상태로 돌아가야 하고, 따라서 스테블 service가 트래픽을 100% 먹도록 트래픽을 다시!!! 스테블 service로 돌려놓는 것이다!
target group 의 실제 동작으로는,
3번이 끝난 후 stable 타겟그룹은 카나리 타겟그룹에 속한 instance 들을 그대로 register하고(카나리 복붙), 기존의 stable instance 들을 deregister 하고, 바로 모든 트래픽을 먹게 된다! 따라서 일시적으로 아래와 같은 상황이 연출된다!
여기서 initiali은 canary target group 에서 갖고있던 pod들이다(새로운 배포 버전 pod)
여기서 draining 은 기존에 stable target group 에서 갖고있던 pod들이다(이전 배포 버전 pod)
이상태로 100%의 트래픽을 받게 된다. 워낙 짧은 순간이라(initiali 이 곧 health 가 되기에) 문제가 없어 보이지만,, 위 상태로만 본다면 initiali pod들이 트래픽을 잘 받을 수 있을지에 대해서... 추가 조사가 필요해 보인다.
참고
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html
What is an Application Load Balancer? - Elastic Load Balancing
What is an Application Load Balancer? Elastic Load Balancing automatically distributes your incoming traffic across multiple targets, such as EC2 instances, containers, and IP addresses, in one or more Availability Zones. It monitors the health of its regi
docs.aws.amazon.com
https://argo-rollouts.readthedocs.io/en/latest/features/traffic-management/alb/
AWS ALB - Argo Rollouts - Kubernetes Progressive Delivery Controller
AWS Load Balancer Controller (ALB) Requirements AWS Load Balancer Controller v1.1.5 or greater Overview AWS Load Balancer Controller (also known as AWS ALB Ingress Controller) enables traffic management through an Ingress object, which configures an AWS Ap
argo-rollouts.readthedocs.io