Menggunakan preemptible VM untuk menjalankan workload fault-tolerant


Halaman ini menunjukkan cara menggunakan preemptible VM di Google Kubernetes Engine (GKE).

Ringkasan

Preemptible VM adalah instance VM Compute Engine yang harganya lebih rendah daripada VM standar dan tidak memberikan jaminan ketersediaan. Preemptible VM menawarkan fungsi yang serupa dengan Spot VM, tetapi hanya bertahan hingga 24 jam setelah pembuatan.

Dalam beberapa kasus, preemptible VM mungkin bertahan lebih dari 24 jam. Hal ini dapat terjadi jika instance Compute Engine baru muncul terlalu cepat dan Kubernetes tidak mengenali bahwa VM Compute Engine yang berbeda telah dibuat. Instance Compute Engine yang mendasarinya akan memiliki durasi maksimum 24 jam dan mengikuti perilaku preemptible VM yang diharapkan.

Perbandingan dengan Spot VM

Preemptible VM memiliki banyak kesamaan dengan Spot VM, termasuk:

  • Dihentikan saat Compute Engine memerlukan resource untuk menjalankan VM standar.
  • Berguna untuk menjalankan workload stateless, batch, atau fault-tolerant.
  • Harga lebih rendah daripada VM standar.
  • Pada cluster yang menjalankan GKE versi 1.20 dan yang lebih baru, pemadaman node tuntas diaktifkan secara default.
  • Dapat digunakan dengan autoscaler cluster dan penyediaan otomatis node.

Berbeda dengan Spot VM, yang tidak memiliki waktu habis masa berlaku maksimum, preemptible VM hanya bertahan hingga 24 jam setelah pembuatan.

Anda dapat mengaktifkan preemptible VM pada cluster dan node pool baru, menggunakan nodeSelector atau afinitas node untuk mengontrol penjadwalan, serta menggunakan taint dan toleransi untuk menghindari masalah terkait beban kerja sistem saat node di-preempt.

Penghentian dan pemadaman tuntas preemptible VM

Saat Compute Engine perlu mengklaim kembali resource yang digunakan oleh preemptible VM, pemberitahuan preemption akan dikirim ke GKE. Preemptible VM dihentikan 30 detik setelah menerima pemberitahuan penghentian.

Secara default, cluster menggunakan penghentian node secara halus. Kubelet merespons pemberitahuan penghentian dan secara tuntas menghentikan Pod yang berjalan di node. Jika Pod adalah bagian dari Deployment, pengontrol akan membuat dan menjadwalkan Pod baru untuk menggantikan Pod yang dihentikan.

Atas dasar upaya terbaik, kubelet memberikan periode penghentian tuntas selama 15 detik untuk Pod non-sistem, setelah itu Pod sistem (dengan priorityClasses system-cluster-critical atau system-node-critical) memiliki waktu 15 detik untuk tuntas dihentikan.

Selama penghentian node tuntas, kubelet akan memperbarui status Pod, dengan menetapkan fase Failed dan alasan Terminated untuk Pod yang dihentikan.

Jika jumlah Pod yang dihentikan mencapai batas 1000 untuk cluster dengan kurang dari 100 node atau 5000 untuk cluster dengan 100 node atau lebih, pembersihan sampah memori akan membersihkan Pod.

Anda juga dapat menghapus secara manual Pod yang dihentikan menggunakan perintah berikut:

  kubectl get pods --all-namespaces | grep -i NodeShutdown | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n
  kubectl get pods --all-namespaces | grep -i Terminated | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n

Perubahan pada perilaku Kubernetes

Penggunaan preemptible VM di GKE mengubah beberapa jaminan dan batasan yang diberikan Kubernetes, seperti berikut ini:

  • GKE memadamkan preemptible VM tanpa masa tenggang untuk Pod, 30 detik setelah menerima pemberitahuan preemption dari Compute Engine.

  • Reklamasi preemptible VM bersifat tidak sukarela dan tidak tercakup dalam jaminan PodDisruptionBudgets. Anda mungkin mengalami ketidaktersediaan yang lebih besar daripada PodDisruptionBudget yang dikonfigurasi.

Batasan

Membuat cluster atau node pool dengan preemptible VM

Anda dapat menggunakan Google Cloud CLI untuk membuat cluster atau node pool dengan preemptible VM.

Untuk membuat cluster dengan preemptible VM, jalankan perintah berikut:

gcloud container clusters create CLUSTER_NAME \
    --preemptible

Ganti CLUSTER_NAME dengan nama cluster baru Anda.

Untuk membuat node pool dengan preemptible VM, jalankan perintah berikut:

gcloud container node-pools create POOL_NAME \
    --cluster=CLUSTER_NAME \
    --preemptible

Ganti POOL_NAME dengan nama node pool baru Anda.

Menggunakan nodeSelector untuk menjadwalkan Pod di preemptible VM

GKE menambahkan label cloud.google.com/gke-preemptible=true dan cloud.google.com/gke-provisioning=preemptible (untuk node yang menjalankan GKE versi 1.25.5-gke.2500 atau yang lebih baru) ke node yang menggunakan preemptible VM. Anda dapat menggunakan nodeSelector di deployment Anda untuk memberi tahu GKE agar menjadwalkan Pod ke preemptible VM.

Sebagai contoh, filter Deployment berikut untuk preemptible VM menggunakan label cloud.google.com/gke-preemptible:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-app
  template:
    metadata:
      labels:
        app: hello-app
    spec:
      containers:
      - name: hello-app
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
        resources:
          requests:
            cpu: 200m
      nodeSelector:
        cloud.google.com/gke-preemptible: "true"

Menggunakan taint node untuk preemptible VM

Anda dapat melakukan taint pada node yang menggunakan preemptible VM sehingga GKE hanya dapat menempatkan Pod dengan toleransi yang sesuai pada node tersebut.

Untuk menambahkan taint node ke node pool yang menggunakan preemptible VM, gunakan tanda --node-taints saat membuat node pool, mirip dengan perintah berikut:

gcloud container node-pools create POOL2_NAME \
    --cluster=CLUSTER_NAME \
    --node-taints=cloud.google.com/gke-preemptible="true":NoSchedule

Sekarang, hanya Pod yang menoleransi taint node yang dijadwalkan ke node.

Untuk menambah toleransi yang relevan ke Pod Anda, ubah deployment dan tambahkan hal berikut ke spesifikasi Pod:

tolerations:
- key: cloud.google.com/gke-preemptible
  operator: Equal
  value: "true"
  effect: NoSchedule

Taint node untuk preemptible VM

Dukungan Preemptible VM menggunakan GPU. Anda harus membuat minimal satu node pool lain di cluster yang tidak menggunakan preemptible VM sebelum menambahkan node pool GPU yang menggunakan preemptible VM. Memiliki node pool standar memastikan bahwa GKE dapat menempatkan komponen sistem dengan aman seperti DNS.

Jika Anda membuat cluster baru dengan node pool GPU yang menggunakan preemptible VM, atau jika Anda menambahkan node pool GPU baru yang menggunakan preemptible VM ke cluster yang belum memiliki node pool standar, GKE tidak secara otomatis menambahkan taint nvidia.com/gpu=present:NoSchedule ke node. GKE mungkin menjadwalkan Pod sistem ke preemptible VM, yang dapat menyebabkan gangguan. Perilaku ini juga meningkatkan konsumsi resource Anda karena node GPU lebih mahal daripada node non-GPU.

Langkah berikutnya