All Products
Search
Document Center

Container Service for Kubernetes:Skalabilitas elastis berbasis HPA dengan Pemantauan Aplikasi ARMS

Last Updated:Mar 26, 2026

Saat terjadi lonjakan traffic API, aplikasi Anda perlu melakukan scaling cukup cepat agar mampu mengimbangi beban. Panduan ini menjelaskan cara menggerakkan Horizontal Pod Autoscaler (HPA) menggunakan data QPS (queries per second) langsung yang dikumpulkan oleh ARMS Application Monitoring—sehingga Pod Anda diskalakan berdasarkan beban permintaan aktual, bukan hanya CPU atau memori.

Cara kerja

ARMS Application Monitoring menginstrumen aplikasi Java Anda dan mengekspos jumlah permintaan per-API sebagai metrik Prometheus. Komponen ack-alibaba-cloud-metrics-adapter membaca metrik tersebut dan menyajikannya ke Kubernetes HPA melalui External Metrics API. HPA kemudian melakukan scaling Penyebaran (Deployment) Anda naik atau turun berdasarkan ambang batas yang Anda konfigurasikan.

Jalur data lengkapnya adalah:

ARMS Application Monitoring mengumpulkan jumlah permintaan per-API dari aplikasi Java Anda → Alibaba Cloud Prometheus menyimpan metrik tersebut → ack-alibaba-cloud-metrics-adapter mengonversi data Prometheus ke dalam format Kubernetes External Metrics API → Kubernetes HPA membaca metrik tersebut dan melakukan scaling Penyebaran Anda naik atau turun.

Panduan ini menggunakan aplikasi arms-springboot-demo dan titik akhir (endpoint) /demo/queryUser/10 sebagai contoh sepanjang panduan.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

hpa

Langkah 1: Instal komponen ARMS Application Monitoring

Instal komponen ack-onepilot untuk menghubungkan aplikasi Anda ke ARMS Application Monitoring.

  1. Masuk ke Konsol ACK. Di panel navigasi kiri, klik Clusters.

  2. Di halaman Clusters, klik nama kluster. Di panel navigasi kiri, klik Add-ons.

  3. Cari ack-onepilot, konfigurasikan parameternya, dan selesaikan instalasi.

Langkah 2: Berikan izin akses ARMS

Otorisasi yang diperlukan bergantung pada jenis kluster Anda.

Untuk kluster ACK Serverless atau aplikasi yang terhubung ke ECI:

Lengkapi otorisasi di halaman RAM Quick Authorization, lalu restart semua Pod komponen ack-onepilot.

Untuk kluster ACK standar:

Periksa apakah ARMS Addon Token ada di kluster.

  1. Masuk ke Konsol ACK. Di panel navigasi kiri, klik Clusters.

  2. Di halaman Clusters, klik nama kluster. Di panel navigasi kiri, pilih Configurations > Secrets.

  3. Di bagian atas halaman, atur Namespace ke kube-system dan periksa apakah addon.arms.token ada.

  • Jika token tersebut ada: ARMS melakukan otorisasi tanpa kata sandi secara otomatis.

    Kluster ACK yang dikelola mencakup ARMS Addon Token secara default. Beberapa kluster yang dikelola versi lama mungkin tidak memilikinya—dalam kasus tersebut, berikan izin secara manual menggunakan langkah-langkah di bawah.
  • Jika token tersebut tidak ada: Berikan izin secara manual.

    1. Buat kebijakan kustom dengan konten berikut. Lihat Langkah 1: Buat kebijakan kustom. ``json { "Action": "arms:*", "Resource": "*", "Effect": "Allow" } ``

    2. Lampirkan kebijakan kustom tersebut ke peran RAM worker kluster. Lihat Langkah 2: Berikan izin ke peran RAM worker kluster.

Langkah 3: Aktifkan ARMS Application Monitoring untuk aplikasi Java Anda

Aktifkan pemantauan dengan menambahkan label ke bagian spec.template.metadata Penyebaran Anda.

  1. Masuk ke Konsol ACK. Di panel navigasi kiri, klik Clusters.

  2. Di halaman Clusters, klik nama kluster. Di panel navigasi kiri, pilih Workloads > Deployments.

  3. Di halaman Deployments, klik Create from YAML.

  4. Pilih templat dari Sample Templates. Di bidang Templates, tambahkan label berikut ke spec.template.metadata:

    Mengaktifkan Application Security akan menimbulkan biaya tambahan. Lihat Apa itu Application Security? dan Penagihan.
    labels:
      armsPilotAutoEnable: "on"
      armsPilotCreateAppName: "<your-deployment-name>"  # Wajib: ganti dengan nama aplikasi Anda
      one-agent.jdk.version: "OpenJDK11"               # Wajib hanya untuk JDK 11
      armsSecAutoEnable: "on"                           # Opsional: mengaktifkan Application Security

    YAML lengkap di bawah ini menerapkan aplikasi arms-springboot-demo dengan pemantauan ARMS yang diaktifkan. Contoh YAML lengkap (Java)

    apiVersion: v1
    kind: Namespace
    metadata:
      name: arms-demo
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: arms-springboot-demo
      namespace: arms-demo
      labels:
        app: arms-springboot-demo
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: arms-springboot-demo
      template:
        metadata:
          labels:
            app: arms-springboot-demo
            armsPilotAutoEnable: "on"
            armsPilotCreateAppName: "arms-k8s-demo"
            one-agent.jdk.version: "OpenJDK11"
        spec:
          containers:
            - resources:
                limits:
                  cpu: 0.5
              image: registry.cn-hangzhou.aliyuncs.com/arms-docker-repo/arms-springboot-demo:v0.1
              imagePullPolicy: Always
              name: arms-springboot-demo
              env:
                - name: SELF_INVOKE_SWITCH
                  value: "true"
                - name: COMPONENT_HOST
                  value: "arms-demo-component"
                - name: COMPONENT_PORT
                  value: "6666"
                - name: MYSQL_SERVICE_HOST
                  value: "arms-demo-mysql"
                - name: MYSQL_SERVICE_PORT
                  value: "3306"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        name: arms-springboot-demo
      name: arms-springboot-demo
      namespace: arms-demo
    spec:
      ports:
        - name: arms-demo-svc
          port: 6666
          targetPort: 8888
      selector:
        app: arms-springboot-demo
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: arms-springboot-demo-subcomponent
      namespace: arms-demo
      labels:
        app: arms-springboot-demo-subcomponent
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: arms-springboot-demo-subcomponent
      template:
        metadata:
          labels:
            app: arms-springboot-demo-subcomponent
            armsPilotAutoEnable: "on"
            armsPilotCreateAppName: "arms-k8s-demo-subcomponent"
            one-agent.jdk.version: "OpenJDK11"
        spec:
          containers:
            - resources:
                limits:
                  cpu: 0.5
              image: registry.cn-hangzhou.aliyuncs.com/arms-docker-repo/arms-springboot-demo:v0.1
              imagePullPolicy: Always
              name: arms-springboot-demo-subcomponent
              env:
                - name: SELF_INVOKE_SWITCH
                  value: "false"
                - name: MYSQL_SERVICE_HOST
                  value: "arms-demo-mysql"
                - name: MYSQL_SERVICE_PORT
                  value: "3306"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        name: arms-demo-component
      name: arms-demo-component
      namespace: arms-demo
    spec:
      ports:
        - name: arms-demo-component-svc
          port: 6666
          targetPort: 8888
      selector:
        app: arms-springboot-demo-subcomponent
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: arms-demo-mysql
      namespace: arms-demo
      labels:
        app: mysql
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mysql
      template:
        metadata:
          labels:
            app: mysql
        spec:
          containers:
            - resources:
                limits:
                  cpu: 0.5
              image: registry.cn-hangzhou.aliyuncs.com/arms-docker-repo/arms-demo-mysql:v0.1
              name: mysql
              ports:
                - containerPort: 3306
                  name: mysql
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        name: mysql
      name: arms-demo-mysql
      namespace: arms-demo
    spec:
      ports:
        - name: arms-mysql-svc
          port: 3306
          targetPort: 3306
      selector:
        app: mysql

    YAML Example

  5. Verifikasi penerapan. Di halaman Deployments, tombol ARMS Console muncul di kolom Actions untuk aplikasi target. Klik ARMS Console untuk melihat data pemantauan. Di panel navigasi kiri, klik Interface Invocation untuk melihat detail akses antarmuka HTTP. Aplikasi demo secara otomatis menghasilkan panggilan antarmuka berkelanjutan.

    ARMS Console Button

    4

  6. Buat Service untuk arms-springboot-demo dan aktifkan load balancing.

    1. Di halaman Clusters, klik nama kluster. Di panel navigasi kiri, pilih Network > Services.

    2. Klik Create, konfigurasikan Service, lalu klik OK. Lihat Buat Service untuk detail konfigurasi.

    3. Setelah Service dibuat, catat External IP dari arms-demo-svc (misalnya, 47.94.XX.XX:8080).

    4. Uji titik akhir: ``shell curl http://47.94.XX.XX:8080/demo/queryUser/10 ` Output yang diharapkan: `json {"id":1,"name":"KeyOfSpectator","password":"12****"} ``

Langkah 4: Konfigurasikan adapter metrik

Penting

Pemantauan Alibaba Cloud Prometheus dan komponen ack-alibaba-cloud-metrics-adapter (yang diterapkan di kube-system) harus keduanya berjalan sebelum Anda melanjutkan.

Langkah ini memetakan data jumlah permintaan ARMS APM ke metrik eksternal bernama yang dapat dikonsumsi oleh HPA. Nama metrik yang digunakan dalam hpa.yaml (Langkah 5) dihasilkan dari bidang name.as yang Anda konfigurasikan di sini.

4.1 Dapatkan URL Prometheus

  1. Masuk ke Konsol ARMS.

  2. Di panel navigasi kiri, pilih Managed Service for Prometheus > Instances.

  3. Klik nama instance target (format: arms_metrics_{RegionId}_XXX). Di panel navigasi kiri, klik Settings.

  4. Di bagian bawah tab Settings, catat HTTP API URL (Grafana Read URL). Ini adalah URL Prometheus Anda.

    5

4.2 Atur URL Prometheus di adapter

  1. Masuk ke Konsol ACK. Di panel navigasi kiri, klik Clusters.

  2. Di halaman Clusters, klik nama kluster. Di panel navigasi kiri, pilih Applications > Helm.

  3. Di halaman Helm, temukan ack-alibaba-cloud-metrics-adapter dan klik Update di kolom Actions.

  4. Di panel Update Release, masukkan URL Prometheus yang telah Anda catat sebelumnya.

    8

4.3 Tambahkan aturan metrik ARMS ke adapter-config

  1. Di halaman Helm, klik ack-alibaba-cloud-metrics-adapter.

  2. Di tab Basic Information, klik adapter-config.

  3. Di pojok kanan atas, klik Edit YAML.

  4. Tambahkan aturan berikut ke adapter-config:

    rules:
    - metricsQuery: sum(sum_over_time_lorc(<<.Series>>{service="arms-k8s-demo",clusterId="cc13c8725******a9839190b7d1695d7",serverIp=~".*",callKind=~"http|rpc|custom_entry|server|consumer|schedule",source="apm",<<.LabelMatchers>>}[1m])) or vector(0)
    #                                                    ^^ Ganti dengan nama layanan ARMS Anda
    #                                                                          ^^ Ganti dengan ID kluster Anda
      name:
        as: "${1}_per_second"       # Menghasilkan nama metrik HPA: arms_app_requests_per_second
        matches: "^(.*)_count_ign_destid_endpoint_ppid_prpc"
      resources:
        namespaced: false
      seriesQuery: arms_app_requests_count_ign_destid_endpoint_ppid_prpc{service="arms-k8s-demo",clusterId="cc13c8725******a9839190b7d1695d7"}
    #                                                                     ^^ Ganti dengan nama layanan ARMS dan ID kluster Anda
    

    Ganti arms-k8s-demo dengan nama layanan ARMS Anda dan cc13c8725****a9839190b7d1695d7 dengan ID kluster Anda. Contoh lengkap adapter-config.

    apiVersion: v1
    data:
      config.yaml: >
        rules:
    
        - metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)
          name:
            as: ${1}_bytes_per_second
            matches: ^(.*)_bytes
          resources:
            overrides:
              namespace:
                resource: namespace
              pod:
                resource: pod
          seriesQuery: container_memory_working_set_bytes{namespace!="",pod!=""}
        - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by
        (<<.GroupBy>>)
          name:
            as: ${1}_core_per_second
            matches: ^(.*)_seconds_total
          resources:
            overrides:
              namespace:
                resource: namespace
              pod:
                resource: pod
          seriesQuery: container_cpu_usage_seconds_total{namespace!="",pod!=""}
        - metricsQuery: sum(sum_over_time_lorc(<<.Series>>{service="arms-k8s-demo",clusterId="cc13c8725******a9839190b7d1695d7",serverIp=~".*",callKind=~"http|rpc|custom_entry|server|consumer|schedule",source="apm",<<.LabelMatchers>>}[1m])) or vector(0)
          name:
            as: "${1}_per_second"
            matches: "^(.*)_count_ign_destid_endpoint_ppid_prpc"
          resources:
            namespaced: false
          seriesQuery: arms_app_requests_count_ign_destid_endpoint_ppid_prpc{service="arms-k8s-demo",clusterId="cc13c8725******a9839190b7d1695d7"}
    kind: ConfigMap
    metadata:
      annotations:
        meta.helm.sh/release-name: ack-alibaba-cloud-metrics-adapter
        meta.helm.sh/release-namespace: kube-system
      creationTimestamp: '2024-04-02T02:29:32Z'
      labels:
        app.kubernetes.io/managed-by: Helm
      managedFields:
        - apiVersion: v1
          fieldsType: FieldsV1
          fieldsV1:
            'f:data':
              .: {}
              'f:config.yaml': {}
            'f:metadata':
              'f:annotations':
                .: {}
                'f:meta.helm.sh/release-name': {}
                'f:meta.helm.sh/release-namespace': {}
              'f:labels':
                .: {}
                'f:app.kubernetes.io/managed-by': {}
          manager: rc
          operation: Update
          time: '2024-04-02T02:40:52Z'
      name: adapter-config
      namespace: kube-system
      resourceVersion: '8223891'
      uid: 294634e6-aeae-4048-9e69-365a4ce4b2cd

4.4 Verifikasi metrik tersedia

  1. Periksa apakah arms_app_requests_per_second muncul di External Metrics API:

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

    Cari "name":"arms_app_requests_per_second" di output.

  2. Periksa apakah metrik mengembalikan data real-time:

    kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/arms-demo/arms_app_requests_per_second" | jq .

    Output yang diharapkan:

    {
      "kind": "ExternalMetricValueList",
      "apiVersion": "external.metrics.k8s.io/v1beta1",
      "metadata": {},
      "items": [
        {
          "metricName": "arms_app_requests_per_second",
          "metricLabels": {},
          "timestamp": "2025-02-13T02:51:31Z",
          "value": "2"
        }
      ]
    }

Langkah 5: Buat HPA

Buat hpa.yaml dengan konten berikut.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: test-hpa
  namespace: arms-demo
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: arms-springboot-demo
  minReplicas: 1
  maxReplicas: 10
  metrics:
    - type: External
      external:
        metric:
          name: arms_app_requests_per_second   # Harus sesuai dengan nama yang dihasilkan oleh adapter-config (bidang name.as di Langkah 4.3)
        target:
          type: AverageValue
          averageValue: 40                     # Lakukan scale-out saat QPS melebihi 40; metrik eksternal hanya mendukung Value dan AverageValue

Terapkan HPA:

kubectl apply -f hpa.yaml

Verifikasi bahwa data metrik sedang diambil:

kubectl get hpa -n arms-demo

Output yang diharapkan:

NAME       REFERENCE                         TARGETS       MINPODS   MAXPODS   REPLICAS   AGE
test-hpa   Deployment/arms-springboot-demo   12/40 (avg)   1         10        1          113s

Nilai TARGETS yang tidak kosong mengonfirmasi bahwa HPA berhasil membaca data metrik.

Langkah 6: Verifikasi skalabilitas elastis dengan uji stres

Jalankan uji stres terhadap aplikasi demo. Ganti 47.94.XX.XX:8080 dengan endpoint eksternal arms-demo-svc.

ab -c 50 -n 2000 http://47.94.XX.XX:8080/demo/queryUser/10

Saat pengujian berlangsung, pantau HPA:

kubectl get hpa -n arms-demo

Output yang diharapkan setelah scaling:

NAME       REFERENCE                         TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
test-hpa   Deployment/arms-springboot-demo   47500m/40 (avg)   1         10        10         6m43s

Periksa efek scaling dari tiga tampilan:

  • Konsol ARMS: Volume permintaan untuk antarmuka melonjak tajam selama uji stres.

    image

  • Dasbor Prometheus: HPA memicu scale-out saat QPS melebihi ambang batas yang dikonfigurasi.

    image

  • Kluster ACK: Jumlah replika Pod melakukan scaling in dan out sesuai dengan QPS panggilan antarmuka.

Untuk melihat riwayat lengkap event scaling, jalankan:

kubectl describe hpa test-hpa -n arms-demo

Contoh lanjutan

Contoh berikut menunjukkan cara mengonfigurasi adapter metrik untuk skenario scaling yang lebih spesifik. Semua contoh menggunakan sum_over_time_lorc untuk mengagregasi jumlah permintaan dalam jendela waktu 1 menit.

Scaling beberapa layanan secara independen

Definisikan satu aturan per layanan, berikan masing-masing nama metrik unik sehingga HPA dapat menargetkannya secara terpisah.

rules:
- metricsQuery: sum(sum_over_time_lorc(<<.Series>>{service="arms-k8s-demo",clusterId="cc13c8725******a9839190b7d1695d7",serverIp=~".*",callKind=~"http|rpc|custom_entry|server|consumer|schedule",source="apm",<<.LabelMatchers>>}[1m])) or vector(0)
  name:
    as: "${1}_per_second_arms_k8s_demo"
    matches: "^(.*)_count_ign_destid_endpoint_ppid_prpc"
  resources:
    namespaced: false
  seriesQuery: arms_app_requests_count_ign_destid_endpoint_ppid_prpc{service="arms-k8s-demo",clusterId="cc13c8725******a9839190b7d1695d7"}
- metricsQuery: sum(sum_over_time_lorc(<<.Series>>{service="arms-k8s-demo-subcomponent",clusterId="cc13c8725******a9839190b7d1695d7",serverIp=~".*",callKind=~"http|rpc|custom_entry|server|consumer|schedule",source="apm",<<.LabelMatchers>>}[1m])) or vector(0)
  name:
    as: "${1}_per_second_arms_k8s_demo_subcomponent"
    matches: "^(.*)_count_ign_destid_endpoint_ppid_prpc"
  resources:
    namespaced: false
  seriesQuery: arms_app_requests_count_ign_destid_endpoint_ppid_prpc{service="arms-k8s-demo-subcomponent",clusterId="cc13c8725******a9839190b7d1695d7"}

Scaling berdasarkan titik akhir RPC tertentu

Tambahkan label rpc ke kueri untuk menargetkan satu titik akhir saja, bukan seluruh traffic untuk suatu layanan.

rules:
- metricsQuery: sum(sum_over_time_lorc(<<.Series>>{service="arms-k8s-demo",rpc="/demo/queryUser/{id}",clusterId="cc13c8725******a9839190b7d1695d7",serverIp=~".*",callKind=~"http|rpc|custom_entry|server|consumer|schedule",source="apm",<<.LabelMatchers>>}[1m])) or vector(0)
  name:
    as: "${1}_per_second_arms_k8s_demo_queryUser"
    matches: "^(.*)_count_ign_destid_endpoint_ppid_prpc"
  resources:
    namespaced: false
  seriesQuery: arms_app_requests_count_ign_destid_endpoint_ppid_prpc{service="arms-k8s-demo",rpc="/demo/queryUser/{id}",clusterId="cc13c8725******a9839190b7d1695d7"}
- metricsQuery: sum(sum_over_time_lorc(<<.Series>>{service="arms-k8s-demo",rpc="/demo/queryException/{id}",clusterId="cc13c8725******a9839190b7d1695d7",serverIp=~".*",callKind=~"http|rpc|custom_entry|server|consumer|schedule",source="apm",<<.LabelMatchers>>}[1m])) or vector(0)
  name:
    as: "${1}_per_second__arms_k8s_demo_queryException"
    matches: "^(.*)_count_ign_destid_endpoint_ppid_prpc"
  resources:
    namespaced: false
  seriesQuery: arms_app_requests_count_ign_destid_endpoint_ppid_prpc{service="arms-k8s-demo",rpc="/demo/queryException/{id}",clusterId="cc13c8725******a9839190b7d1695d7"}
- metricsQuery: sum(sum_over_time_lorc(<<.Series>>{service="arms-k8s-demo",rpc="/demo/queryNotExistDB/{id}",clusterId="cc13c8725******a9839190b7d1695d7",serverIp=~".*",callKind=~"http|rpc|custom_entry|server|consumer|schedule",source="apm",<<.LabelMatchers>>}[1m])) or vector(0)
  name:
    as: "${1}_per_second__arms_k8s_demo_queryNotExistDB"
    matches: "^(.*)_count_ign_destid_endpoint_ppid_prpc"
  resources:
    namespaced: false
  seriesQuery: arms_app_requests_count_ign_destid_endpoint_ppid_prpc{service="arms-k8s-demo",rpc="/demo/queryNotExistDB/{id}",clusterId="cc13c8725******a9839190b7d1695d7"}

Referensi