Alokasi Sumber Daya Dinamis

FEATURE STATE: Kubernetes v1.32 [beta] (enabled by default: false)

Alokasi sumber daya dinamis (dynamic resource allocation) adalah API untuk meminta dan berbagi sumber daya antara Pod dan kontainer di dalam sebuah Pod. Ini merupakan generalisasi dari API PersistentVolume untuk sumber daya generik. Biasanya, sumber daya tersebut bisa berupa perangkat seperti GPU.

Driver sumber daya pihak ketiga bertanggung jawab untuk melacak dan mempersiapkan sumber daya, dengan alokasi sumber daya yang ditangani oleh Kubernetes melalui parameter terstruktur (diperkenalkan pada Kubernetes 1.30). Berbagai jenis sumber daya mendukung parameter sembarang untuk mendefinisikan kebutuhan dan inisialisasi.

Kubernetes versi 1.26 hingga 1.31 menyertakan implementasi (alpha) dari DRA (Dynamic Resource Allocation) klasik, yang sekarang sudah tidak didukung lagi. Dokumentasi ini yang ditujukan untuk Kubernetes versi 1.33, menjelaskan pendekatan terkini untuk alokasi sumber daya dinamis dalam Kubernetes.

Sebelum kamu memulai

Kubernetes versi 1.33 menyertakan dukungan API tingkat klaster untuk alokasi sumber daya dinamis, tetapi harus diaktifkan secara eksplisit. Kamu juga harus menginstal driver sumber daya untuk sumber daya tertentu yang akan dikelola menggunakan API ini. Jika kamu tidak menggunakan Kubernetes versi 1.33, periksa dokumentasi untuk versi Kubernetes tersebut.

API

resource.k8s.io/v1beta1 dan resource.k8s.io/v1beta2 API groups menyediakan tipe-tipe berikut:

ResourceClaim
Menggambarkan permintaan akses ke sumber daya di dalam klaster untuk digunakan oleh beban kerja (workload). Misalnya, jika sebuah beban kerja membutuhkan perangkat akselerator dengan properti tertentu, permintaan tersebut diekspresikan melalui tipe ini. Bagian status melacak apakah klaim ini telah terpenuhi dan sumber daya spesifik apa yang telah dialokasikan.
ResourceClaimTemplate
Mendefinisikan spesifikasi dan beberapa metadata untuk membuat ResourceClaim. Dibuat oleh pengguna saat menerapkan beban kerja. ResourceClaim untuk setiap Pod kemudian dibuat dan dihapus secara otomatis oleh Kubernetes.
DeviceClass
Berisi kriteria seleksi yang telah ditentukan untuk perangkat tertentu serta konfigurasi untuk perangkat tersebut. DeviceClass dibuat oleh administrator klaster saat menginstal driver sumber daya. Setiap permintaan untuk mengalokasikan perangkat dalam ResourceClaim harus merujuk tepat satu DeviceClass.
ResourceSlice
Digunakan oleh driver DRA untuk mempublikasikan informasi tentang sumber daya (biasanya perangkat) yang tersedia di klaster.
DeviceTaintRule
Digunakan oleh administrator atau komponen control plane untuk menambahkan taint perangkat pada perangkat yang dijelaskan dalam ResourceSlice.

Semua parameter yang memilih perangkat didefinisikan dalam ResourceClaim dan DeviceClass menggunakan tipe in-tree. Parameter konfigurasi dapat disematkan di sana. Parameter konfigurasi yang valid bergantung pada driver DRA -- Kubernetes hanya meneruskannya tanpa memprosesnya.

PodSpec dari core/v1 mendefinisikan ResourceClaim yang diperlukan untuk sebuah Pod dalam field resourceClaims. Entri dalam daftar tersebut merujuk pada ResourceClaim atau ResourceClaimTemplate. Ketika merujuk pada ResourceClaim, semua Pod yang menggunakan PodSpec ini (misalnya, di dalam Deployment atau StatefulSet) berbagi instance ResourceClaim yang sama. Ketika merujuk pada ResourceClaimTemplate, setiap Pod mendapatkan instance tersendiri.

Daftar resources.claims untuk sumber daya kontainer mendefinisikan apakah sebuah kontainer mendapatkan akses ke instance sumber daya tersebut, yang memungkinkan berbagi sumber daya antara satu atau lebih kontainer.

Berikut adalah contoh untuk driver sumber daya fiksi. Dua objek ResourceClaim akan dibuat untuk Pod ini, dan setiap kontainer mendapatkan akses ke salah satu dari mereka.

apiVersion: resource.k8s.io/v1beta2
kind: DeviceClass
metadata:
  name: resource.example.com
spec:
  selectors:
  - cel:
      expression: device.driver == "resource-driver.example.com"
---
apiVersion: resource.k8s.io/v1beta2
kind: ResourceClaimTemplate
metadata:
  name: large-black-cat-claim-template
spec:
  spec:
    devices:
      requests:
      - name: req-0
        exactly:
          deviceClassName: resource.example.com
          selectors:
          - cel:
             expression: |-
                device.attributes["resource-driver.example.com"].color == "black" &&
                device.attributes["resource-driver.example.com"].size == "large"                
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-cats
spec:
  kontainers:
  - name: kontainer0
    image: ubuntu:20.04
    command: ["sleep", "9999"]
    resources:
      claims:
      - name: cat-0
  - name: kontainer1
    image: ubuntu:20.04
    command: ["sleep", "9999"]
    resources:
      claims:
      - name: cat-1
  resourceClaims:
  - name: cat-0
    resourceClaimTemplateName: large-black-cat-claim-template
  - name: cat-1
    resourceClaimTemplateName: large-black-cat-claim-template

Penjadwalan (Scheduling)

Scheduler bertanggung jawab untuk mengalokasikan sumber daya ke ResourceClaim setiap kali sebuah Pod membutuhkannya. Scheduler melakukan ini dengan mengambil daftar lengkap sumber daya yang tersedia dari objek ResourceSlice, melacak sumber daya mana yang sudah dialokasikan ke ResourceClaim yang ada, dan kemudian memilih dari sumber daya yang masih tersisa.

Saat ini, satu-satunya jenis sumber daya yang didukung adalah perangkat. Sebuah instance perangkat memiliki nama, beberapa atribut, dan kapasitas. Perangkat dipilih melalui ekspresi CEL (Common Expression Language) yang memeriksa atribut dan kapasitas tersebut. Selain itu, perangkat yang dipilih juga dapat dibatasi pada kumpulan perangkat yang memenuhi batasan tertentu. Sumber daya yang dipilih dicatat dalam status ResourceClaim bersama dengan konfigurasi spesifik vendor, sehingga ketika sebuah pod akan dijalankan pada sebuah Node, driver sumber daya di Node tersebut memiliki semua informasi yang diperlukan untuk mempersiapkan sumber daya tersebut.

Dengan menggunakan parameter terstruktur, scheduler dapat mengambil keputusan tanpa berkomunikasi dengan driver sumber daya DRA. Scheduler juga dapat menjadwalkan beberapa Pod dengan cepat dengan menyimpan informasi tentang alokasi ResourceClaim di memori dan menuliskan informasi ini ke objek ResourceClaim di latar belakang sambil secara bersamaan mengikat pod ke sebuah Node.

Memantau Sumber Daya

Kubelet menyediakan layanan gRPC untuk memungkinkan penemuan sumber daya dinamis dari Pod yang sedang berjalan. Untuk informasi lebih lanjut tentang endpoint gRPC, lihat pelaporan alokasi sumber daya.

Pod yang Sudah Dijadwalkan Sebelumnya

Ketika kamu - atau klien API lainnya - membuat sebuah Pod dengan spec.nodeName yang sudah diatur, scheduler akan dilewati. Jika ada ResourceClaim yang dibutuhkan oleh Pod tersebut tetapi belum ada, belum dialokasikan, atau belum dipesan untuk Pod tersebut, maka kubelet akan gagal menjalankan Pod dan akan memeriksa ulang secara berkala karena persyaratan tersebut mungkin masih dapat dipenuhi di kemudian waktu.

Situasi semacam ini juga dapat terjadi ketika dukungan untuk alokasi sumber daya dinamis tidak diaktifkan di scheduler pada saat Pod dijadwalkan (karena perbedaan versi, konfigurasi, feature gate, dll.). kube-controller-manager mendeteksi hal ini dan mencoba membuat Pod dapat dijalankan dengan memesan ResourceClaim yang diperlukan. Namun, ini hanya berhasil jika ResourceClaim tersebut telah dialokasikan oleh scheduler untuk Pod lain.

Lebih baik untuk menghindari melewati scheduler karena Pod yang ditugaskan ke sebuah Node akan memblokir sumber daya normal (RAM, CPU) yang tidak dapat digunakan untuk Pod lain sementara Pod tersebut terhenti. Untuk membuat sebuah Pod berjalan di Node tertentu sambil tetap melalui alur penjadwalan normal, buatlah Pod dengan nodeSelector yang secara tepat cocok dengan Node yang diinginkan:

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-cats
spec:
  nodeSelector:
    kubernetes.io/hostname: name-of-the-intended-node
  ...

Kamu juga dapat memodifikasi Pod yang masuk, pada saat admission, untuk menghapus field .spec.nodeName dan menggunakan nodeSelector sebagai gantinya.

Akses Admin

FEATURE STATE: Kubernetes v1.32 [alpha] (enabled by default: false)

Kamu dapat menandai sebuah permintaan dalam ResourceClaim atau ResourceClaimTemplate sebagai memiliki fitur istimewa untuk tugas pemeliharaan dan pemecahan masalah. Permintaan dengan akses admin memberikan akses ke perangkat yang sedang digunakan dan mungkin mengaktifkan izin tambahan saat membuat perangkat tersedia di dalam sebuah kontainer:

apiVersion: resource.k8s.io/v1beta2
kind: ResourceClaimTemplate
metadata:
  name: large-black-cat-claim-template
spec:
  spec:
    devices:
      requests:
      - name: req-0
        exactly:
          deviceClassName: resource.example.com
          allocationMode: All
          adminAccess: true

Jika fitur ini dinonaktifkan, field adminAccess akan secara otomatis dihapus saat membuat ResourceClaim semacam itu.

Akses admin adalah mode istimewa dan tidak boleh diberikan kepada pengguna biasa dalam klaster multi-tenant. Mulai dari Kubernetes v1.33, hanya pengguna yang memiliki otorisasi untuk membuat objek ResourceClaim atau ResourceClaimTemplate di namespace yang diberi label resource.k8s.io/admin-access: "true" (case-sensitive) yang dapat menggunakan field adminAccess. Hal ini memastikan bahwa pengguna non-admin tidak dapat menyalahgunakan fitur tersebut.

Status Perangkat ResourceClaim

FEATURE STATE: Kubernetes v1.33 [beta] (enabled by default: true)

Driver dapat melaporkan data status perangkat spesifik driver untuk setiap perangkat yang dialokasikan dalam sebuah ResourceClaim. Misalnya, IP yang diberikan ke perangkat antarmuka jaringan dapat dilaporkan dalam status ResourceClaim.

Driver yang menetapkan status, keakuratan informasi bergantung pada implementasi driver DRA tersebut. Oleh karena itu, status perangkat yang dilaporkan mungkin tidak selalu mencerminkan perubahan waktu nyata dari keadaan perangkat.

Ketika fitur ini dinonaktifkan, field tersebut secara otomatis akan dihapus saat menyimpan ResourceClaim.

Status perangkat ResourceClaim didukung ketika memungkinkan, dari driver DRA, untuk memperbarui ResourceClaim yang ada di mana field status.devices diatur.

Daftar Prioritas

FEATURE STATE: Kubernetes v1.33 [alpha] (enabled by default: false)

Kamu dapat menyediakan daftar prioritas sub-permintaan untuk permintaan dalam sebuah ResourceClaim. Scheduler kemudian akan memilih sub-permintaan pertama yang dapat dialokasikan. Ini memungkinkan pengguna untuk menentukan perangkat alternatif yang dapat digunakan oleh beban kerja jika pilihan utama tidak tersedia.

Dalam contoh di bawah ini, ResourceClaimTemplate meminta perangkat dengan warna hitam dan ukuran besar. Jika perangkat dengan atribut tersebut tidak tersedia, Pod tidak dapat dijadwalkan. Dengan fitur daftar prioritas, alternatif kedua dapat ditentukan, yang meminta dua perangkat dengan warna putih dan ukuran kecil. Perangkat hitam besar akan dialokasikan jika tersedia. Namun, jika tidak tersedia dan dua perangkat putih kecil tersedia, Pod masih dapat berjalan.

apiVersion: resource.k8s.io/v1beta2
kind: ResourceClaimTemplate
metadata:
  name: prioritized-list-claim-template
spec:
  spec:
    devices:
      requests:
      - name: req-0
        firstAvailable:
        - name: large-black
          deviceClassName: resource.example.com
          selectors:
          - cel:
              expression: |-
                device.attributes["resource-driver.example.com"].color == "black" &&
                device.attributes["resource-driver.example.com"].size == "large"                
        - name: small-white
          deviceClassName: resource.example.com
          selectors:
          - cel:
              expression: |-
                device.attributes["resource-driver.example.com"].color == "white" &&
                device.attributes["resource-driver.example.com"].size == "small"                
          count: 2

Perangkat yang Dapat Dipartisi

FEATURE STATE: Kubernetes v1.33 [alpha] (enabled by default: false)

Perangkat yang direpresentasikan dalam DRA tidak harus berupa satu unit yang terhubung ke satu mesin, tetapi juga dapat berupa perangkat logis yang terdiri dari beberapa perangkat yang terhubung ke beberapa mesin. Perangkat-perangkat ini mungkin menggunakan sumber daya yang saling tumpang tindih dari perangkat fisik yang mendasarinya, yang berarti bahwa ketika satu perangkat logis dialokasikan, perangkat lainnya tidak akan lagi tersedia.

Dalam API ResourceSlice, ini direpresentasikan sebagai daftar CounterSet yang diberi nama, masing-masing berisi satu set counter yang juga diberi nama. Counter ini merepresentasikan sumber daya yang tersedia pada perangkat fisik yang digunakan oleh perangkat logis yang diiklankan melalui DRA.

Perangkat logis dapat menentukan daftar ConsumesCounters. Setiap entri berisi referensi ke sebuah CounterSet dan satu set counter yang diberi nama dengan jumlah yang akan mereka konsumsi. Jadi, agar sebuah perangkat dapat dialokasikan, set counter yang direferensikan harus memiliki jumlah yang cukup untuk counter yang direferensikan oleh perangkat tersebut.

Berikut adalah contoh dua perangkat, masing-masing mengonsumsi 6Gi memori dari sebuah counter bersama yang memiliki 8Gi memori. Dengan demikian, hanya satu dari perangkat tersebut yang dapat dialokasikan pada satu waktu. Scheduler menangani ini, dan hal ini transparan bagi konsumen karena API ResourceClaim tidak terpengaruh.

kind: ResourceSlice
apiVersion: resource.k8s.io/v1beta2
metadata:
  name: resourceslice
spec:
  nodeName: worker-1
  pool:
    name: pool
    generation: 1
    resourceSliceCount: 1
  driver: dra.example.com
  sharedCounters:
  - name: gpu-1-counters
    counters:
      memory:
        value: 8Gi
  devices:
  - name: device-1
    consumesCounters:
    - counterSet: gpu-1-counters
      counters:
        memory:
          value: 6Gi
  - name: device-2
    consumesCounters:
    - counterSet: gpu-1-counters
      counters:
        memory:
          value: 6Gi

Taint dan Toleransi Perangkat

FEATURE STATE: Kubernetes v1.32 [beta] (enabled by default: false)

Taint perangkat mirip dengan taint pada Node: sebuah taint memiliki kunci string, nilai string, dan efek. Efek ini diterapkan pada ResourceClaim yang menggunakan perangkat yang telah ditaint dan pada semua Pod yang merujuk ke ResourceClaim tersebut. Efek "NoSchedule" mencegah penjadwalan Pod-Pod tersebut. Perangkat yang ditaint akan diabaikan saat mencoba mengalokasikan ResourceClaim karena penggunaannya akan mencegah penjadwalan Pod.

Efek "NoExecute" menyiratkan "NoSchedule" dan, selain itu, menyebabkan pengusiran semua Pod yang telah dijadwalkan sebelumnya. Pengusiran ini diimplementasikan dalam pengontrol pengusiran taint perangkat di kube-controller-manager dengan cara menghapus Pod yang terpengaruh.

ResourceClaim dapat mentoleransi taint. Jika sebuah taint ditoleransi, efeknya tidak berlaku. Toleransi kosong cocok dengan semua taint. Toleransi dapat dibatasi pada efek tertentu dan/atau cocok dengan pasangan kunci/nilai tertentu. Toleransi dapat memeriksa keberadaan kunci tertentu, terlepas dari nilai apa yang dimilikinya, atau dapat memeriksa nilai spesifik dari sebuah kunci. Untuk informasi lebih lanjut tentang pencocokan ini, lihat konsep taint pada Node.

Pengusiran dapat ditunda dengan mentoleransi taint untuk durasi tertentu. Penundaan tersebut dimulai saat taint ditambahkan ke perangkat, yang dicatat dalam sebuah field pada taint.

Taint berlaku seperti yang dijelaskan di atas juga untuk ResourceClaim yang mengalokasikan "semua" perangkat pada sebuah Node. Semua perangkat harus tidak ditaint atau semua taint mereka harus ditoleransi. Mengalokasikan perangkat dengan akses admin (dijelaskan di atas) juga tidak dikecualikan. Seorang admin yang menggunakan mode tersebut harus secara eksplisit mentoleransi semua taint untuk mengakses perangkat yang ditaint.

Taint dapat ditambahkan ke perangkat dengan dua cara berbeda:

Taint yang Ditetapkan oleh Driver

Driver DRA dapat menambahkan taint ke informasi perangkat yang dipublikasikan dalam ResourceSlice. Konsultasikan dokumentasi driver DRA untuk mengetahui apakah driver menggunakan taint dan apa kunci serta nilainya.

Taint yang Ditetapkan oleh Admin

Seorang admin atau komponen control plane dapat menaint perangkat tanpa harus meminta driver DRA untuk menyertakan taint dalam informasi perangkatnya di ResourceSlice. Mereka melakukannya dengan membuat DeviceTaintRules. Setiap DeviceTaintRule menambahkan satu taint ke perangkat yang cocok dengan selector perangkat. Tanpa selector semacam itu, tidak ada perangkat yang ditaint. Hal ini membuat lebih sulit untuk secara tidak sengaja mengusir semua Pod yang menggunakan ResourceClaim karena kesalahan dalam menentukan selector.

Perangkat dapat dipilih dengan memberikan nama DeviceClass, driver, pool, dan/atau perangkat. DeviceClass memilih semua perangkat yang dipilih oleh selector dalam DeviceClass tersebut. Dengan hanya nama driver, seorang admin dapat melakukan taint semua perangkat yang dikelola oleh driver tersebut, misalnya saat melakukan pemeliharaan driver di seluruh klaster. Menambahkan nama pool dapat membatasi taint ke satu Node, jika driver mengelola perangkat lokal Node.

Terakhir, menambahkan nama perangkat dapat memilih satu perangkat spesifik. Nama perangkat dan nama pool juga dapat digunakan sendiri, jika diinginkan. Misalnya, driver untuk perangkat lokal Node didorong untuk menggunakan nama Node sebagai nama pool mereka. Maka, melakukan taint dengan nama pool tersebut secara otomatis melakukan taint semua perangkat pada sebuah Node.

Driver mungkin menggunakan nama stabil seperti "gpu-0" yang menyembunyikan perangkat spesifik mana yang saat ini ditugaskan ke nama tersebut. Untuk mendukung perlakuan taint ubstabs perangkat keras tertentu, selector CEL dapat digunakan dalam DeviceTaintRule untuk mencocokkan atribut ID unik spesifik vendor, jika driver mendukungnya untuk perangkat kerasnya.

Taint berlaku selama DeviceTaintRule ada. taint dapat dimodifikasi dan dihapus kapan saja. Berikut adalah contoh DeviceTaintRule untuk driver DRA fiksi:

apiVersion: resource.k8s.io/v1alpha3
kind: DeviceTaintRule
metadata:
  name: example
spec:
  # The entire hardware installation for this
  # particular driver is broken.
  # Evict all pods and don't schedule new ones.
  deviceSelector:
    driver: dra.example.com
  _taint_:
    key: dra.example.com/unhealthy
    value: Broken
    effect: NoExecute

Mengaktifkan Alokasi Sumber Daya Dinamis

Alokasi sumber daya dinamis adalah fitur beta yang secara default tidak diaktifkan dan hanya dapat diaktifkan jika feature gate DynamicResourceAllocation serta API groups resource.k8s.io/v1beta1 dan resource.k8s.io/v1beta2 diaktifkan. Untuk detail lebih lanjut, lihat parameter --feature-gates dan --runtime-config pada kube-apiserver. Selain itu, kube-scheduler, kube-controller-manager, dan kubelet juga memerlukan feature gate ini.

Ketika driver sumber daya melaporkan status perangkat, maka feature gate DRAResourceClaimDeviceStatus harus diaktifkan selain DynamicResourceAllocation. Cara cepat untuk memeriksa apakah klaster Kubernetes mendukung fitur ini adalah dengan daftar objek DeviceClass menggunakan perintah berikut:

kubectl get deviceclasses

Jika klaster kamu mendukung alokasi sumber daya dinamis, respon-nya adalah daftar objek DeviceClass atau:

No resources found

Jika tidak didukung, kesalahan berikut akan dicetak:

error: the server doesn't have a resource type "deviceclasses"

Konfigurasi default kube-scheduler mengaktifkan plugin "DynamicResources" hanya jika feature gate diaktifkan dan menggunakan API konfigurasi v1. Konfigurasi kustom mungkin perlu dimodifikasi untuk menyertakannya.

Selain mengaktifkan fitur di klaster, driver sumber daya juga harus diinstal. Silakan merujuk ke dokumentasi driver untuk detail lebih lanjut.

Mengaktifkan Akses Admin

Akses Admin adalah fitur alpha dan hanya dapat diaktifkan jika feature gate DRAAdminAccess diaktifkan di kube-apiserver dan kube-scheduler.

Mengaktifkan Status Perangkat

Status perangkat ResourceClaim adalah fitur alpha dan hanya dapat diaktifkan jika feature gate DRAResourceClaimDeviceStatus diaktifkan di kube-apiserver.

Mengaktifkan Daftar Prioritas

Daftar prioritas adalah fitur alpha dan hanya dapat diaktifkan jika feature gate DRAPrioritizedList diaktifkan di kube-apiserver dan kube-scheduler. Fitur ini juga memerlukan feature gate DynamicResourceAllocation diaktifkan.

Mengaktifkan Perangkat yang Dapat Dipartisi

Perangkat yang dapat dipartisi adalah fitur alpha dan hanya dapat diaktifkan jika feature gate DRAPartitionableDevices diaktifkan di kube-apiserver dan kube-scheduler.

Mengaktifkan Taint dan Toleransi Perangkat

Taint dan toleransi perangkat adalah fitur alpha dan hanya dapat diaktifkan jika feature gate DRADevice_Taint_s diaktifkan di kube-apiserver, kube-controller-manager, dan kube-scheduler. Untuk menggunakan DeviceTaintRules, versi API resource.k8s.io/v1alpha3 harus diaktifkan.

Selanjutnya