Kubernetes Practice – Kubernetes based Event Driven Autoscaler

Giới thiệu Chào mọi người đến với series practice về kubernetes. Ở bài này chúng ta sẽ tìm hiểu về KEDA, một resource giúp ta scale các container trong Kubernetes một cách rất dễ dàng và cover rất nhiều use case phổ biến. Khi ta sử dụng kubernetes, để scale một pod container ta thường

Giới thiệu

Chào mọi người đến với series practice về kubernetes. Ở bài này chúng ta sẽ tìm hiểu về KEDA, một resource giúp ta scale các container trong Kubernetes một cách rất dễ dàng và cover rất nhiều use case phổ biến.

image.png

Khi ta sử dụng kubernetes, để scale một pod container ta thường sử dụng Horizontal Pod Autoscaling. Nhưng Horizontal Pod Autoscaling chỉ hỗ trợ ta scale container theo một vài metric đơn giản, ví dụ như là cpu và memory. Nếu ta muốn scale container theo các metric khác thì ta phải viết custom metrics khá phúc tạp, ví dụ như là scale container 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ó.

image.png

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 container 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.

image.png

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ẽ install 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 install Helm thì install 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.sh

Sau đó ta chạy các lệnh sau.

  1. Add Helm repo
helm repo add kedacore https://kedacore.github.io/charts
  1. Update Helm repo
helm repo update
  1. Install keda Helm chart
helm install keda kedacore/keda --namespace keda --create-namespace
NAME: keda
LAST DEPLOYED: Wed Apr 13 17:22:29 2022
NAMESPACE: keda
STATUS: deployed
REVISION: 1
TEST SUITE: None

Kiểm tra CRDs đã chạy chưa.

kubectl get all -n keda

NAME                                                   READY   STATUS    RESTARTS   AGE
pod/keda-operator-778cf49bcf-k8n2m                     1/1     Running   0          77s
pod/keda-operator-metrics-apiserver-5ccf7b74dd-f4c9m   1/1     Running   0          77s

NAME                                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/keda-operator-metrics-apiserver   ClusterIP   10.102.19.207   <none>        443/TCP,80/TCP   77s

NAME                                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/keda-operator                     1/1     1            1           77s
deployment.apps/keda-operator-metrics-apiserver   1/1     1            1           77s

NAME                                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/keda-operator-778cf49bcf                     1         1         1       77s
replicaset.apps/keda-operator-metrics-apiserver-5ccf7b74dd   1         1         1       77s

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.yaml

Tạo consumer.

kubectl apply -f share-consume-queue.yaml

Kiể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           12s

Sau đó ta tạo ScaledObject.

kubectl apply -f scaled-object.yaml

Config của ScaledObject như sau.

apiVersion: v1
kind: Secret
metadata:name: rabbitmq-secret
data:MQ_HOST: YW1xcDovL2s4cy1wcmFjdGljZTprOHMtcHJhY3RpY2VAcmFiYml0bXEuZGVmYXVsdDo1NjcyL3Zob3N0 # base64 encoded value of format amqp://k8s-practice:[email protected]:5672/vhost---apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:name: rabbitmq-trigger-auth
spec:secretTargetRef:-parameter: host
      name: rabbitmq-secret # secret namekey: MQ_HOST # secret key---apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:name: share-consume-queue
spec:scaleTargetRef:name: share-consume-queue
  triggers:-type: rabbitmq
      metadata:mode: QueueLength
        queueName: scale_out
        value:"5"authenticationRef:name: rabbitmq-trigger-auth

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 0

Thứ 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-auth

Thuộ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 ta mà ta sẽ thực hiện trigger scale mỗi replica. 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           17m

Mộ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.yaml
apiVersion: batch/v1
kind: Job
metadata:name: rabbitmq-publish
spec:backoffLimit:4template: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           46m
$ kubectl get pod

NAME                                   READY   STATUS      RESTARTS   AGE
rabbitmq-568f45bff9-bbxkx              1/1     Running     0          47m
rabbitmq-publish-2stmd                 0/1     Completed   0          42s
share-consume-queue-68774b665c-7qg4f   1/1     Running     0          17s
share-consume-queue-68774b665c-gvmtn   1/1     Running     0          18s
share-consume-queue-68774b665c-khrxf   1/1     Running     0          17s
share-consume-queue-68774b665c-mc5tv   1/1     Running     0          17s

Kiể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          28m

Lú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           50m
$ kubectl get hpa

NAME                           REFERENCE                        TARGETS     MINPODS   MAXPODS   REPLICAS   AGE
keda-hpa-share-consume-queue   Deployment/share-consume-queue   0/5 (avg)   1         100       10         32m

Oke, 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 rõ thêm chỗ nào thì các bạn có thể hỏi dưới phần comment.

Mục tìm kiếm đồng đội

Hiện tại thì bên công ty mình, là Hoàng Phúc International, với hơn 30 năm kinh nghiệm trong lĩnh vực thời trang. Và là trang thương mại điện tử về thời trang lớn nhất Việt Nam. Team công nghệ của HPI đang tìm kiếm đồng đội cho các vị trí như:

Với mục tiêu trong vòng 5 năm tới về mảng công nghệ là:

  • Sẽ có trang web nằm trong top 10 trang web nhanh nhất VN với 20 triệu lượt truy cập mỗi tháng.
  • 5 triệu loyal customers và có hơn 10 triệu transactions mỗi năm.

Team đang xây dựng một hệ thống rất lớn với rất nhiều vấn đề cần giải quyết, và sẽ có rất nhiều bài toán thú vị cho các bạn. Nếu các bạn có hứng thú trong việc xây dựng một hệ thống lớn, linh hoạt, dễ dàng mở rộng, và performance cao với kiến trúc microservices thì hãy tham gia với tụi mình.

Nếu các bạn quan tâm hãy gửi CV ở trong trang tuyển dụng của Hoàng Phúc International hoặc qua email của mình nha [email protected]. Cảm ơn các bạn đã đọc.

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ