Thiết lập nhanh: Triển khai KEDA trong 5 phút
Horizontal Pod Autoscaler (HPA) mặc định của Kubernetes hoạt động rất hiệu quả cho các dịch vụ HTTP phụ thuộc vào CPU hoặc bộ nhớ. Tuy nhiên, các worker xử lý hàng đợi bất đồng bộ lại là một câu chuyện hoàn toàn khác. Một worker thread có thể chỉ dùng 12% CPU trong khi có tới 50.000 tác vụ mã hóa video đang tồn đọng. Ngược lại, một tác vụ tính toán nặng duy nhất có thể đẩy CPU lên 95%, kích hoạt scale-out không mong muốn ngay cả khi hàng đợi đang trống rỗng.
Kubernetes Event-driven Autoscaling (KEDA) giải quyết triệt để khoảng cách này. KEDA vừa đóng vai trò là một custom metrics server, vừa là một lifecycle controller. KEDA giám sát trực tiếp các hàng đợi bên ngoài, tự động khởi tạo pod khi có tác vụ đến và thu nhỏ deployment về 0 (scale to zero) khi hàng đợi không hoạt động—giúp tiết kiệm chi phí hạ tầng cho các worker node nhàn rỗi.
1. Cài đặt KEDA qua Helm
Cài đặt KEDA trên bất kỳ cụm Kubernetes nào (v1.27+) bằng Helm chart chính thức:
# Thêm và cập nhật repository KEDA Helm
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
# Triển khai KEDA vào namespace riêng
helm install keda kedacore/keda \
--namespace keda \
--create-namespace \
--set metricsServer.dnsPolicy=ClusterFirstWithHostNet
2. Kiểm tra cài đặt
Kiểm tra xem cả operator pod và metrics API server pod đã khởi chạy thành công chưa:
kubectl get pods -n keda
# Kết quả mong đợi:
# NAME READY STATUS RESTARTS AGE
# keda-operator-7b6494cb68-x28qf 1/1 Running 0 45s
# keda-operator-metrics-apiserver-585474775d-n4vwx 1/1 Running 0 45s
Các khái niệm cốt lõi và Scaler trong môi trường Production
KEDA dựa trên hai Custom Resource Definition (CRD) chính:
- ScaledObject: Ánh xạ một nguồn sự kiện (như RabbitMQ hoặc SQS) tới Deployment hoặc StatefulSet của bạn, xác định ngưỡng bản sao tối thiểu/tối đa và chỉ số mục tiêu.
- TriggerAuthentication: Lưu trữ thông tin xác thực, chuỗi kết nối hoặc IAM role trên đám mây tách biệt khỏi manifest triển khai ứng dụng.
Khả năng co giãn từ 0 lên 1 (Zero-to-one scaling) được KEDA xử lý trực tiếp. Khi pod đầu tiên đã hoạt động, KEDA sẽ chuyển giao các chỉ số cho Kubernetes HPA tiêu chuẩn để quản lý việc scale-out từ 1 lên N bản sao.
1. Co giãn theo độ dài hàng đợi RabbitMQ
Xét một dịch vụ thay đổi kích thước hình ảnh xử lý các tác vụ từ hàng đợi RabbitMQ có tên là image-tasks. Mục tiêu: cấp phát 1 Pod cho mỗi 30 tin nhắn tồn đọng, giới hạn tối đa ở mức 20 bản sao.
apiVersion: v1
kind: Secret
metadata:
name: rabbitmq-credentials
namespace: default
type: Opaque
data:
# Chuỗi Base64 cho: amqp://user:[email protected]:5672/vhost
host: YW1xcDovL3VzZXI6cGFzc3dvcmRAcmFiYml0bXEuZGVmYXVsdC5zdmMuY2x1c3Rlci5sb2NhbDo1NjcyL3Zob3N0
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: rabbitmq-trigger-auth
namespace: default
spec:
secretTargetRef:
- parameter: host
name: rabbitmq-credentials
key: host
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: image-processor-scaler
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: image-processor
minReplicaCount: 0
maxReplicaCount: 20
pollingInterval: 15
cooldownPeriod: 60
triggers:
- type: rabbitmq
metadata:
queueName: image-tasks
mode: QueueLength
value: "30"
authenticationRef:
name: rabbitmq-trigger-auth
2. Co giãn theo Lag của Consumer Group trong Apache Kafka
Co giãn Kafka nhắm vào độ trễ (lag) của consumer group thay vì số lượng tin nhắn thô. KEDA truy vấn offset phân vùng trên broker và tính toán tổng lag chưa commit trên các consumer đang hoạt động.
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: telemetry-consumer-scaler
namespace: default
spec:
scaleTargetRef:
name: telemetry-consumer
minReplicaCount: 1
maxReplicaCount: 16
pollingInterval: 10
triggers:
- type: kafka
metadata:
bootstrapServers: kafka-cluster-kafka-bootstrap.kafka.svc:9092
consumerGroup: telemetry-workers
topic: device-telemetry
lagThreshold: "100"
offsetResetPolicy: latest
3. Co giãn trên AWS SQS với IAM Roles (IRSA)
Tránh sử dụng AWS access key tĩnh trong Kubernetes secret. Khi chạy trên Amazon EKS, hãy xác thực KEDA bằng IAM Roles for Service Accounts (IRSA) hoặc EKS Pod Identity.
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: keda-aws-sqs-auth
namespace: default
spec:
podIdentity:
provider: aws-eks
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: order-processor-scaler
namespace: default
spec:
scaleTargetRef:
name: order-processor
minReplicaCount: 0
maxReplicaCount: 50
triggers:
- type: aws-sqs-queue
metadata:
queueURL: https://sqs.us-east-1.amazonaws.com/123456789012/order-processing-queue
queueLength: "10"
awsRegion: us-east-1
authenticationRef:
name: keda-aws-sqs-auth
Tinh chỉnh hành vi Autoscaling
1. Ngăn ngừa hiện tượng Pod Flapping
Lượng tin nhắn tăng đột biến theo từng đợt có thể gây ra vòng lặp co giãn liên tục (flapping). Các pod khởi tạo nhanh chóng, xử lý sạch hàng đợi trong vài giây, bị hủy ngay lập tức và sau đó lại khởi động lại khi có đợt tin nhắn tiếp theo. Hãy ổn định các thao tác scale-down bằng cách tinh chỉnh hành vi HPA trực tiếp bên trong ScaledObject:
spec:
advanced:
horizontalPodAutoscalerConfig:
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
2. Kết hợp Trigger hàng đợi với CPU dự phòng (Fallback)
KEDA hỗ trợ kết hợp nhiều trigger trên cùng một workload. Khi định nghĩa nhiều chỉ số, controller sẽ tính toán mục tiêu cho từng trigger một cách độc lập và chọn giá trị tạo ra số lượng bản sao lớn nhất:
spec:
triggers:
- type: rabbitmq
metadata:
queueName: high-priority-jobs
mode: QueueLength
value: "10"
authenticationRef:
name: rabbitmq-trigger-auth
- type: cpu
metadata:
type: Utilization
value: "75"
Những lưu ý quan trọng trong môi trường Production
Vận hành các ứng dụng hướng sự kiện ở quy mô lớn tiềm ẩn một số bẫy kỹ thuật. Hãy ghi nhớ ba nguyên tắc sau trước khi đưa hệ thống vào hoạt động chính thức:
1. Cân đối Kafka Partition với số lượng Replica tối đa
Một partition trong Kafka chỉ có thể được đọc bởi một consumer trong cùng một consumer group. Nếu topic có 12 partition mà bạn cấu hình maxReplicaCount: 30, 18 pod sẽ tiêu tốn CPU và RAM nhưng không xử lý bất kỳ công việc nào. Hãy giới hạn maxReplicaCount khớp với số lượng partition.
2. Bảo vệ các tác vụ đang thực thi khi Scale-Down
Kubernetes gửi tín hiệu SIGTERM khi chấm dứt các bản sao. Nếu worker đang chạy được 40 giây trong một tác vụ kéo dài 60 giây, việc dừng tiến trình ngay lập tức sẽ gây mất kết nối hoặc xử lý trùng lặp dữ liệu.
Hãy tăng terminationGracePeriodSeconds trong Pod spec và bắt tín hiệu dừng an toàn (graceful shutdown) trong ứng dụng worker của bạn:
spec:
template:
spec:
terminationGracePeriodSeconds: 120
containers:
- name: worker
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "touch /tmp/draining && sleep 5"]
3. Giám sát tải thăm dò (Polling Overhead) lên Broker
KEDA định kỳ thăm dò (poll) các endpoint của hàng đợi (mặc định: 30 giây). Việc triển khai 200 tài nguyên ScaledObject với khoảng thời gian thăm dò 2 giây sẽ tạo ra 100 truy vấn quản trị HTTP hoặc AMQP mỗi giây tới broker. Hãy duy trì khoảng thời gian từ 15–30 giây trừ khi hệ thống bắt buộc phải phản hồi hàng đợi theo thời gian thực dưới một giây.

