KubeCon2022 - KEDA - Real Time and Serverless Scaling in Kubernetes
https://youtu.be/vjKLbfEZ7MU?si=X_RLkD6Ww5ij7MJp
발표자
- Jeff Hollan: Snowflake Product Director. 그전엔 MS에서 Azure Function Lead로 10년 정도 일했었고, KEDA founding memeber.
- Zbynek Roubalik: RedHat Engineer. KEDA founding member. Knative maintainer.
예컨대 KubeCon에 참여한 모든 사람들에게 피자를 제공해야 한다고 하자.
- Strategy 1: 피자가 부족할 때마다 한 판씩 주문한다.
- Strategy 2: 참여자가 얼마나 있는지 확인해서, 예상되는 양을 미리 주문한다.
Strategy 1을 쓰면, KubeCon 참가자가 많을 경우 뒷사람은 몇 시간을 기다려야 할 수도 있다.
두 개 선택지에서 많은 사람들은 2번 전략을 선택한다. 그런데 scaling 관점에서는, 1을 선택하는 경우가 매우 많다.
- 일단 배포하고, CPU / Memory 모니터링. 필요하다 싶으면 약간 더 할당하는 식.
- scale based on Event, which is causing the consumption in the CPU / Memory.
- 55+ integrated Event Source (Prometheus, RabbitMQ, Kafka, SQS...) https://keda.sh 에서 확인 가능,
- Seamlessly put it into any architecture in K8s.
Demo (7:24 ~ )
- RabbitMQ: 메시지 큐
- Deployment: mq 메시지 핸들링
- KEDA: rabbitmq에 남아 있는 메시지 개수 확인 -> scale Deployment.
- HPA 사용.
애플리케이션은 KEDA와 어떤 Dependency도 없다. KEDA의 존재도 모름. 코드 변경할 필요도 없다.
---
...
# event source 정의, what I want
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: rabbitmq-consumer
namespace: default
spec:
scaleTargetRef:
name: rabbitmq-consumer # rabbitmq-consumer 라는 deployment를 scale 대상으로 정의.
pollingInterval: 5 # Optional. default 30s
cooldownPeriod: 30 # Optional. default 300s
maxReplicaCount: 30 # Optional. default 100
fallback: # Optional. specify fallback options
failureThreshold: 1 # mandatory if fallback section is included
replicas: 4 # rabbitmq 통신에 문제가 생겼을 경우, 4 replica로 실행하라는 뜻.
triggers:
- type: rabbitmq
metadata:
queueName: hello
queueLength: "5" # container당 5 messages.
authenticationRef:
name: rabbitmq-consumer-trigger # authentication 관련 설정은 여기에 이름으로 명시하고, 자세한 설정은 별도의 CR로 배포한다.
...
메시지가 없을 경우 scale 0으로 내려가고, rabbitmq에 메시지 전달하는 Job을 실행하자 scale out되는 것을 볼 수 있다.
Architecture
- Built on Top of Kubernetes
- 핵심 CR은 ScaledObject / ScaledJob.
- 컴포넌트는 크게 두 가지. Controller와 KEDA Matrics Adapter
ScaledObject를 생성하면
- metadata 정보 토대로 HPA 배포.
- scale out 기준이 되는 external service (위 예시의 경우 RabbitMQ) 와 통신할 adapter 배포.
HPA 자체는 scale 0가 불가능하다.
- scale 0는 KEDA Operator가 수행한다.
- zero to one 과정을 activatino phase라고 부르며, threshold 설정이 가능하다.
- zeron to one에 필요한 metric 정보를 HPA에 제공해서, HPA가 동작하도록 만드는 셈.
Components
ScaledObject
- Scale 대상으로 deployment, statefulset, /scale 이 구현되어 있는 custom resource에 적용 가능
- multiple scaler 설정 가능. kafka, prometheus 등 여러 event source를 하나의 deployment의 scaler로 쓸 수 있다.
- metric을 HPA에 전달하고, scale 동작은 HPA에 맡기는 식.
ScaledJob
- 이벤트 기반으로 deployment와 같은 application이 아니라 job을 생성하는 것. 따라서 Long-running process에 적합.
- target에 deployment가 아니라 k8s job을 명시하면 된다.
사용법 간단하다. 문법도 익숙하고, k8s object에 ScaledObject 붙이면 됨.
Advanced Features
- scaling window를 설정하거나, replica Number를 지정할 수 있다.
- Metric의 변동이 심할 경우, pod도 계속 up / down을 반복하게 되는 문제 해결.
- Pause Autoscaling 가능. annotation 명시하면 된다.
- Scaling 관련 로직의 Observability를 위해 Prometheus metric 제공. 계속 개선 중임.
- External Scaler 직접 구현해서 쓸 수 있는 interface 제공함. gRPC 형태.
Authentication
외부 MQ 등 External Service와 통신하기 위한 Authentication 지원.
- Secrets, Vaults, Pod Identity
- Namespace 단위로 관리 -> 같은 NS의 여러 ScaledObject 관리할 수 있다.
- Cluster Wide로도 설정 가능.
What's Next?
Cache Metrics values in KEDA Metrics Server.
- HPA가 요청할 때마다 수집해서 보내고 있는데, 이러면 수많은 ScaledObject가 동일한 external Service 기반으로 scale하기 어려운 구조.
- 예컨대 하나의 prometheus Server만 보고 있는 경우라던가... high Load.
- Smoother Autoscaling
- Multiple Trigger 간 Custom Logic
- 예컨대 하나의 deployment에 RabbitMQ, CPU, Memory 등 여러 조건이 scale trigger로 걸려 있다면, 같은 조건이 여러 개 충족될 경우 무엇이 우선순위인지?
- 지금은 whatever number is biggest 하나뿐인 걸로 아는데, custom logic이 필요함.
- cloudevent integration
- prometheus와는 잘 연동되어 있음. scaling based on Prometheus time-series Query 등등.
- KEDA 자체적으로 cloudevent emit한다던가, 외부에서 발생시킨 cloudevent를 사용하고 싶다던가..
- OpenTelemtry integration
- Predictive Autoscaling
- 외부로부터 이벤트를 받기 때문에, incoming metric 기반으로 predict actual state 한다던가...
- predict 결과 매주 월요일에 얼만큼 scale out 해둬야 한다던가. 그런 것들
자원 효율적으로 동작할 수 있는 autoscaler라서... 탄소중립적인 프로젝트에도 PoC 진행 중. (Carbon Aware Autoscaling)
Q. Prometheus Metric Server에 설정한 interval은 얼마인지? 정확히는 poolingInterval 이라는 필드의 뜻
- activation phase에서만 사용됨 (for the operator). zero to one으로 넘어가는 initial scale에서만 쓰인다.
- interval 마다 metric 수집 요청 보내는 건 HPA가 담당함.
Q. Knative와의 차이는?
- Complimentary tool. KEDA는 Message System을 쓰기에 pull-base / push-base 둘 중 하나일 수밖에 없음.
- pull일 경우, external source와의 통신 로직이 application 내부에 있어야 한다. 현재 HPA, KEDA의 방식.
- push의 경우, incoming request만 기다리면 된다.
- Depends on Usecase. 예컨대 HTTP request는 근본적으로 push based이므로, KEDA보다는 Knative가 좀더 적합하다.
Q. KEDA가 적합한 Workload 예시는 뭐가 있을지? 예시만 보면 MQ의 이벤트가 homogeneous여야 할 거 같은데, heterogeneous jobs인 경우엔?
- KEDA의 이상적인 예시는 independent pod 간 Horizontal Scale인 것.
- 예컨대 transcode video 돌리는 Job. (1 job per video, long processing)
- 다양한 이벤트 타입이나 이벤트 내용을 보고 핸들링하는 건 knative eventing 쪽이 좀더 맞을 듯. KEDA는 이벤트 내부 데이터 정보는 보지 않는다.
Q. KEDA는 scale 하나?
- No. metric server는 k8s 서버에 한 대만 설치되기에, KEDA 컴포넌트를 scale한다 해도 same metric server를 호출함.
- upstream으로 proxy를 붙인다던가 개선 방법이 있겠지만, 지금은 X.
Q. is there a time you've switched to using gcp's cloud function or AWS's lambda?
- (KEDA와 관련있는건 아니고 단순 의견을 물어본 거 같음)
- Azure Function 관리자였고, Snowflake에서 multi-cloud 환경을 사용하는 입장에서 답하자면
- 둘다 개좋음. 다른 프로덕트 올라가 있는 cloud provider 따라가면 된다. GCP 쓰고 있다면 cloud function, AWS 쓰고 있으면 lambda.
- 잘 모르겠으면? snowflake로 와라 ㅎㅎ