0
0
Lập trình
Hưng Nguyễn Xuân 1
Hưng Nguyễn Xuân 1xuanhungptithcm

Tự động mở rộng Kubernetes với KEDA: Giải pháp cho Microservices

Đăng vào 6 ngày trước

• 5 phút đọc

Tự động mở rộng Kubernetes với KEDA

Giới thiệu

Khi triển khai các dịch vụ tiêu thụ Kafka hoặc RabbitMQ trong Kubernetes, bạn có thể gặp phải tình trạng các dịch vụ này bị dư thừa tài nguyên hoặc quá tải. Cách mở rộng dựa trên CPU thông qua HPA không phải lúc nào cũng là giải pháp tối ưu. Đó là lý do tại sao KEDA (Kubernetes-based Event-Driven Autoscaling) ra đời.

KEDA cho phép bạn tự động mở rộng ứng dụng dựa trên các sự kiện hoặc chỉ số bên ngoài như độ dài hàng đợi trong Kafka hoặc RabbitMQ, các chỉ số Prometheus, hoặc sự kiện từ các dịch vụ đám mây như Azure, AWS, GCP.


KEDA là gì?

KEDA là một trình tự động mở rộng nhẹ cho phép bạn mở rộng các khối lượng công việc Kubernetes dựa trên các sự kiện hoặc chỉ số bên ngoài.

Các đặc điểm chính của KEDA:

  • Không giống HPA, KEDA cho phép các pod của bạn mở rộng một cách linh hoạt dựa trên khối lượng công việc thực tế.
  • KEDA hoạt động như một Deployment trong cụm Kubernetes của bạn.
    • Nó không phải là một StatefulSet hay một Deployment đặc biệt của ứng dụng của bạn.
    • Nó tiêu thụ CPU/memory như bất kỳ Deployment nào khác, tùy thuộc vào số lượng ScaledObjects và các trigger bạn định nghĩa.
    • Điều này có nghĩa là nếu bạn định nghĩa nhiều hàng đợi, chính Deployment của KEDA sẽ tăng cường sử dụng tài nguyên.

Cách KEDA hoạt động

KEDA giới thiệu một đối tượng mới trong Kubernetes được gọi là ScaledObject:

  • Mapping ScaledObject → Deployment: cho KEDA biết khối lượng công việc nào cần mở rộng.
  • Mỗi ScaledObject có thể có một hoặc nhiều trigger.
  • Logic mở rộng:
    • Logic OR giữa các trigger (nếu bất kỳ trigger nào vượt quá ngưỡng → mở rộng).
    • Không thể mở rộng độc lập các subset pod trong cùng một Deployment.

Ví dụ: ScaledObject cho RabbitMQ

yaml Copy
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: orders-consumer-scaler
spec:
  scaleTargetRef:
    name: orders-consumer
  minReplicaCount: 1
  maxReplicaCount: 10
  triggers:
  - type: rabbitmq
    metadata:
      queueName: orders-queue
      host: amqp://guest:guest@rabbitmq:5672/
      queueLength: "100"

Giải thích:

  • Deployment orders-consumer sẽ mở rộng từ 1 đến 10 pods tùy thuộc vào độ dài hàng đợi.
  • Việc mở rộng sẽ xảy ra nếu độ dài hàng đợi lớn hơn 100.

Cách KEDA xác định số lượng Pods

KEDA tính toán số lượng replicas mong muốn dựa trên chỉ số hàng đợi và ngưỡng:

  1. Giá trị ngưỡng (queueLength): chỉ số mà KEDA theo dõi (độ sâu hàng đợi).
  2. Min và Max Replicas:
yaml Copy
minReplicaCount: 1
maxReplicaCount: 10

Cách tính toán số lượng replicas mong muốn (đơn giản):

yaml Copy
desiredReplicas = ceil(currentQueueLength / queueLengthThreshold)

Scaling áp dụng qua HPA

KEDA cập nhật số replicas của Deployment giữa minReplicaCountmaxReplicaCount.


Ví dụ hình ảnh

Giả sử hàng đợi orders-queue có ngưỡng là 100 tin nhắn:

Copy
Queue Depth → Desired Replicas → Deployment Pods
------------------------------------------------
50          → 1                 → 1 pod (minReplicaCount)
120         → 2                 → 2 pods
250         → 3                 → 3 pods
1050        → 11                → 10 pods (maxReplicaCount)

Sơ đồ:

Copy
[Queue Depth: 250]
        │
        ▼
[Threshold: 100 per pod]
        │
        ▼
[Desired Replicas: ceil(250/100) = 3]
        │
        ▼
[orders-consumer Deployment scales to 3 pods]

Hạn chế của KEDA

Mặc dù KEDA rất mạnh mẽ, nhưng nó vẫn có một số hạn chế quan trọng:

N hàng đợi → N dịch vụ tiêu thụ không được hỗ trợ một cách tự nhiên.

Bạn không thể định nghĩa nhiều hàng đợi với các Deployment tiêu thụ khác nhau trong một ScaledObject.
Logic mở rộng là OR giữa các trigger; tất cả các pods sẽ mở rộng cùng nhau.

Điều này không lý tưởng cho các microservices với nhiều hàng đợi và luồng công việc khác nhau.

Ví dụ: nếu bạn có 10 hàng đợi với các logic/xử lý khác nhau, KEDA không thể mở rộng chúng một cách độc lập.

Bạn sẽ cần nhiều Deployments + nhiều ScaledObjects, điều này có thể trở nên phức tạp.


Tiêu thụ tài nguyên

KEDA cũng là một Deployment; mỗi ScaledObject sẽ thêm vào mức tiêu thụ CPU/memory.
Việc mở rộng nhiều hàng đợi có thể làm tăng mức tiêu thụ tài nguyên trên cụm.

Ví dụ với Kubectl

Sau khi tạo nhiều ScaledObjects:

bash Copy
kubectl get scaledobjects

Kết quả ví dụ:

Copy
NAME                       SCALETARGETKIND      SCALETARGETNAME     MIN   MAX   TRIGGERS
orders-consumer-scaler     apps/v1.Deployment   orders-consumer      1    10    rabbitmq
payments-consumer-scaler   apps/v1.Deployment   payments-consumer    1     5    rabbitmq
kafka-consumer-scaler      apps/v1.Deployment   kafka-consumer       1    15    kafka

Mỗi ScaledObject nhắm đến một Deployment duy nhất.
Nhiều trigger cho cùng một Deployment sẽ mở rộng tất cả các pods cùng nhau (logic OR).


Những điều cần lưu ý

  • KEDA rất tuyệt vời cho việc mở rộng đơn giản dựa trên sự kiện.
  • Mỗi ScaledObject chỉ định một Deployment.
  • Logic OR cho nhiều trigger → không phù hợp cho microservices với nhiều hàng đợi và luồng công việc khác nhau.
  • KEDA tự động tính toán số lượng replicas dựa trên chỉ số và ngưỡng, mở rộng các pods của Deployment giữa min và max.
  • Mức tiêu thụ tài nguyên tăng lên với nhiều ScaledObjects và trigger.

Kết luận

Phần 2 sẽ trình bày cách xây dựng một trình tự động mở rộng tùy chỉnh có thể xử lý nhiều hàng đợi, nhiều dịch vụ tiêu thụ và logic mở rộng độc lập cho các microservices phức tạp.


Mẹo chuyên nghiệp: Bắt đầu với KEDA cho việc mở rộng hàng đợi đơn giản. Đối với các microservices phức tạp với nhiều hàng đợi, thường cần một giải pháp HPA/KEDA tùy chỉnh.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào