Plugin Perangkat

Gunakan kerangka kerja plugin perangkat Kubernetes untuk mengimplementasikan plugin untuk GPU, NIC, FPGA, InfiniBand, dan sumber daya sejenis yang membutuhkan setelan spesifik vendor.
FEATURE STATE: Kubernetes v1.26 [stable]

Kubernetes menyediakan kerangka kerja plugin perangkat sehingga kamu dapat memakainya untuk memperlihatkan sumber daya perangkat keras sistem ke dalam Kubelet.

Daripada menkustomisasi kode Kubernetes itu sendiri, vendor dapat mengimplementasikan plugin perangkat yang di-deploy secara manual atau sebagai DaemonSet. Perangkat yang dituju termasuk GPU, NIC berkinerja tinggi, FPGA, adaptor InfiniBand, dan sumber daya komputasi sejenis lainnya yang perlu inisialisasi dan setelan spesifik vendor.

Pendaftaran plugin perangkat

Kubelet mengekspor servis gRPC Registration:

service Registration {
	rpc Register(RegisterRequest) returns (Empty) {}
}

Plugin perangkat bisa mendaftarkan dirinya sendiri dengan kubelet melalui servis gRPC. Dalam pendaftaran, plugin perangkat perlu mengirim:

  • Nama Unix socket-nya.
  • Versi API Plugin Perangkat yang dipakai.
  • ResourceName yang ingin ditunjukkan. ResourceName ini harus mengikuti skema penamaan sumber daya ekstensi sebagai vendor-domain/tipe-sumber-daya. (Contohnya, NVIDIA GPU akan dinamai nvidia.com/gpu.)

Setelah registrasi sukses, plugin perangkat mengirim daftar perangkat yang diatur ke kubelet, lalu kubelet kemudian bertanggung jawab untuk mengumumkan sumber daya tersebut ke peladen API sebagai bagian pembaruan status node kubelet. Contohnya, setelah plugin perangkat mendaftarkan hardware-vendor.example/foo dengan kubelet dan melaporkan kedua perangkat dalam node dalam kondisi sehat, status node diperbarui untuk menunjukkan bahwa node punya 2 perangkat “Foo” terpasang dan tersedia.

Kemudian, pengguna dapat meminta perangkat dalam spesifikasi Kontainer seperti meminta tipe sumber daya lain, dengan batasan berikut:

  • Sumber daya ekstensi hanya didukung sebagai sumber daya integer dan tidak bisa overcommitted.
  • Perangkat tidak bisa dibagikan antar Kontainer.

Semisal klaster Kubernetes menjalankan plugin perangkat yang menunjukkan sumber daya hardware-vendor.example/foo pada node tertentu. Berikut contoh Pod yang meminta sumber daya itu untuk menjalankan demo beban kerja:

---
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  containers:
    - name: demo-container-1
      image: registry.k8s.io/pause:3.8
      resources:
        limits:
          hardware-vendor.example/foo: 2
#
# Pod ini perlu 2 perangkat perangkat-vendor.example/foo
# dan hanya dapat menjadwalkan ke Node yang bisa memenuhi
# kebutuhannya.
#
# Jika Node punya lebih dari 2 perangkat tersedia,
# maka kelebihan akan dapat digunakan Pod lainnya.

Implementasi plugin perangkat

Alur kerja umum dari plugin perangkat adalah sebagai berikut:

  • Inisiasi. Selama fase ini, plugin perangkat melakukan inisiasi spesifik vendor dan pengaturan untuk memastikan perangkat pada status siap.

  • Plugin memulai servis gRPC, dengan Unix socket pada lokasi /var/lib/kubelet/device-plugins/, yang mengimplementasi antarmuka berikut:

    service DevicePlugin {
          // GetDevicePluginOptions mengembalikan opsi yang akan dikomunikasikan dengan Device Manager.
          rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {}
    
         // ListAndWatch mengembalikan aliran dari List of Devices
         // Kapanpun Device menyatakan perubahan atau kehilangan Device, ListAndWatch
         // mengembalikan daftar baru
          rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
    
         // Allocate dipanggil saat pembuatan kontainer sehingga Device
         // Plugin dapat menjalankan operasi spesifik perangkat dan menyuruh Kubelet
         // dari operasi untuk membuat Device tersedia di kontainer
          rpc Allocate(AllocateRequest) returns (AllocateResponse) {}
    
          // GetPreferredAllocation mengembalikan sekumpulan perangkat yang disukai untuk dialokasikan
          // dari daftar yang tersedia. Alokasi yang dihasilkan tidak
          // dijamin sebagai alokasi yang pada akhirnya dilakukan oleh
          // devicemanager. Ini dirancang hanya untuk membantu devicemanager membuat
          // keputusan alokasi yang lebih tepat ketika memungkinkan.
          rpc GetPreferredAllocation(PreferredAllocationRequest) returns (PreferredAllocationResponse) {}
    
          // PreStartContainer dipanggil, jika ditunjukkan oleh Plugin Perangkat selama fase pendaftaran,
          // sebelum setiap awal kontainer. Plugin perangkat dapat menjalankan operasi spesifik perangkat
          // seperti mereset perangkat sebelum membuat perangkat tersedia bagi kontainer.
          rpc PreStartContainer(PreStartContainerRequest) returns (PreStartContainerResponse) {}
    }
    
  • Plugin mendaftarkan dirinya sendiri dengan kubelet melalui Unix socket pada lokasi host /var/lib/kubelet/device-plugins/kubelet.sock.

  • Seteleh sukses mendaftarkan dirinya sendiri, plugin perangkat berjalan dalam mode peladen, dan selama itu dia tetap mengawasi kesehatan perangkat dan melaporkan balik ke kubelet terhadap perubahan status perangkat. Dia juga bertanggung jawab untuk melayani request gRPC Allocate. Selama Allocate, plugin perangkat dapat membuat persiapan spesifik-perangkat; contohnya, pembersihan GPU atau inisiasi QRNG. Jika operasi berhasil, plugin perangkat mengembalikan AllocateResponse yang memuat konfigurasi runtime kontainer untuk mengakses perangkat teralokasi. Kubelet memberikan informasi ini ke runtime kontainer.

AllocateResponse berisi nol atau lebih objek ContainerAllocateResponse. Di dalam objek-objek ini, plugin perangkat mendefinisikan modifikasi yang harus dilakukan pada definisi kontainer untuk memberikan akses ke perangkat. Modifikasi ini meliputi:

  • Anotasi
  • node perangkat
  • variabel lingkungan
  • pemasangan (mounts)
  • nama perangkat CDI yang sepenuhnya terqualifikasi

Menangani kubelet yang restart

Plugin perangkat diharapkan dapat mendeteksi kubelet yang restart dan mendaftarkan dirinya sendiri kembali dengan instance kubelet baru. Pada implementasi sekarang, sebuah instance kubelet baru akan menghapus semua socket Unix yang ada di dalam /var/lib/kubelet/device-plugins ketika dijalankan. Plugin perangkat dapat mengawasi penghapusan socket Unix miliknya dan mendaftarkan dirinya sendiri kembali ketika hal tersebut terjadi.

Plugin perangkat dan perangkat yang tidak sehat

Ada kalanya perangkat mengalami kegagalan atau dimatikan. Tanggung jawab Plugin Perangkat dalam kasus ini adalah memberi tahu kubelet mengenai situasi tersebut menggunakan API ListAndWatchResponse.

Setelah sebuah perangkat ditandai sebagai tidak sehat, kubelet akan mengurangi jumlah yang dapat dialokasikan untuk sumber daya ini di Node, untuk mencerminkan berapa banyak perangkat yang dapat digunakan untuk menjadwalkan pod baru. Jumlah kapasitas untuk sumber daya tersebut tidak akan berubah.

Pod yang telah ditugaskan ke perangkat yang gagal akan terus diasosiasikan dengan perangkat ini. Umumnya, kode yang bergantung pada perangkat akan mulai gagal, dan Pod mungkin akan masuk ke fase Gagal jika restartPolicy untuk Pod tersebut tidak diatur ke Always, atau bisa juga masuk ke loop crash.

Sebelum Kubernetes v1.31, cara untuk mengetahui apakah sebuah Pod terkait dengan perangkat yang gagal adalah dengan menggunakan API PodResources.

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

Dengan mengaktifkan feature gate ResourceHealthStatus, field allocatedResourcesStatus akan ditambahkan ke setiap status kontainer, dalam .status untuk setiap Pod. Field allocatedResourcesStatus melaporkan informasi kesehatan untuk setiap perangkat yang ditugaskan kepada kontainer.

Untuk Pod yang gagal, atau di mana Anda mencurigai adanya kesalahan, Anda dapat menggunakan status ini untuk memahami apakah perilaku Pod mungkin terkait dengan kegagalan perangkat. Misalnya, jika sebuah akselerator melaporkan kejadian suhu berlebih, field allocatedResourcesStatus mungkin dapat melaporkan hal ini.

Deployment plugin perangkat

Kamu dapat melakukan deploy sebuah plugin perangkat sebagai DaemonSet, sebagai sebuah paket untuk sistem operasi node-mu, atau secara manual.

Direktori canonical /var/lib/kubelet/device-plugins membutuhkan akses berprivilese, sehingga plugin perangkat harus berjalan dalam konteks keamanan dengan privilese. Jika kamu melakukan deploy plugin perangkat sebagai DaemonSet, /var/lib/kubelet/device-plugins harus dimuat sebagai Volume pada PodSpec plugin.

Jika kamu memilih pendekatan DaemonSet, kamu dapat bergantung pada Kubernetes untuk meletakkan Pod plugin perangkat ke Node, memulai-ulang Pod daemon setelah kegagalan, dan membantu otomasi pembaruan.

Kecocokan API

Sebelumnya, skema pengversian mengharuskan versi API Plugin Perangkat untuk cocok persis dengan versi kubelet. Sejak lulusnya fitur ini ke tahap Beta di v1.12, ini bukan lagi persyaratan yang ketat. API telah terversi dan tetap stabil sejak lulusnya fitur ini ke tahap Beta. Karena itu, peningkatan kubelet seharusnya berjalan lancar, tetapi masih mungkin ada perubahan dalam API sebelum stabilisasi, yang membuat upgrade tidak dijamin tidak akan mengganggu.

Sebagai proyek, Kubernetes merekomendasikan para developer plugin perangkat:

  • Mengamati perubahan pada rilis mendatang.
  • Mendukung versi API plugin perangkat berbeda untuk kompatibilitas-maju/mundur.

Jika kamu menyalakan fitur DevicePlugins dan menjalankan plugin perangkat pada node yang perlu diperbarui ke rilis Kubernetes dengan versi API plugin yang lebih baru, perbarui plugin perangkatmu agar mendukung kedua versi sebelum membarui para node ini. Memilih pendekatan demikian akan menjamin fungsi berkelanjutan dari alokasi perangkat selama pembaruan.

Mengawasi Sumber Daya Plugin Perangkat

FEATURE STATE: Kubernetes v1.28 [stable]

Dalam rangka mengawasi sumber daya yang disediakan plugin perangkat, agen monitoring perlu bisa menemukan kumpulan perangkat yang terpakai dalam node dan mengambil metadata untuk mendeskripsikan pada kontainer mana metrik harus diasosiasikan. Metrik prometheus diekspos oleh agen pengawas perangkat harus mengikuti Petunjuk Instrumentasi Kubernetes, mengidentifikasi kontainer dengan label prometheus pod, namespace, dan container.

kubelet menyediakan servis gRPC untuk menyalakan pencarian perangkat yang terpakai, dan untuk menyediakan metadata untuk perangkat berikut:

// PodResourcesLister adalah layanan yang disediakan kubelet untuk menyediakan informasi tentang
// sumber daya node yang dikonsumsi Pod dan kontainer pada node
service PodResourcesLister {
    rpc List(ListPodResourcesRequest) returns (ListPodResourcesResponse) {}
    rpc GetAllocatableResources(AllocatableResourcesRequest) returns (AllocatableResourcesResponse) {}
    rpc Get(GetPodResourcesRequest) returns (GetPodResourcesResponse) {}
}

Endpoint gRPC List

Endpoint List menyediakan informasi tentang sumber daya dari pod yang sedang berjalan, dengan rincian seperti ID CPU yang dialokasikan secara eksklusif, ID perangkat sebagaimana dilaporkan oleh plugin perangkat, dan ID dari node NUMA di mana perangkat ini dialokasikan. Selain itu, untuk mesin berbasis NUMA, endpoint ini juga mencakup informasi tentang memori dan hugepages yang diperuntukkan bagi sebuah kontainer.

Mulai dari Kubernetes v1.27, endpoint List dapat memberikan informasi tentang sumber daya dari pod yang sedang berjalan yang dialokasikan dalam ResourceClaims melalui API DynamicResourceAllocation. Untuk mengaktifkan fitur ini, kubelet harus dimulai dengan flag berikut:

--feature-gates=DynamicResourceAllocation=true,KubeletPodResourcesDynamicResources=true
// ListPodResourcesResponse adalah respons yang dikembalikan oleh fungsi List
message ListPodResourcesResponse {
    repeated PodResources pod_resources = 1;
}

// PodResources berisi informasi tentang sumber daya node yang dialokasikan untuk sebuah pod
message PodResources {
    string name = 1;
    string namespace = 2;
    repeated ContainerResources containers = 3;
}

// ContainerResources berisi informasi tentang sumber daya yang dialokasikan untuk sebuah kontainer
message ContainerResources {
    string name = 1;
    repeated ContainerDevices devices = 2;
    repeated int64 cpu_ids = 3;
    repeated ContainerMemory memory = 4;
    repeated DynamicResource dynamic_resources = 5;
}

// ContainerMemory berisi informasi tentang memori dan hugepages yang dialokasikan untuk sebuah kontainer
message ContainerMemory {
    string memory_type = 1;
    uint64 size = 2;
    TopologyInfo topology = 3;
}

// Topology menjelaskan topologi perangkat keras dari sumber daya
message TopologyInfo {
        repeated NUMANode nodes = 1;
}

// Representasi NUMA dari node NUMA
message NUMANode {
        int64 ID = 1;
}

// ContainerDevices berisi informasi tentang perangkat yang dialokasikan untuk sebuah kontainer
message ContainerDevices {
    string resource_name = 1;
    repeated string device_ids = 2;
    TopologyInfo topology = 3;
}

// DynamicResource berisi informasi tentang perangkat yang dialokasikan untuk sebuah kontainer oleh Alokasi Sumber Daya Dinamis
message DynamicResource {
    string class_name = 1;
    string claim_name = 2;
    string claim_namespace = 3;
    repeated ClaimResource claim_resources = 4;
}

// ClaimResource berisi informasi sumber daya per-plugin
message ClaimResource {
    repeated CDIDevice cdi_devices = 1 [(gogoproto.customname) = "CDIDevices"];
}

// CDIDevice mengspesifikasikan informasi perangkat CDI
message CDIDevice {
    // Nama perangkat CDI yang sepenuhnya terqualifikasi
    // misalnya: vendor.com/gpu=gpudevice1
    // lihat detail lebih lanjut dalam spesifikasi CDI:
    // https://github.com/container-orchestrated-devices/container-device-interface/blob/main/SPEC.md
    string name = 1;
}

Endpoint gRPC GetAllocatableResources

FEATURE STATE: Kubernetes v1.28 [stable]

GetAllocatableResources menyediakan informasi tentang sumber daya yang awalnya tersedia pada node pekerja. Ini memberikan informasi lebih banyak daripada yang diekspor kubelet ke APIServer.

// AllocatableResourcesResponses berisi informasi tentang semua perangkat yang diketahui oleh kubelet
message AllocatableResourcesResponse {
    repeated ContainerDevices devices = 1;
    repeated int64 cpu_ids = 2;
    repeated ContainerMemory memory = 3;
}

ContainerDevices memang mengungkapkan informasi topologi yang menyatakan ke sel NUMA mana perangkat tersebut terasosiasi. Sel NUMA diidentifikasi menggunakan ID integer yang tidak jelas, yang nilainya konsisten dengan apa yang dilaporkan oleh plugin perangkat ketika mereka mendaftar ke kubelet.

Servis gRPC dilayani lewat socket unix pada /var/lib/kubelet/pod-resources/kubelet.sock. Agen pengawas untuk sumber daya plugin perangkat dapat di-deploy sebagai daemon, atau sebagai DaemonSet. Direktori canonical /var/lib/kubelet/pod-resources perlu akses berprivilese, sehingga agen pengawas harus berjalan dalam konteks keamanan dengan privilese. Jika agen pengawas perangkat berjalan sebagai DaemonSet, /var/lib/kubelet/pod-resources harus dimuat sebagai Volume pada plugin PodSpec.

Endpoint gRPC Get

FEATURE STATE: Kubernetes v1.27 [alpha]

Endpoint Get menyediakan informasi tentang sumber daya dari Pod yang sedang berjalan. Ini mengekspos informasi yang mirip dengan yang dijelaskan pada endpoint List. Endpoint Get memerlukan PodName dan PodNamespace dari Pod yang sedang berjalan.

// GetPodResourcesRequest berisi informasi tentang pod
message GetPodResourcesRequest {
    string pod_name = 1;
    string pod_namespace = 2;
}

Untuk mengaktifkan fitur ini, Anda harus memulai layanan kubelet Anda dengan flag berikut:

--feature-gates=KubeletPodResourcesGet=true

Endpoint Get dapat memberikan informasi Pod yang berkaitan dengan sumber daya dinamis yang dialokasikan oleh API alokasi sumber daya dinamis. Untuk mengaktifkan fitur ini, Anda harus memastikan layanan kubelet Anda dimulai dengan flag berikut:

--feature-gates=KubeletPodResourcesGet=true,DynamicResourceAllocation=true,KubeletPodResourcesDynamicResources=true

Integrasi Plugin Perangkat dengan Topology Manager

FEATURE STATE: Kubernetes v1.27 [stable]

Topology Manager adalah komponen Kubelet yang membolehkan sumber daya untuk dikoordinasi secara selaras dengan Topology. Untuk melakukannya, API Plugin Perangkat telah dikembangkan untuk memasukkan struct TopologyInfo.

message TopologyInfo {
    repeated NUMANode nodes = 1;
}

message NUMANode {
    int64 ID = 1;
}

Plugin Perangkat yang ingin memanfaatkan Topology Manager dapat mengembalikan beberapa struct TopologyInfo sebagai bagian dari pendaftaran perangkat, bersama dengan ID perangkat dan status kesehatan perangkat. Manajer perangkat akan memakai informasi ini untuk konsultasi dengan Topology Manager dan membuat keputusan alokasi sumber daya.

TopologyInfo mendukung kolom nodes yang bisa nil (sebagai bawaan) atau daftar node NUMA. Ini membuat Plugin Perangkat mengumumkan apa saja yang bisa meliputi node NUMA.

Menetapkan TopologyInfo ke nil atau menyediakan daftar sel NUMA yang kosong untuk perangkat tertentu menunjukkan bahwa Plugin Perangkat tidak memiliki preferensi afinitas NUMA untuk perangkat tersebut.

Contoh struct TopologyInfo untuk perangkat yang dipopulate oleh Plugin Perangkat:

pluginapi.Device{ID: "25102017", Health: pluginapi.Healthy, Topology:&pluginapi.TopologyInfo{Nodes: []*pluginapi.NUMANode{&pluginapi.NUMANode{ID: 0,},}}}

Contoh plugin perangkat

Berikut beberapa contoh implementasi plugin perangkat:

Selanjutnya

Items on this page refer to third party products or projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for those third-party products or projects. See the CNCF website guidelines for more details.

You should read the content guide before proposing a change that adds an extra third-party link.

Last modified December 26, 2024 at 4:18 PM PST: [id] Add text to: compute-storage-net/device-plugins.md (7f46b51605)