Home > Blog > tech

HPA Custom Metrics คืออะไร? Autoscaling K8s ด้วย Prometheus Metrics 2026

kubernetes horizontal pod autoscaler custom metrics
HPA Custom Metrics คืออะไร? Autoscaling K8s ด้วย Prometheus Metrics 2026
2026-04-16 | tech | 920 words


HPA Custom Metrics คืออะไร? พลิกโฉม Autoscaling บน Kubernetes ด้วย Prometheus Metrics

ในโลกของ Microservices และการประมวลผลแบบคลาวด์-เนทีฟ (Cloud-Native) ความสามารถในการปรับขนาดทรัพยากรได้อย่างอัตโนมัติและแม่นยำถือเป็นหัวใจสำคัญของการรักษาประสิทธิภาพและควบคุมต้นทุน Kubernetes (K8s) มอบเครื่องมือทรงพลังอย่าง Horizontal Pod Autoscaler (HPA) ให้เราใช้ แต่ HPA พื้นฐานที่ปรับขนาดตาม CPU และ Memory ใช่ว่าจะเพียงพอสำหรับทุกสถานการณ์เสมอไป วันนี้เราจะเจาะลึกไปอีกขั้นกับ HPA Custom Metrics และการผนวกพลังของ Prometheus เพื่อสร้างระบบ Autoscaling ที่ตอบโจทย์ธุรกิจและเทคนิคได้อย่างแท้จริง

ทำความรู้จักกับ Horizontal Pod Autoscaler (HPA) พื้นฐาน

Horizontal Pod Autoscaler (HPA) เป็นตัวควบคุม (Controller) ใน Kubernetes ที่ทำหน้าที่เพิ่มหรือลดจำนวน Pod (Replicas) ของ Deployment, StatefulSet หรือรีซอร์สอื่นๆ โดยอัตโนมัติ ตามเมตริกที่กำหนด เป้าหมายคือเพื่อรักษาระดับการใช้งานทรัพยากรให้อยู่ในระดับที่กำหนด (Target Value)

HPA พื้นฐานที่ทุกคนมักเริ่มต้นใช้คือการสเกลตามเมตริกจาก Resource Metrics API เช่น ค่าเฉลี่ยการใช้ CPU หรือ Memory ของ Pods ตัวอย่างเช่น คุณอาจตั้งค่าให้ HPA เพิ่มจำนวน Pod เมื่อการใช้ CPU เฉลี่ยเกิน 70% ของ Request ที่กำหนด กลไกนี้ทำงานได้ดีสำหรับบริการที่ภาระงานสัมพันธ์โดยตรงกับ CPU/Memory แต่ในโลกความจริง เมตริกที่บ่งชี้ "ความคับคั่ง" ของบริการอาจซับซ้อนกว่านั้นมาก

ข้อจำกัดของ HPA แบบ Resource Metrics และก้าวสู่ Custom Metrics

ลองนึกภาพบริการเหล่านี้:

ในกรณีเหล่านี้ CPU Usage อาจไม่กระเพื่อมมากนักแม้คิวจะยาวเป็นกิโล หรือในทางกลับกัน CPU อาจสูงชั่วขณะหนึ่งโดยที่จำนวน Request จริงยังน้อยอยู่ การสเกลตาม Resource Metrics ล้วนๆ อาจทำให้ได้จำนวน Pod ที่ไม่เหมาะสม ทั้งมากเกินไปหรือน้อยเกินไป นี่คือจุดที่ HPA Custom Metrics เข้ามาแก้ไขปัญหาโดยอนุญาตให้คุณกำหนดเมตริกสำหรับ Autoscaling จากแหล่งข้อมูลใดๆ ก็ตามที่คุณสามารถวัดได้

สถาปัตยกรรมและส่วนประกอบสำคัญของ HPA Custom Metrics

สำหรับ HPA ที่จะเข้าถึงเมตริกที่ไม่ได้มาจาก Resource Metrics API ได้ ระบบ Kubernetes ต้องการส่วนประกอบเพิ่มเติมหลักๆ ดังนี้:

  1. Custom Metrics API: เป็น API Server ที่ทำหน้าที่เป็นตัวกลางให้ HPA ดึงเมตริกที่กำหนดเองได้ Kubernetes เองไม่มีตัวนี้มาให้ เราต้องติดตั้งเพิ่ม ซึ่งมักมาพร้อมกับ...
  2. Prometheus Adapter (หรือตัว adapter อื่นๆ): เป็นตัวเชื่อมระหว่าง Custom Metrics API และแหล่งเก็บเมตริกอย่าง Prometheus มันจะแปลง query ของ Prometheus ให้เป็น API ที่ HPA เข้าใจได้
  3. แหล่งที่มาของเมตริก (เช่น Prometheus): ระบบเก็บและประมวลผลเมตริกที่เราต้องการ ซึ่ง Prometheus เป็นตัวเลือกยอดนิยมเนื่องจากเก็บข้อมูลเป็น time series และมีชุมชนที่แข็งแรง

เมื่อ HPA ต้องการประเมินว่าจะสเกลหรือไม่ มันจะส่งคำขอไปยัง Custom Metrics API -> Prometheus Adapter -> Prometheus เพื่อดึงค่าล่าสุดของเมตริกที่เรากำหนด แล้วนำมาเปรียบเทียบกับ Target Value ที่ตั้งไว้

ติดตั้งและกำหนดค่า Prometheus Adapter สำหรับ Custom Metrics

ก่อนอื่นต้องมี Kubernetes Cluster และติดตั้ง Prometheus ไว้แล้ว (เช่นผ่าน Helm chart `prometheus-community/kube-prometheus-stack`) จากนั้นเราสามารถติดตั้ง Prometheus Adapter ได้ง่ายๆ ด้วย Helm เช่นกัน

# เพิ่ม repo ของ prometheus-community
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# ติดตั้ง prometheus-adapter
helm install prometheus-adapter prometheus-community/prometheus-adapter \
  --namespace monitoring \
  --set prometheus.url=http://prometheus-server.monitoring.svc.cluster.local \
  --set prometheus.port=80

หลังจากติดตั้งแล้ว เราสามารถตรวจสอบว่า Custom Metrics API ทำงานได้และมีเมตริกอะไรบ้างโดยใช้คำสั่ง:

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq .

สร้าง HPA ที่สเกลตาม Custom Metrics จาก Prometheus

สมมติว่าเรามี Deployment ชื่อ `api-worker` ที่ประมวลผลงานจากคิว Redis และเราต้องการสเกลตามความยาวของคิว (จำนวนงานที่ค้างอยู่) ใน Redis ที่มีชื่อคิวว่า `my_jobs`

ขั้นตอนที่ 1: เปิดเผยเมตริกใน Prometheus
แอปพลิเคชันของคุณหรือตัว exporter ต้องส่งเมตริก `redis_queue_length` ไปยัง Prometheus อยู่แล้ว โดยมี label `queue="my_jobs"`

ขั้นตอนที่ 2: กำหนดค่า Prometheus Adapter Rule
เราต้องบอก Adapter ว่าเมตริก `redis_queue_length` นั้นสามารถดึงผ่าน Custom Metrics API ได้และให้แมปมันอย่างไร โดยปกติเรากำหนดผ่านค่า `rules` ใน `values.yaml` ของ Helm chart หรือผ่าน ConfigMap ซึ่ง rule อาจมีหน้าตาแบบนี้:

rules:
  custom:
  - seriesQuery: 'redis_queue_length{queue!=""}'
    resources:
      overrides:
        namespace: {resource: "namespace"}
        pod: {resource: "pod"}
    name:
      matches: "^(.*)_length"
      as: "${1}_per_pod"
    metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'

แต่สำหรับตัวอย่างง่ายๆ เราอาจใช้ rule ที่ตรงไปตรงมาเพื่อดึงค่าล่าสุดของคิว:

apiVersion: v1
kind: ConfigMap
metadata:
  name: adapter-config
  namespace: monitoring
data:
  config.yaml: |
    rules:
    - seriesQuery: 'redis_queue_length{namespace!="",queue!=""}'
      resources:
        template: <<.Resource>>
      name:
        matches: "redis_queue_length"
        as: "queue_length"
      metricsQuery: 'redis_queue_length{queue="my_jobs"}'

ขั้นตอนที่ 3: สร้าง HPA Object
นี่คือส่วนสำคัญ เราจะสร้าง HPA ที่อ้างอิงเมตริก `queue_length` จาก Custom Metrics API

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-worker-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-worker
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Pods
    pods:
      metric:
        name: queue_length # ชื่อเมตริกที่ปรากฏใน Custom Metrics API
      target:
        type: AverageValue
        averageValue: 10 # เป้าหมาย: คิวความยาวเฉลี่ย 10 งานต่อ Pod

HPA นี้จะพยายามรักษาให้ค่าเฉลี่ยของ `queue_length` ต่อ Pod อยู่ที่ 10 หากคิวยาวเฉลี่ย 30 งาน และมี Pod อยู่ 2 Pod (เฉลี่ย 15 งาน/Pod ซึ่งเกิน 10) HPA จะคำนวณว่า需要 Pod ใหม่ = ceil(30 / 10) = 3 Pods จึงจะสั่งเพิ่ม Replicas เป็น 3 Pods

ตัวอย่างจริง: Autoscaling Web Service ตาม Requests Per Second (RPS)

สำหรับบริการเว็บ เรามักใช้เมตริกจาก Prometheus เช่น `http_requests_total` (จาก nginx-ingress controller หรือตัวแอปเอง) มาคำนวณเป็น RPS

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: frontend-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: frontend
  minReplicas: 3
  maxReplicas: 20
  metrics:
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: 50 # เป้าหมาย: 50 RPS ต่อ Pod

โดยที่ `http_requests_per_second` ถูกกำหนดใน Prometheus Adapter rule ดังนี้:

rules:
  - seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
    resources:
      overrides:
        namespace: {resource: "namespace"}
        pod: {resource: "pod"}
    name:
      matches: "http_requests_total"
      as: "http_requests_per_second"
    metricsQuery: 'sum(rate(http_requests_total{namespace="default",service="frontend"}[2m])) by (pod)'

การผสานรวมระบบคลาวด์อย่างมีประสิทธิภาพเป็นกุญแจสำคัญสำหรับสถาปัตยกรรมสมัยใหม่ ซึ่งการจัดการเมตริกและการสเกลอัตโนมัติก็เป็นส่วนหนึ่งของกระบวนการนั้น

ตารางเปรียบเทียบ: HPA Resource Metrics vs. Custom Metrics vs. External Metrics

ลักษณะHPA Resource Metrics (CPU/Memory)HPA Custom Metrics (Pod/Object)HPA External Metrics
แหล่งที่มาของเมตริกResource Metrics API (จาก cAdvisor)Custom Metrics API (มักมาจาก Prometheus)External Metrics API (จาก cloud provider, Kafka, ฯลฯ)
ขอบเขตเมตริกต่อ Pod หรือต่อ Containerต่อ Pod หรือต่อ Object ใน Namespaceเมตริกระดับ global (เช่น ความยาวคิว SQS ของ AWS ทั้งหมด)
กรณีใช้ตัวอย่างบริการที่ใช้ CPU/Memory สูงตามภาระงานสเกลตาม RPS, Latency, ความยาวคิวภายในสเกลตามความยาวคิว Cloud Message Queue, คอนซูเมอร์แล็กของ Kafka Topic
ความซับซ้อนในการตั้งค่าต่ำ (มีในตัว Kubernetes)ปานกลาง (ต้องติดตั้ง Adapter และกำหนด Rule)ปานกลางถึงสูง (ขึ้นกับ provider)
ความยืดหยุ่นต่ำสูงมาก (วัดอะไรก็ได้ที่ส่งเข้า Prometheus)สูง (เชื่อมกับบริการภายนอกได้)

แนวทางปฏิบัติและข้อควรระวัง

การจัดการทรัพยากรคลาวด์อย่างชาญฉลาดไม่เพียงแต่เพิ่มประสิทธิภาพแต่ยังช่วยในการวางแผนงบประมาณ ซึ่งการทำความเข้าใจเครื่องมือเหล่านี้ก็เหมือนกับการเข้าใจตลาดการเงินที่ต้องอาศัยข้อมูลที่แม่นยำและทันท่วงที

FAQ (คำถามที่พบบ่อย)

HPA Custom Metrics แตกต่างจาก External Metrics อย่างไร?

HPA Custom Metrics จะดึงเมตริกที่สัมพันธ์กับวัตถุภายใน Kubernetes Cluster (เช่น ต่อ Pod, ต่อ Namespace) ส่วน HPA External Metrics จะดึงเมตริกที่ไม่ได้สัมพันธ์กับวัตถุใน Cluster เลย (เช่น จำนวนข้อความใน Amazon SQS Queue, ความลึกของคิว RabbitMQ ที่รันบนเซิร์ฟเวอร์ภายนอก) โดยทั้งสองใช้ API คนละตัวกัน (custom.metrics.k8s.io vs. external.metrics.k8s.io) แต่สามารถใช้ Prometheus Adapter รองรับทั้งสองแบบได้หากกำหนดค่า rule ถูกต้อง

จำเป็นต้องใช้ Prometheus เท่านั้นหรือไม่?

ไม่จำเป็น Prometheus เป็นเพียงตัวเลือกที่นิยมที่สุดเนื่องจากมี ecosystem ที่ครบครัน แต่ Custom Metrics API สามารถใช้กับ adapter อื่นๆ ได้ เช่น Microsoft Azure Adapter, Google Stackdriver Adapter, หรือแม้แต่เขียน adapter ขึ้นมาเองเพื่อดึงเมตริกจากแหล่งข้อมูลอื่นๆ เช่น Datadog, InfluxDB ได้ หลักการคือต้องมีตัวกลางที่ดึงเมตริกจากแหล่งนั้นๆ และแปลงเป็นรูปแบบที่ Custom Metrics API ต้องการ

หากเมตริกจาก Prometheus หายไป (Missing Metrics) จะเกิดอะไรขึ้น?

พฤติกรรมของ HPA ขึ้นอยู่กับเวอร์ชันและการกำหนดค่า โดยทั่วไปหาก HPA v2 ไม่สามารถดึงเมตริกที่กำหนดได้ (ได้สถานะ `NoData`) มันจะถือว่าเมตริกนั้นเป็น `0` สำหรับการสเกลดาวน์ (scaleDown) และจะ ไม่ดำเนินการ ใดๆ สำหรับการสเกลอัพ (scaleUp) ซึ่งเป็นพฤติกรรมที่ปลอดภัยกว่า เพื่อป้องกันการสเกลโดยขาดข้อมูล อย่างไรก็ตาม ควรตั้ง Alert ใน Prometheus ตัวเองเพื่อแจ้งเตือนเมื่อเมตริกสำคัญหายไป และตรวจสอบสุขภาพของ exporter หรือแอปพลิเคชันที่เกี่ยวข้องทันที

สามารถใช้หลายเมตริกพร้อมกันใน HPA เดียวได้หรือไม่?

ได้แน่นอน นี่คือหนึ่งในความสามารถของ HPA API เวอร์ชัน 2 (`autoscaling/v2`) คุณสามารถระบุเมตริกได้หลายตัวในฟิลด์ `spec.metrics[]` HPA จะคำนวณจำนวน replica ที่ต้องการจาก ทุกเมตริก และเลือกค่าที่ มากที่สุด มาใช้ ตัวอย่างเช่น คุณอาจกำหนดให้สเกลตามทั้ง CPU > 70% และ RPS > 50 ต่อ Pod หากระบบคำนวณจาก CPU ต้องการ 4 Pods แต่จาก RPS ต้องการ 6 Pods HPA จะสเกลไปที่ 6 Pods เพื่อให้เป็นไปตามเงื่อนไขที่เข้มงวดที่สุดของทุกเมตริก

การทำ Autoscaling แบบ Custom Metrics ส่งผลต่อการจัดการทรัพยากรคลาวด์โดยรวมอย่างไร?

การทำ Autoscaling ที่แม่นยำช่วยเพิ่มประสิทธิภาพการใช้ทรัพยากรคลาวด์ได้อย่างมาก ลดการจ่ายเงินสำหรับเซิร์ฟเวอร์ที่ idle ลง และรับประ 


Back to Blog | iCafe Forex | SiamLanCard | Siam2R