Từ trước đến giờ chúng ta thưởng sử dụng auto scaling on k8s bằng HPA.
hoặc bạn cài các adapter prometheus rồi tương tác custom metrics feature với HPA.
Bài toán của mình đặt ra auto scaling pods on k8s base on metrics of Cloudwatch.
1) Install Keda on kubernetes.
https://keda.sh/docs/2.8/deploy/#helm
kubectl create namespace keda
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda --namespace keda
2)Keda integrates with kafka.
Sau khi cài xong Keda, chúng ta integrate with kafka/ AWS MSK
https://keda.sh/docs/2.8/scalers/apache-kafka/
Hiện tại mình đang có MSK trên AWS.

Bạn cần tạo secret:
apiVersion: v1 kind: Secret metadata: name: kafka-akhq-secrets namespace: xxxx type: Opaque data: tls: ZW5hYmxl # enable
Bạn cần tạo TriggerAuthentication và nó link tới secret bên trên. :
apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: kafka-akhq-trigger-auth-credential namespace: qa-md-cloud-rest spec: secretTargetRef: - parameter: tls name: kafka-akhq-secrets key: tls
Bạn cần tạo ScaledObject
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: kafka-akhq-scaledobject namespace: qa-md-cloud-rest spec: maxReplicaCount: 5 minReplicaCount: 1 pollingInterval: 10 scaleTargetRef: name: kafka-akhq triggers: - authenticationRef: name: kafka-akhq-trigger-auth-credential metadata: activationLagThreshold: '3' bootstrapServers: b-2.xxx-msk-dev.dlweos.c12.kafka.us-west-2.amazonaws.com:9094 consumerGroup: 4dbd50d3-008c-4be2-95b4-2aab77e16bcc lagThreshold: '100' offsetResetPolicy: latest topic: results version: 1.37.2 type: kafka
ScaledObject sẽ tạo ra HPA cho k8s

2.1) lagThreshold
Chúng ta sẽ tìm hiểu lagThreshold



và 336/4 = 84
lagThreshold: bạn có thể hiểu là 1 consumer sẽ có khả năng consume được 100 messages.
SumOffsetLag / (number of pod) > lagThreshold ==> scale up the pods
2.2) allowIdleConsumers
Nhưng các bạn cũng đã biết nếu hoặc chưa biết
Số consumer luôn luôn <= “bé hơn hoặc bằng” số partition của 1 topic.
Nếu số consumer > partition thì số consumer dư là sẽ vào trang thái Idle (Starveling)
và Keda cũng biết điều này.
allowIdleConsumers
– When set to true
, the number of replicas can exceed the number of partitions on a topic, allowing for idle consumers. (Default: false
, Optional)
==> Nếu bạn có nhu cấu số consumer > partition thì chỉnh: allowIdleConsumers: 'true'
Bạn có thể đọc issue này để hiểu hơn
https://github.com/kedacore/keda/issues/2908#issuecomment-1133605509
2.3) pollingInterval
This is the interval to check each trigger on. By default KEDA will check each trigger source on every ScaledObject every 30 seconds.
Nếu bạn muốn cập nhật nhanh hơn chỉnh số thấp.
3) Keda integrates with Ram/CPU metrics.
https://keda.sh/docs/2.8/scalers/cpu/
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: cpu-scaledobject namespace: default spec: scaleTargetRef: name: my-deployment triggers: - metadata: value: '80' metricType: Utilization type: cpu - metadata: value: '80' metricType: Utilization type: memory
Parameter list:
type
– Type of metric to use. Options areUtilization
, orAverageValue
.value
– Value to trigger scaling actions for:- When using
Utilization
, the target value is the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods. - When using
AverageValue
, the target value is the target value of the average of the metric across all relevant pods (quantity).
- When using
containerName
– Name of the specific container to scale based on its CPU, rather than the entire pod. Defaults to empty if not specified.
4) Keda integrates with RabbitMQ
Ồ dê, Keda cũng có thể đọc thẳng vào queue là lấy ra lượng message chưa được sử lý.
https://keda.sh/docs/2.8/scalers/rabbitmq-queue/
Đây là config của mình:
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: workload1-nimtechnology-scaledobject spec: scaleTargetRef: name: workload1-nimtechnology minReplicaCount: 1 maxReplicaCount: 4 pollingInterval: 15 triggers: - type: rabbitmq metadata: host: amqp://guest:guest@192.168.101.27:5672 protocol: amqp queueName: publisher mode: QueueLength value: "2" metricName: workload1-nimtechnology-request-mq
host
– Host of RabbitMQ with format<protocol>://<host>:<port>/vhost
. The resolved host should follow a format likeamqp://guest:password@localhost:5672/vhost
orhttp://guest:password@localhost:15672/vhost
. When using a username/password consider usinghostFromEnv
or a TriggerAuthentication.protocol
– Protocol to be used for communication. (Values:auto
,http
,amqp
, Default:auto
, Optional)queueName
– Name of the queue to read message from.mode
– QueueLength to trigger on number of messages in the queue. MessageRate to trigger on the publish rate into the queue. (Values:QueueLength
,MessageRate
)
Ook giờ mình sẽ giải thích một chút
Với config ….mode: QueueLength
value: "2"
Nó sẽ lấy message backlog và bạn có thể hiểu là những message được lấy bới consumers.

Bạn có thể thấy External Metric có giá trị là 2
Current Metric đang có Average Value là 1 <<<<====Tại sao nhỉ???


Nếu (Totals message in backlog) / (Numbers of Pod) lớn hơn External Metric ===> scale up pods of Deployment
Tiếp theo mình push thêm 2 message vào queue:

Bạn có thể thấy HPA current metrics đã có sự thay đổi.

và pod đã tăng lên 2

OK nhé.
Debug on Keda
Nếu bạn muốn debug trên Keda thì bạn cần chỉnh
https://github.com/kedacore/keda/blob/main/BUILD.md#setting-log-levels
Deployment: keda-operator

deployment: keda-operator-metrics-apiserver

KEDA might break existing deployment on cluster which already has another External Metrics Adapter installed
Các bạn cần lưu ý điều này.
https://github.com/kedacore/keda/issues/470
Edit the objects belong to KEDA

Bạn muốn sửa ScaledObject:
kubectl edit scaledobject.keda.sh/<name> -n <namespace>
Enable metrics of Keda.
strong value helm bạn cần thêm như sau:
prometheus: metricServer: enabled: true
Cách thử 2 bạn sửa deployment và service
Service: keda-operator-metrics-apiserver
spec: ports: - name: https port: 443 protocol: TCP targetPort: 6443 - name: http port: 80 protocol: TCP targetPort: 8080 - name: metrics port: 9022 protocol: TCP targetPort: 9022

Deployment: keda-operator-metrics-apiserver
template: metadata: annotations: prometheus.io/path: /metrics prometheus.io/port: '9022' prometheus.io/scrape: 'true'

spec: automountServiceAccountToken: true containers: - args: - /usr/local/bin/keda-adapter - '--secure-port=6443' - '--logtostderr=true' - '--metrics-port=9022' - '--metrics-path=/metrics' - '--v=0'

name: keda-operator-metrics-apiserver ports: - containerPort: 6443 name: https protocol: TCP - containerPort: 8080 name: http protocol: TCP - containerPort: 9022 name: metrics protocol: TCP readinessProbe: httpGet: path: /readyz port: 6443 scheme: HTTPS

Issues when provisioning Keda.
keda-operator error creating kafka client: kafka: client has run out of available brokers
Gần đây bên SRE có báo mình là ScaledObject bị lỗi false và trong describe:
Warning KEDAScalerFailed 85s (x3629 over 41d) keda-operator error creating kafka client: kafka: client has run out of available brokers to talk to: 3 errors occurred: │ │ * unexpected EOF │ │ * unexpected EOF │ │ * unexpected EOF │ │ Warning ScaledObjectCheckFailed 85s (x3629 over 41d) keda-operator Failed to ensure HPA is correctly created for ScaledObject
Bạn cần kiểm tra lại ScaledObject, TriggerAuthentication, Secret đã được tạo đầy đủ hay chưa?
https://github.com/kedacore/keda/discussions/2636