Portal/Notes πŸ“
Cka

Scaling: Horizontal Pod Autoscaler

Versi Bahasa Indonesia. Baca dalam Bahasa Inggris

Di Kubernetes, HorizontalPodAutoscaler secara otomatis memperbarui resource workload (seperti Deployment atau StatefulSet) dengan tujuan menskalakan workload secara otomatis sesuai permintaan.

Scaling horizontal berarti respons terhadap peningkatan beban adalah dengan menerapkan lebih banyak Pod. Ini berbeda dengan scaling vertikal, yang untuk Kubernetes berarti menetapkan lebih banyak resource (misalnya memory atau CPU) ke Pod yang sudah berjalan untuk workload tersebut.

Jika beban menurun, dan jumlah Pod di atas minimum yang dikonfigurasi, HorizontalPodAutoscaler menginstruksikan resource workload (Deployment, StatefulSet, atau resource serupa lainnya) untuk mengecilkan skala kembali.

Memperbarui Aplikasi Kita

Mari kita perbarui aplikasi kita terlebih dahulu untuk mengembalikan pesan yang di-hash menggunakan SHA256 untuk membuat beban CPU tambahan. Tambahkan field baru bernama Hash dalam definisi respons kita.

type Response struct {
    Message string `json:"message,omitempty"`
    Hash    string `json:"hash,omitempty"`
}

Tambahkan pesan yang di-hash ke field respons Hash dan kemudian bangun ulang aplikasi.

hasher := sha256.New()
hasher.Write([]byte(message))
hash := fmt.Sprintf("%x", hasher.Sum(nil))

res := Response{
    Message: message,
    Hash:    hash,
}

Mari kita terapkan aplikasi yang baru dibangun ke dalam klaster Kubernetes. Kita dapat melakukannya menggunakan perintah rollout restart. Kubernetes akan membuat pod baru dan menghapus pod lama setelah yang baru siap menerima traffic. Ini memastikan tidak ada downtime ke service ketika kita menerapkan versi baru aplikasi.

➜ kubectl rollout restart deployment/simple-go
deployment.apps/simple-go restarted

Kita dapat memeriksa menggunakan perintah get pod dan kita akan melihat kumpulan pod baru berjalan.

Mendefinisikan HPA

Selanjutnya, mari kita definisikan horizontal pod autoscaler. Kita dapat membuat file baru hpa.yaml dan masukkan definisi di bawah ini.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: simple-go-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: simple-go
  minReplicas: 3
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 50
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 120
      policies:
      - type: Pods
        value: 1
        periodSeconds: 15

spec.scaleTargetRef

Di bagian ini kita menentukan objek mana yang harus ditargetkan oleh autoscaler. Kita memilih objek deployment bernama simple-go sebagai target. Controller manager kemudian memilih pod berdasarkan label .spec.selector dari resource target (yang dalam kasus kita adalah app: simple-go), dan memperoleh metrics dari API resource metrics.

spec.minReplicas

Menentukan jumlah minimum Pod.

spec.maxReplicas

Menentukan jumlah maksimum Pod.

spec.metrics

Di bagian ini kita menentukan metrik apa yang harus dilihat oleh controller manager. Kita memilih cpu sebagai resource dengan target type: Utilization dan averageUtilization: 50. Ini berarti jika rata-rata penggunaan CPU pod di atas 50%, controller manager akan membuat pod baru.

Controller manager akan terus membuat pod baru hingga rata-rata penggunaan di bawah nilai yang ditentukan atau maxReplicas tercapai.

Jika rata-rata penggunaan di bawah nilai yang ditentukan untuk jangka waktu tertentu (default 300s), controller manager akan menghapus pod hingga minReplicas tercapai.

spec.behavior

Kita juga dapat menentukan bagaimana perilaku scaling. Perilaku default dapat dibaca di sini: HPA: Default Behavior.

Kita mendefinisikan bahwa perilaku scaleDown memiliki stabilizationWindowSeconds: 120, yang berarti controller manager perlu menunggu selama 120 detik atau 2 menit agar metrik stabil sebelum menghapus beberapa pod.

    policies:
      - type: Pods
        value: 1
        periodSeconds: 15

Kebijakan di sini berarti bahwa controller manager dapat menghapus 1 pod setiap 15s jika metrik sudah stabil.

Menerapkan dan Memvalidasi

Mari kita terapkan HPA menggunakan perintah apply dan validasi menggunakan get horizontalpodautoscalers.autoscaling.

➜ kubectl apply -f hpa.yaml 
horizontalpodautoscaler.autoscaling/simple-go-hpa create
➜ kubectl get horizontalpodautoscalers.autoscaling
NAME            REFERENCE              TARGETS                         
simple-go-hpa   Deployment/simple-go   cpu: 10%/50%  

MINPODS   MAXPODS   REPLICAS   AGE
3         10        3          26s

Pengujian Beban

Untuk menguji apakah HPA kita berfungsi seperti yang diharapkan, kita dapat membuat pengujian beban. Pengujian beban ini akan mensimulasikan peningkatan traffic ke service kita.

Kita menggunakan k6 untuk melakukan pengujian beban. Anda dapat mengunduh dan menginstalnya dengan mengikuti petunjuk di dokumentasi resmi. Setelah menginstal, buat file baru bernama load_test.js dan salin kode ini. Ubah url ke url service Anda dari Minikube.

import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  // A number specifying the number of VUs to run concurrently.
  vus: 100,
  // A string specifying the total duration of the test run.
  duration: '120s',
};

export default function() {
  http.get('http://127.0.0.1:64544'); // change to your service url from minikube
  sleep(1);
}

Pada dasarnya kita akan melakukan pengujian beban ke service kita selama 120s. Untuk menjalankan skrip, gunakan perintah k6 run <test_file> seperti ini.

➜ k6 run load_test.js

          /\      |β€Ύβ€Ύ| /β€Ύβ€Ύ/   /β€Ύβ€Ύ/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   β€Ύβ€Ύ\  
   /          \   |  |\  \ |  (β€Ύ)  | 
  / __________ \  |__| \__\ \_____/ .io

  execution: local
     script: load_test.js
     output: -

  scenarios: (100.00%) 1 scenario, 100 max VUs, 2m30s max duration (incl. graceful stop):
           * default: 100 looping VUs for 2m0s (gracefulStop: 30s)


running (0m23.3s), 100/100 VUs, 2207 complete and 0 interrupted iterations
default   [======>-------------------------------] 100 VUs  0m23.3s/2m0s

Pod Baru Dibuat

Setelah beberapa detik, mari kita periksa HPA kita dan kita akan melihat bahwa REPLICAS meningkat. Di mesin saya, saya melihat 6 replika yang berarti saya memiliki 3 pod baru yang berjalan. Di mesin Anda, ini mungkin berbeda. Ini berarti scale up berfungsi seperti yang diharapkan.

➜ kubectl get horizontalpodautoscalers.autoscaling
NAME            REFERENCE              TARGETS                          
simple-go-hpa   Deployment/simple-go   cpu: 93%/50%  

MINPODS   MAXPODS   REPLICAS   AGE
3         10        6          11m

Jika kita memeriksa daftar pod, kita juga akan melihat pod baru yang berjalan, Anda dapat membedakannya dari usia.

➜ kubectl get pods                                
simple-go-764bc77644-2dtbj   1/1     Running   0          33s
simple-go-764bc77644-8pfcs   1/1     Running   0          17m31s
simple-go-764bc77644-g9zph   1/1     Running   0          33s
simple-go-764bc77644-grfhg   1/1     Running   0          17m29s
simple-go-764bc77644-jf897   1/1     Running   0          33s
simple-go-764bc77644-snb8n   1/1     Running   0          17m26s

Beberapa menit setelah pengujian beban selesai, kita dapat memeriksa pod lagi dan kita akan melihat bahwa kita hanya memiliki 3 pod sekarang, sama dengan nilai minReplicas yang ditentukan.

➜ kubectl get pods  
NAME                         READY   STATUS    RESTARTS   AGE
simple-go-764bc77644-8pfcs   1/1     Running   0          25m
simple-go-764bc77644-grfhg   1/1     Running   0          25m
simple-go-764bc77644-snb8n   1/1     Running   0          25m

Ini berarti traffic service sudah stabil dan controller manager telah menghapus replika yang tidak diperlukan hingga mencapai jumlah minimum replika yang kita tentukan. Scale down dari HPA kita berfungsi seperti yang diharapkan.

Referensi


Edit on GitHub

Last updated on

Scaling: Horizontal Pod Autoscaler | Faisal Affan