Penskalaan otomatis pod horizontal (HPA)

Dokumen ini menjelaskan cara mengaktifkan penskalaan otomatis pod horizontal (HPA) untuk Google Cloud Managed Service for Prometheus. Anda dapat mengaktifkan HPA dengan melakukan salah satu hal berikut:

Anda tidak dapat menggunakan Stackdriver Adapter dan Prometheus Adapter secara bersamaan dalam cluster yang sama karena definisi resource-nya tumpang-tindih, seperti yang dijelaskan dalam Pemecahan Masalah. Sebaiknya pilih hanya satu solusi untuk HPA.

Menggunakan KEDA

KEDA (Kubernetes Event-driven Autoscaling) adalah autoscaler yang baru saja dirilis dan menggunakan metrik Prometheus, serta menjadi solusi yang disukai dalam komunitas Prometheus.

Untuk memulai, lihat dokumentasi KEDA untuk mengintegrasikan dengan Google Cloud Managed Service for Prometheus.

Menggunakan Adaptor Stackdriver Metrik Kustom

Custom Metrics Stackdriver Adapter mendukung kueri metrik dari Managed Service for Prometheus mulai dari versi v0.13.1 adaptor.

Untuk menyiapkan contoh konfigurasi HPA menggunakan Custom Metrics Stackdriver Adapter, lakukan hal berikut:

  1. Siapkan koleksi terkelola di cluster Anda.
  2. Instal Custom Metrics Stackdriver Adapter di cluster Anda.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml
    
  3. Deploy contoh pengekspor metrik Prometheus dan resource HPA:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/examples/prometheus-to-sd/custom-metrics-prometheus-sd.yaml
    

    Perintah ini men-deploy aplikasi pengekspor yang memancarkan metrik foo dan resource HPA. HPA menskalakan aplikasi ini hingga 5 replika untuk mencapai nilai target untuk metrik foo.

  4. Jika Anda menggunakan Workload Identity Federation untuk GKE, Anda juga harus memberikan peran Monitoring Viewer ke akun layanan yang digunakan adapter untuk berjalan. Lewati langkah ini jika Anda tidak mengaktifkan Workload Identity Federation for GKE di cluster Kubernetes Anda.

    export PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format 'get(projectNumber)')
    gcloud projects add-iam-policy-binding projects/PROJECT_ID \
      --role roles/monitoring.viewer \
      --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter
    
  5. Tentukan resource PodMonitoring dengan menempatkan konfigurasi berikut dalam file bernama podmonitoring.yaml.

    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: prom-example
    spec:
      selector:
        matchLabels:
          run: custom-metric-prometheus-sd
      endpoints:
      - port: 8080
        interval: 30s
    
  6. Deploy resource PodMonitoring baru:

    kubectl -n default apply -f podmonitoring.yaml
    

    Dalam beberapa menit, Managed Service for Prometheus akan memproses metrik yang di-scrape dari pengekspor dan menyimpannya di Cloud Monitoring menggunakan nama panjang. Metrik Prometheus disimpan dengan konvensi berikut:

    • Awalan prometheus.googleapis.com.
    • Sufiks ini biasanya adalah salah satu dari gauge, counter, summary, atau histogram, meskipun metrik yang tidak diketik mungkin memiliki sufiks unknown atau unknown:counter. Untuk memverifikasi akhiran, cari metrik di Cloud Monitoring menggunakan Metrics Explorer.
  7. Perbarui HPA yang di-deploy untuk membuat kueri metrik dari Cloud Monitoring. Metrik foo dimasukkan sebagai prometheus.googleapis.com/foo/gauge. Agar metrik dapat dikueri oleh resource HorizontalPodAutoscaler yang di-deploy, Anda menggunakan nama bentuk panjang di HPA yang di-deploy, tetapi Anda harus mengubahnya dengan mengganti semua garis miring ke depan (/) dengan karakter pipa (|): prometheus.googleapis.com|foo|gauge. Untuk mengetahui informasi selengkapnya, lihat bagian Metrik yang tersedia dari Stackdriver di repositori Custom Metrics Stackdriver Adapter.

    1. Perbarui HPA yang di-deploy dengan menjalankan perintah berikut:

      kubectl edit hpa custom-metric-prometheus-sd
      
    2. Ubah nilai kolom pods.metric.name dari foo menjadi prometheus.googleapis.com|foo|gauge. Bagian spec akan terlihat seperti berikut:

      spec:
         maxReplicas: 5
         metrics:
         - pods:
             metric:
               name: prometheus.googleapis.com|foo|gauge
             target:
               averageValue: "20"
               type: AverageValue
           type: Pods
         minReplicas: 1
      

    Dalam contoh ini, konfigurasi HPA mencari nilai rata-rata metrik prometheus.googleapis.com/foo/gauge menjadi 20. Karena Deployment menetapkan nilai metrik menjadi 40, pengontrol HPA akan meningkatkan jumlah pod hingga nilai kolom maxReplicas (5) untuk mencoba mengurangi nilai rata-rata metrik di semua pod menjadi 20.

    Kueri HPA dicakup ke namespace dan cluster tempat resource HPA diinstal, sehingga metrik yang identik di cluster dan namespace lain tidak memengaruhi penskalaan otomatis Anda.

  8. Untuk melihat penskalaan workload, jalankan perintah berikut:

    kubectl get hpa custom-metric-prometheus-sd --watch
    

    Nilai kolom REPLICAS berubah dari 1 menjadi 5.

    NAME                          REFERENCE                                TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
    custom-metric-prometheus-sd   Deployment/custom-metric-prometheus-sd   40/20          1         5         5          *
    
  9. Untuk menurunkan skala deployment, perbarui nilai metrik target agar lebih tinggi daripada nilai metrik yang diekspor. Dalam contoh ini, Deployment menetapkan nilai metrik prometheus.googleapis.com/foo/gauge ke 40. Jika Anda menetapkan nilai target ke angka yang lebih tinggi dari 40, maka deployment akan diskalakan ke bawah.

    Misalnya, gunakan kubectl edit untuk mengubah nilai kolom pods.target.averageValue dalam konfigurasi HPA dari 20 menjadi 100.

    kubectl edit hpa custom-metric-prometheus-sd
    

    Ubah bagian spesifikasi agar sesuai dengan yang berikut:

    spec:
      maxReplicas: 5
      metrics:
      - pods:
          metric:
            name: prometheus.googleapis.com|foo|gauge
          target:
            averageValue: "100"
            type: AverageValue
      type: Pods
      minReplicas: 1
    
  10. Untuk melihat penurunan skala workload, jalankan perintah berikut:

    kubectl get hpa custom-metric-prometheus-sd --watch
    

    Nilai kolom REPLICAS berubah dari 5 menjadi 1. Secara desain, hal ini terjadi lebih lambat daripada saat menskalakan jumlah pod:

    NAME                          REFERENCE                                TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
    custom-metric-prometheus-sd   Deployment/custom-metric-prometheus-sd   40/100          1         5         1          *
    
  11. Untuk membersihkan contoh yang di-deploy, jalankan perintah berikut:

    kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml
    kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/examples/prometheus-to-sd/custom-metrics-prometheus-sd.yaml
    kubectl delete podmonitoring/prom-example
    

Untuk mengetahui informasi selengkapnya, lihat contoh Prometheus di repositori Custom Metrics Stackdriver Adapter, atau lihat Menskalakan aplikasi.

Menggunakan Adaptor Prometheus

Konfigurasi prometheus-adapter yang ada dapat digunakan untuk penskalaan otomatis hanya dengan beberapa perubahan. Mengonfigurasi prometheus-adapter untuk melakukan penskalaan menggunakan Managed Service for Prometheus memiliki dua batasan tambahan dibandingkan dengan melakukan penskalaan menggunakan Prometheus upstream:

  • Kueri harus dirutekan melalui proxy UI frontend Prometheus, seperti saat membuat kueri Managed Service for Prometheus menggunakan API atau UI Prometheus. Untuk prometheus-adapter, Anda perlu mengedit prometheus-adapter Deployment untuk mengubah nilai prometheus-url sebagai berikut:

    --prometheus-url=http://frontend.NAMESPACE_NAME.svc:9090/
    

    dengan NAMESPACE_NAME adalah namespace tempat frontend di-deploy.

  • Anda tidak dapat menggunakan pencocok ekspresi reguler pada nama metrik di kolom .seriesQuery dari konfigurasi aturan. Sebagai gantinya, Anda harus menentukan nama metrik sepenuhnya.

Karena data mungkin memerlukan waktu lebih lama untuk tersedia dalam Managed Service for Prometheus dibandingkan dengan Prometheus upstream, mengonfigurasi logika penskalaan otomatis yang terlalu agresif dapat menyebabkan perilaku yang tidak diinginkan. Meskipun tidak ada jaminan keaktualan data, data biasanya tersedia untuk dikueri 3-7 detik setelah dikirim ke Managed Service for Prometheus, tidak termasuk latensi jaringan.

Semua kueri yang dikeluarkan oleh prometheus-adapter memiliki cakupan global. Artinya, jika Anda memiliki aplikasi di dua namespace yang memancarkan metrik dengan nama yang sama, konfigurasi HPA yang menggunakan metrik tersebut akan melakukan penskalaan menggunakan data dari kedua aplikasi. Sebaiknya selalu gunakan filter namespace atau cluster di PromQL Anda untuk menghindari penskalaan menggunakan data yang salah.

Untuk menyiapkan contoh konfigurasi HPA menggunakan prometheus-adapter dan pengumpulan terkelola, gunakan langkah-langkah berikut:

  1. Siapkan koleksi terkelola di cluster Anda.
  2. Deploy proxy UI frontend Prometheus di cluster Anda. Jika Anda menggunakan Workload Identity Federation untuk GKE, Anda juga harus mengonfigurasi dan mengizinkan akun layanan.
  3. Deploy manifes di direktori examples/hpa/ dalam repo prometheus-engine:
    • example-app.yaml: Contoh deployment dan layanan yang menghasilkan metrik.
    • pod-monitoring.yaml: Resource yang mengonfigurasi pengambilan contoh metrik.
    • hpa.yaml: Resource HPA yang mengonfigurasi penskalaan untuk workload Anda.
  4. Pastikan prometheus-adapter diinstal di cluster Anda. Hal ini dapat dilakukan dengan men-deploy contoh manifes penginstalan ke cluster Anda. Manifes ini dikonfigurasi untuk:

    • Kueri proxy frontend yang di-deploy di namespace default.
    • Keluarkan PromQL untuk menghitung dan menampilkan metrik http_requests_per_second dari contoh deployment.
  5. Jalankan perintah berikut, masing-masing di sesi terminal terpisah:

    1. Buat beban HTTP terhadap layanan prometheus-example-app:
      kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://prometheus-example-app; done"
    2. Amati autoscaler pod horizontal:
      kubectl get hpa prometheus-example-app --watch
    3. Amati peningkatan skala workload:
      kubectl get po -lapp.kubernetes.io/name=prometheus-example-app --watch
  6. Hentikan pembuatan beban HTTP menggunakan Ctrl+C dan amati penskalaan kembali beban kerja.

Pemecahan masalah

Custom Metrics Stackdriver Adapter menggunakan definisi resource dengan nama yang sama seperti di Prometheus Adapter, prometheus-adapter. Tumpang-tindih nama ini berarti menjalankan lebih dari satu adaptor di cluster yang sama akan menyebabkan error.

Menginstal Prometheus Adapter di cluster yang sebelumnya telah menginstal Custom Metrics Stackdriver Adapter dapat memunculkan error seperti FailedGetObjectMetric karena nama yang bertabrakan. Untuk mengatasinya, Anda mungkin harus menghapus apiservice v1beta1.external.metrics.k8s.io, v1beta1.custom.metrics.k8s.io, dan v1beta2.custom.metrics.k8s.io yang sebelumnya didaftarkan oleh Adaptor Metrik Kustom.

Tips pemecahan masalah:

  • Beberapa metrik sistem Cloud Monitoring seperti metrik Pub/Sub tertunda selama 60 detik atau lebih. Karena Prometheus Adapter menjalankan kueri menggunakan stempel waktu saat ini, membuat kueri metrik ini menggunakan Prometheus Adapter dapat menghasilkan data yang salah. Untuk membuat kueri metrik yang tertunda, gunakan pengubah offset di PromQL untuk mengubah offset waktu kueri Anda sebesar jumlah yang diperlukan.

  • Untuk memverifikasi bahwa proxy UI frontend berfungsi seperti yang diharapkan dan tidak ada masalah dengan izin, jalankan perintah berikut di terminal:

    kubectl -n NAMESPACE_NAME port-forward svc/frontend 9090
    

    Selanjutnya, buka terminal lain dan jalankan perintah berikut:

    curl --silent 'localhost:9090/api/v1/series?match%5B%5D=up'
    

    Jika proxy UI frontend berfungsi dengan baik, respons di terminal kedua akan terlihat seperti berikut:

    curl --silent 'localhost:9090/api/v1/series?match%5B%5D=up' | jq .
    {
      "status": "success",
      "data": [
         ...
      ]
    }
    

    Jika Anda menerima error 403, berarti proxy UI frontend tidak dikonfigurasi dengan benar. Untuk mengetahui informasi tentang cara mengatasi error 403, lihat panduan mengonfigurasi dan memberikan otorisasi akun layanan.

  • Untuk memverifikasi bahwa server API metrik kustom tersedia, jalankan perintah berikut:

    kubectl get apiservices.apiregistration.k8s.io v1beta1.custom.metrics.k8s.io
    

    Jika apiserver tersedia, responsnya akan mirip dengan berikut ini:

    $ kubectl get apiservices.apiregistration.k8s.io v1beta1.custom.metrics.k8s.io
    NAME                            SERVICE                         AVAILABLE   AGE
    v1beta1.custom.metrics.k8s.io   monitoring/prometheus-adapter   True        33m
    
  • Untuk memverifikasi bahwa HPA Anda berfungsi sebagaimana mestinya, jalankan perintah berikut:

    $ kubectl describe hpa prometheus-example-app
    Name:                                  prometheus-example-app
    Namespace:                             default
    Labels:                                
    Annotations:                           
    Reference:                             Deployment/prometheus-example-app
    Metrics:                               ( current / target )
    "http_requests_per_second" on pods:  11500m / 10
    Min replicas:                          1
    Max replicas:                          10
    Deployment pods:                       2 current / 2 desired
    Conditions:
    Type            Status  Reason              Message
    ----            ------  ------              -------
    AbleToScale     True    ReadyForNewScale    recommended size matches current size
    ScalingActive   True    ValidMetricFound    the HPA was able to successfully calculate a replica count from pods metric http_requests_per_second
    ScalingLimited  False   DesiredWithinRange  the desired count is within the acceptable range
    Events:
    Type     Reason               Age                   From                       Message
    ----     ------               ----                  ----                       -------
    Normal   SuccessfulRescale    47s                   horizontal-pod-autoscaler  New size: 2; reason: pods metric http_requests_per_second above target
    

    Jika respons berisi pernyataan seperti FailedGetPodsMetric, maka HPA gagal. Berikut ini mengilustrasikan respons terhadap panggilan describe saat HPA gagal:

    $ kubectl describe hpa prometheus-example-app
    Name:                                  prometheus-example-app
    Namespace:                             default
    Reference:                             Deployment/prometheus-example-app
    Metrics:                               ( current / target )
      "http_requests_per_second" on pods:   / 10
    Min replicas:                          1
    Max replicas:                          10
    Deployment pods:                       1 current / 1 desired
    Conditions:
      Type            Status  Reason               Message
      ----            ------  ------               -------
      AbleToScale     True    ReadyForNewScale     recommended size matches current size
      ScalingActive   False   FailedGetPodsMetric  the HPA was unable to compute the replica count: unable to get metric http_requests_per_second: unable to fetch metrics from custom metrics API: the server could not find the metric http_requests_per_second for pods
      ScalingLimited  False   DesiredWithinRange   the desired count is within the acceptable range
    Events:
      Type     Reason               Age                   From                       Message
      ----     ------               ----                  ----                       -------
      Warning  FailedGetPodsMetric  104s (x11 over 16m)   horizontal-pod-autoscaler  unable to get metric http_requests_per_second: unable to fetch metrics from custom metrics API: the server could not find the metric http_requests_per_second for pods
    

    Jika HPA gagal, pastikan Anda membuat metrik dengan load-generator. Anda dapat memeriksa API metrik kustom secara langsung, dengan perintah:

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

    Output yang berhasil akan tampak seperti berikut ini:

    $ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | jq .
      {
      "kind": "APIResourceList",
      "apiVersion": "v1",
      "groupVersion": "custom.metrics.k8s.io/v1beta1",
      "resources": [
         {
            "name": "namespaces/http_requests_per_second",
            "singularName": "",
            "namespaced": false,
            "kind": "MetricValueList",
            "verbs": [
            "get"
            ]
         },
         {
            "name": "pods/http_requests_per_second",
            "singularName": "",
            "namespaced": true,
            "kind": "MetricValueList",
            "verbs": [
            "get"
            ]
         }
      ]
      }
    

    Jika tidak ada metrik, tidak akan ada data di bagian "resources" dalam output, misalnya:

    kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | jq .
    {
    "kind": "APIResourceList",
    "apiVersion": "v1",
    "groupVersion": "custom.metrics.k8s.io/v1beta1",
    "resources": []
    }