Giới thiệu
Ở bài này chúng ta sẽ tìm hiểu về KEDA, một công cụ giúp ta trong việc scale các Pod trong Kubernetes một cách rất dễ dàng và cung cấp rất nhiều metrics phổ biến.
Mục lục
- KEDA
- High-level architecture
- Event sources.
- Install KEDA with Helm
- Scale with RabbitMQ
- Kết luận
- Bài viết liên quan
Khi ta sử dụng kubernetes, để scale một Pod ta thường sử dụng Horizontal Pod Autoscaling. Nhưng Horizontal Pod Autoscaling chỉ hỗ trợ ta scale theo một vài metrics đơn giản, ví dụ như là CPU hoặc Memory. Nếu ta muốn scale theo các metrics khác thì ta phải viết custom metrics khá phức tạp, ví dụ như là scale dựa theo Kafka topic. Thay vì phải tự viết thì ta có thể sử dụng KEDA để làm công việc này.
KEDA
KEDA (Kubernetes-based Event Driven Autoscaler) là một Custom Resource Definition mà ta có thể thêm vào một kubernetes cluster có sẵn. KEDA sẽ tương tác với Horizontal Pod Autoscaling ở bên dưới để mở rộng thêm function của HPA.
Với KEDA ta có thể scale một ứng dụng dựa vào event-driven, ví dụ như số lượng message bên trong RabbitMQ đạt tới một số lượng nhất định.
High-level architecture
Thì để hiểu rõ hơn về KEDA thì ta sẽ coi sơ qua kiến trúc high-level của nó.
KEDA bao gồm các thành phần cơ bản sau:
- Metrics adapter: thành phần hành động tương tự như kubernetes metrics server, mà sẽ expose các rich event data như queue length hoặc stream lag tới Horizontal Pod Autoscaler để xử lý việc scale
- Controller: thành phần thực hiện việc scale Pod về 0
- Scaler: đóng vai trò là một connector để kết nối tới external event source như kafka, rabbitmq và thu thập metric về
- ScaledObject: định nghĩa quan hệ giữa event source và workload resource (Deployment, StatefulSet)
Event sources.
KEDA hỗ trợ rất nhiều event sources, hỗ trợ với cả các resource của AWS và AZURE.
Các bạn có thể xem tất cả các event sources mà KEDA hỗ trợ ở đây.
Oke, ta nói lý thuyết đủ rồi, tiếp theo ta sẽ cài đặt KEDA lên trên Kubernetes Cluster của ta và làm thử một ví dụ scale theo RabbitMQ.
Install KEDA with Helm
Ta sẽ dùng Helm để cài KEDA, nếu các bạn chưa cài đặt Helm thì cài đặt Helm như sau.
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.shSau đó ta chạy các lệnh sau.
- Add Helm repo
helm repo add kedacore https://kedacore.github.io/charts- Update Helm repo
helm repo update- Install keda Helm chart
helm install keda kedacore/keda --namespace keda --create-namespaceNAME: keda
LAST DEPLOYED: Wed Apr 13 17:22:29 2022
NAMESPACE: keda
STATUS: deployed
REVISION: 1
TEST SUITE: NoneKiểm tra CRDs đã chạy chưa.
Scale with RabbitMQ
Ok, giờ ta sẽ tạo rabbitmq + consumer, sau đó tạo một ScaledObject mà chỉ định thông số để consumer scale theo số lượng message.
Các bạn tải code ở github sau https://github.com/hoalongnatsu/kubernetes-practice. Tạo RabbitMQ.
kubectl apply -f rabbitmq.yamlTạo consumer.
kubectl apply -f share-consume-queue.yamlKiểm tra consumer mà ta đã tạo.
kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
rabbitmq 1/1 1 1 10m
share-consume-queue 1/1 1 1 12sSau đó ta tạo ScaledObject.
kubectl apply -f scaled-object.yamlConfig của ScaledObject như sau.
Các bạn có thể đọc full cấu hình ở đây https://keda.sh/docs/2.6/scalers/rabbitmq-queue. Mình sẽ giải thích sơ qua các resource cần thiết để ta tạo ScaledObject với RabbitMQ.
Đầu tiên là Secret dùng để lưu connection tới rabbitmq, giá trị MQ_HOST là chuỗi base64 của connection string amqp://k8s-practice:[email protected]:5672/vhost, ta tạo ra nó bằng câu lệnh encode.
echo -n "amqp://k8s-practice:[email protected]:5672/vhost" | base64 -w 0Thứ hai là TriggerAuthentication resource, được Scaler dùng để tạo connection tới rabbitmq, giá trị của secretTargetRef sẽ gồm 3 thuộc tính là parameter, name, key. Với giá trị name là tên của Secret, key là giá trị key trong trường data của Secret.
Cuối cùng là ScaledObject, thành phần chính để config scale cho consumer. Với giá trị của scaleTargetRef là resource ta chọn để scale, còn giá trị triggers dùng để định nghĩa event mà ta dùng để thực hiện scale.
- type: rabbitmq
metadata:
mode: QueueLength
queueName: scale_out
value: "5"
vhostName: /
authenticationRef:
name: rabbitmq-trigger-authThuộc tính type ta chọn là rabbitmq, metadata.mode ta chỉ định giá trị là QueueLength, metadata.queueName là tên của queue ta theo dõi message của nó, mode.value là số lượng message tương ứng với một replica, số lượng replica sẽ được tính dựa theo số này. Ví dụ số lượng message là 30 thì ta sẽ scale lên 6 replica.
Giá trị của trường authenticationRef ta là tên của TriggerAuthentication. Sau khi ta tạo ScaledObject xong, lúc này nếu bạn kiểm tra lại Deployment thì bạn sẽ thấy share-consume-queue của ta đã scale xuống còn 0 replica.
kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
rabbitmq 1/1 1 1 19m
share-consume-queue 0/0 0 0 17mMột điểm mà KEDA khác với thằng HPA bình thường là nó cho phép ta scale một resource xuống còn 0 replica.
Bây giờ ta sẽ tạo Job để nó push message vào queue, sau đó ta sẽ kiểm tra coi consumer của ta có scale như ta đã nói hay không.
kubectl apply -f publisher-job.yamlapiVersion: batch/v1
kind: Job
metadata:
name: rabbitmq-publish
spec:
backoffLimit: 4
template:
spec:
restartPolicy: Never
containers:
- name: rabbitmq-client
image: 080196/k8s-practice-keda-send
env:
- name: QUEUE_LENGTH
value: "50"
envFrom:
- configMapRef:
name: share-consume-queueỞ trên ta send 50 message vào queue. Sau đó bạn get pod lại, lúc này ta sẽ thấy số lượng pod của ta đã tăng lên.
kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
rabbitmq 1/1 1 1 47m
share-consume-queue 4/4 4 4 46mKiểm tra resource HPA.
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-share-consume-queue Deployment/share-consume-queue 50/5 (avg) 1 100 1 28mLúc này thì pod của ta mới scale lên 4 pod, đợi một lúc bạn get lại Deployment thì sẽ thấy nó đã scale lên 10 replica.
kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
rabbitmq 1/1 1 1 49m
share-consume-queue 10/10 10 10 47mĐợi một lát khi consumer tiêu thụ hết message trong queue, lúc này pod của ta sẽ scale xuống lại.
kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
rabbitmq 1/1 1 1 52m
share-consume-queue 0/0 0 0 50mkubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
keda-hpa-share-consume-queue Deployment/share-consume-queue 0/5 (avg) 1 100 10 32mOke, ta đã thực hiện thành công 😁.
Kết luận
Vậy ta là ta đã tìm hiểu xong cơ bản về Kubernetes based Event Driven Autoscaler, như bạn thấy nó khá đơn giản mà rất hữu dụng. Nếu có thắc mắc hoặc cần giải thích ở chỗ nào thì các bạn hỏi ở đây nha: bình luận.
Tác giả @Quân Huỳnh
First AI Journey for DevOps:
- PromptOps: From YAML to AI
- The DevOps AI Advantage
- The AIOps Book
