All Products
Search
Document Center

Alibaba Cloud Service Mesh:Gunakan metrik ASM untuk menskalakan workload secara otomatis

Last Updated:Apr 21, 2026

Service Mesh (ASM) menghasilkan data telemetri untuk setiap permintaan yang mengalir melalui service mesh Anda tanpa memerlukan perubahan pada kode aplikasi. Berdasarkan empat sinyal emas pemantauan—latensi, traffic, error, dan saturasi—ASM menghasilkan serangkaian metrik untuk layanan yang dikelolanya. Metrik ini dapat diintegrasikan ke dalam Horizontal Pod Autoscaler (HPA) Kubernetes untuk menskalakan workload berdasarkan sinyal traffic aktual seperti laju permintaan, bukan hanya berdasarkan pemanfaatan CPU atau memori.

Panduan ini mencakup penyiapan end-to-end: mengumpulkan metrik ASM di Prometheus, men-deploy adapter metrik kustom, dan mengonfigurasi HPA yang menskalakan workload contoh ketika laju permintaan rata-rata melebihi ambang batas tertentu.

Cara kerja

Kubernetes mendukung dua jenis skalabilitas otomatis:

  • Cluster Autoscaler (CA) — menambah atau menghapus node berdasarkan permintaan penjadwalan pod yang tertunda.

  • Horizontal Pod Autoscaler (HPA) — menyesuaikan jumlah replika Deployment atau StatefulSet.

Lapisan agregasi di Kubernetes memungkinkan aplikasi pihak ketiga memperluas API Kubernetes dengan mendaftar sebagai komponen add-on API. Komponen add-on ini dapat mengimplementasikan Custom Metrics API dan memungkinkan HPA mengakses berbagai metrik. HPA mengambil metrik dari tiga API Kubernetes:

APITujuanContoh metrik
Resource Metrics API (metrics.k8s.io)Metrik resource intiCPU, memori
Custom Metrics API (custom.metrics.k8s.io)Metrik spesifik aplikasi yang terikat pada objek KubernetesPods, Ingresses
External Metrics API (external.metrics.k8s.io)Metrik dari sistem di luar klusterKueri Prometheus, pemantauan cloud

Metrik ASM berasal dari Prometheus, yang berada di luar model objek Kubernetes. Oleh karena itu, External Metrics API merupakan pilihan yang tepat. kube-metrics-adapter menjembatani Prometheus dan External Metrics API sehingga HPA dapat mengkueri metrik ASM secara langsung.

Architecture: ASM sidecar proxies report Istio metrics to Prometheus. The kube-metrics-adapter exposes those metrics through the External Metrics API. The HPA reads the metrics and scales the target Deployment.

Metrik ASM yang tersedia untuk autoscaling

ASM menghasilkan metrik standar Istio untuk traffic HTTP, HTTP/2, dan gRPC. Metrik yang paling umum digunakan untuk autoscaling adalah:

MetricTypeUse caseContoh PromQL
istio_requests_totalCounterSkala berdasarkan laju permintaansum(rate(istio_requests_total{destination_workload="<workload>"}[1m]))
istio_request_duration_millisecondsDistributionSkala berdasarkan latensi P99histogram_quantile(0.99, sum(rate(istio_request_duration_milliseconds_bucket{destination_workload="<workload>"}[1m])) by (le))
istio_requests_total (difilter)CounterSkala berdasarkan laju errorsum(rate(istio_requests_total{destination_workload="<workload>", response_code=~"5.."}[1m]))

Label utama yang digunakan dalam kueri ini:

  • destination_workload — nama workload target

  • destination_workload_namespace — namespace workload target

  • reporter — diatur ke destination untuk pelaporan sisi server, source untuk sisi klien

Panduan ini menggunakan istio_requests_total untuk menskalakan berdasarkan laju permintaan. Ganti kueri PromQL dengan salah satu alternatif di atas untuk menskalakan berdasarkan latensi atau laju error.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

Langkah 1: Aktifkan pengumpulan metrik Prometheus

Aktifkan ASM untuk mengekspor metrik ke instans Prometheus Anda. Untuk instruksi detail, lihat Kumpulkan metrik pemantauan di Managed Service for Prometheus.

Langkah 2: Deploy adapter metrik kustom

Instal kube-metrics-adapter, yang mendaftarkan dirinya sebagai penyedia untuk External Metrics API dan menerjemahkan permintaan metrik HPA menjadi kueri Prometheus.

  1. Instal adapter dengan Helm. Ganti http://prometheus.istio-system.svc:9090 dengan URL server Prometheus Anda jika berjalan di namespace berbeda atau menggunakan nama layanan berbeda.

       helm -n kube-system install asm-custom-metrics ./kube-metrics-adapter \
         --set prometheus.url=http://prometheus.istio-system.svc:9090
  2. Verifikasi instalasi.

    1. Konfirmasi bahwa API autoscaling/v2 tersedia.

         kubectl api-versions | grep "autoscaling/v2"

      Output yang diharapkan:

         autoscaling/v2
    2. Periksa apakah pod adapter sedang berjalan.

         kubectl get po -n kube-system | grep metrics-adapter

      Output yang diharapkan:

         asm-custom-metrics-kube-metrics-adapter-85c6d5d865-2****   1/1     Running   0   19s
    3. Konfirmasi bahwa endpoint External Metrics API telah terdaftar.

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

      Output yang diharapkan:

         {
           "kind": "APIResourceList",
           "apiVersion": "v1",
           "groupVersion": "external.metrics.k8s.io/v1beta1",
           "resources": [
             {
               "name": "prometheus-query",
               "singularName": "",
               "namespaced": true,
               "kind": "ExternalMetricValueList",
               "verbs": [
                 "get"
               ]
             }
           ]
         }

      Array resources kosong karena belum ada HPA yang mendaftarkan kueri metrik. Array ini akan terisi setelah Anda men-deploy HPA di Langkah 4.

Langkah 3: Deploy aplikasi contoh

Buat namespace

Buat namespace bernama test dan aktifkan injeksi sidecar otomatis. Untuk informasi lebih lanjut, lihat Kelola namespace dan kuota dan Aktifkan injeksi otomatis.

Deploy aplikasi podinfo

  1. Buat file bernama podinfo.yaml dengan konten berikut.

    podinfo.yaml

       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: podinfo
         namespace: test
         labels:
           app: podinfo
       spec:
         minReadySeconds: 5
         strategy:
           rollingUpdate:
             maxUnavailable: 0
           type: RollingUpdate
         selector:
           matchLabels:
             app: podinfo
         template:
           metadata:
             annotations:
               prometheus.io/scrape: "true"
             labels:
               app: podinfo
           spec:
             containers:
             - name: podinfod
               image: stefanprodan/podinfo:latest
               imagePullPolicy: IfNotPresent
               ports:
               - containerPort: 9898
                 name: http
                 protocol: TCP
               command:
               - ./podinfo
               - --port=9898
               - --level=info
               livenessProbe:
                 exec:
                   command:
                   - podcli
                   - check
                   - http
                   - localhost:9898/healthz
                 initialDelaySeconds: 5
                 timeoutSeconds: 5
               readinessProbe:
                 exec:
                   command:
                   - podcli
                   - check
                   - http
                   - localhost:9898/readyz
                 initialDelaySeconds: 5
                 timeoutSeconds: 5
               resources:
                 limits:
                   cpu: 2000m
                   memory: 512Mi
                 requests:
                   cpu: 100m
                   memory: 64Mi
       ---
       apiVersion: v1
       kind: Service
       metadata:
         name: podinfo
         namespace: test
         labels:
           app: podinfo
       spec:
         type: ClusterIP
         ports:
           - name: http
             port: 9898
             targetPort: 9898
             protocol: TCP
         selector:
           app: podinfo
  2. Terapkan manifes.

       kubectl apply -n test -f podinfo.yaml

Menerapkan penguji beban

  1. Buat file bernama loadtester.yaml dengan konten berikut.

    loadtester.yaml

       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: loadtester
         namespace: test
         labels:
           app: loadtester
       spec:
         selector:
           matchLabels:
             app: loadtester
         template:
           metadata:
             labels:
               app: loadtester
             annotations:
               prometheus.io/scrape: "true"
           spec:
             containers:
               - name: loadtester
                 image: weaveworks/flagger-loadtester:0.18.0
                 imagePullPolicy: IfNotPresent
                 ports:
                   - name: http
                     containerPort: 8080
                 command:
                   - ./loadtester
                   - -port=8080
                   - -log-level=info
                   - -timeout=1h
                 livenessProbe:
                   exec:
                     command:
                       - wget
                       - --quiet
                       - --tries=1
                       - --timeout=4
                       - --spider
                       - http://localhost:8080/healthz
                   timeoutSeconds: 5
                 readinessProbe:
                   exec:
                     command:
                       - wget
                       - --quiet
                       - --tries=1
                       - --timeout=4
                       - --spider
                       - http://localhost:8080/healthz
                   timeoutSeconds: 5
                 resources:
                   limits:
                     memory: "512Mi"
                     cpu: "1000m"
                   requests:
                     memory: "32Mi"
                     cpu: "10m"
                 securityContext:
                   readOnlyRootFilesystem: true
                   runAsUser: 10001
       ---
       apiVersion: v1
       kind: Service
       metadata:
         name: loadtester
         namespace: test
         labels:
           app: loadtester
       spec:
         type: ClusterIP
         selector:
           app: loadtester
         ports:
           - name: http
             port: 80
             protocol: TCP
             targetPort: http
  2. Terapkan manifes.

       kubectl apply -n test -f loadtester.yaml

Verifikasi deployment

  1. Periksa apakah kedua pod berjalan dengan injeksi sidecar (2/2 kontainer). Output yang diharapkan:

       kubectl get pod -n test
       NAME                          READY   STATUS    RESTARTS   AGE
       loadtester-64df4846b9-nxhvv   2/2     Running   0          2m8s
       podinfo-6d845cc8fc-26xbq      2/2     Running   0          11m
  2. Kirim permintaan uji dari load tester untuk mengonfirmasi konektivitas. Respons sukses mengonfirmasi bahwa aplikasi contoh dapat dijangkau melalui mesh.

       export loadtester=$(kubectl -n test get pod -l "app=loadtester" \
         -o jsonpath='{.items[0].metadata.name}')
       kubectl -n test exec -it ${loadtester} -c loadtester -- \
         hey -z 5s -c 10 -q 2 http://podinfo.test:9898

Langkah 4: Konfigurasikan HPA dengan metrik ASM

Definisikan HPA yang menskalakan Deployment podinfo berdasarkan laju permintaan. Konfigurasi ini menghubungkan tiga komponen:

Apa yang Anda konfigurasikanDi mana ditempatkanTujuan
Kueri PromQLAnotasi HPAMenentukan metrik Prometheus yang akan dikueri
Nama metrik + labelspec.metrics[].externalKunci pencarian yang digunakan HPA untuk mereferensikan anotasi
Ambang batas targetspec.metrics[].external.targetLaju permintaan saat skala keluar dimulai
Contoh ini menggunakan versi API HPA autoscaling/v2, yang memerlukan Kubernetes 1.23 atau lebih baru. Versi v2beta2 telah dihapus di Kubernetes 1.26.
  1. Buat file bernama hpa.yaml dengan konten berikut.

    Penjelasan field utama:

    FieldDeskripsi
    metric-config.external.prometheus-query.prometheus/processed-requests-per-secondAnotasi yang menyematkan kueri PromQL. Akhiran (processed-requests-per-second) adalah nama yang ditentukan pengguna yang menghubungkan anotasi dengan pemilih metrik HPA.
    metrics[].external.metric.nameHarus prometheus-query — pengenal tetap yang dikenali oleh kube-metrics-adapter.
    metrics[].external.metric.selector.matchLabels.query-nameHarus sesuai dengan akhiran kunci anotasi (processed-requests-per-second).
    target.averageValueAmbang batas per pod. HPA membagi hasil total kueri dengan jumlah replika saat ini dan membandingkannya dengan nilai ini.
       apiVersion: autoscaling/v2
       kind: HorizontalPodAutoscaler
       metadata:
         name: podinfo
         namespace: test
         annotations:
           # Format anotasi: metric-config.external.prometheus-query.prometheus/<query-name>
           # <query-name> harus sesuai dengan label query-name di spec.metrics di bawah.
           # Nilainya adalah kueri PromQL yang dikirim kube-metrics-adapter ke Prometheus.
           metric-config.external.prometheus-query.prometheus/processed-requests-per-second: |
             sum(
                 rate(
                     istio_requests_total{
                       destination_workload="podinfo",
                       destination_workload_namespace="test",
                       reporter="destination"
                     }[1m]
                 )
             )
       spec:
         maxReplicas: 10
         minReplicas: 1
         scaleTargetRef:
           apiVersion: apps/v1
           kind: Deployment
           name: podinfo
         metrics:
           - type: External          # Gunakan External karena metrik Prometheus bukan objek Kubernetes
             external:
               metric:
                 name: prometheus-query                  # Nama metrik tetap untuk kube-metrics-adapter
                 selector:
                   matchLabels:
                     query-name: processed-requests-per-second  # Harus sesuai dengan kunci anotasi di atas
               target:
                 type: AverageValue
                 averageValue: "10"   # Lakukan skala keluar ketika laju permintaan rata-rata melebihi 10 req/s per pod
  2. Terapkan HPA.

       kubectl apply -f hpa.yaml
  3. Verifikasi bahwa External Metrics API sekarang mencantumkan metrik yang terdaftar. Output yang diharapkan: Resource prometheus-query mengonfirmasi bahwa HPA telah mendaftarkan metriknya ke adapter.

       kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq .
       {
         "kind": "APIResourceList",
         "apiVersion": "v1",
         "groupVersion": "external.metrics.k8s.io/v1beta1",
         "resources": [
           {
             "name": "prometheus-query",
             "singularName": "",
             "namespaced": true,
             "kind": "ExternalMetricValueList",
             "verbs": [
               "get"
             ]
           }
         ]
       }

Verifikasi skalabilitas otomatis

  1. Hasilkan beban berkelanjutan dari pod load tester. Ini mengirim 50 permintaan per detik (10 pekerja konkuren dengan 5 QPS masing-masing) selama 5 menit.

       # Dapatkan nama pod load tester (lewati ini jika $loadtester sudah diatur dari Langkah 3)
       export loadtester=$(kubectl -n test get pod -l "app=loadtester" \
         -o jsonpath='{.items[0].metadata.name}')
    
       kubectl -n test exec -it ${loadtester} -c loadtester -- \
         hey -z 5m -c 10 -q 5 http://podinfo.test:9898
  2. Pantau HPA di terminal terpisah. Output yang diharapkan (setelah sekitar satu menit):

    Catatan

    HPA menyinkronkan metrik setiap 30 detik. Keputusan penskalaan hanya berlaku jika tidak ada peristiwa penskalaan dalam 3–5 menit sebelumnya. Jeda ini mencegah keputusan penskalaan yang cepat dan bertentangan serta memberi waktu bagi Cluster Autoscaler untuk menyediakan node baru jika diperlukan.

       watch kubectl -n test get hpa/podinfo
       NAME      REFERENCE            TARGETS          MINPODS   MAXPODS   REPLICAS   AGE
       podinfo   Deployment/podinfo   8308m/10 (avg)   1         10        6          124m
  3. Amati skala turun setelah pengujian beban selesai. Ketika pengujian beban berakhir, laju permintaan turun menjadi nol. HPA secara bertahap melakukan skala turun Deployment hingga jumlah replika kembali ke 1.

Langkah selanjutnya

  • Untuk menskalakan berdasarkan latensi atau laju error alih-alih laju permintaan, ganti kueri PromQL di anotasi HPA dengan salah satu alternatif dari tabel Metrik ASM yang tersedia untuk autoscaling.

  • Untuk menyesuaikan perilaku skala naik dan skala turun (jendela stabilisasi, kebijakan penskalaan), tambahkan field behavior ke spesifikasi HPA. Lihat Configurable scaling behavior dalam dokumentasi Kubernetes.

  • Untuk daftar lengkap metrik Istio dan labelnya, lihat Istio standard metrics.