新聞中心
設(shè)備插件
FEATURE STATE: Kubernetes v1.10 [beta]

為昆玉等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計制作服務(wù),及昆玉網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都做網(wǎng)站、成都網(wǎng)站設(shè)計、昆玉網(wǎng)站設(shè)計,以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!
Kubernetes 提供了一個 設(shè)備插件框架,你可以用它來將系統(tǒng)硬件資源發(fā)布到 Kubelet。
供應(yīng)商可以實現(xiàn)設(shè)備插件,由你手動部署或作為 DaemonSet 來部署,而不必定制 Kubernetes 本身的代碼。目標設(shè)備包括 GPU、高性能 NIC、FPGA、 InfiniBand 適配器以及其他類似的、可能需要特定于供應(yīng)商的初始化和設(shè)置的計算資源。
注冊設(shè)備插件
?kubelet ?提供了一個 ?Registration ?的 gRPC 服務(wù):
service Registration {
rpc Register(RegisterRequest) returns (Empty) {}
}設(shè)備插件可以通過此 gRPC 服務(wù)在 kubelet 進行注冊。在注冊期間,設(shè)備插件需要發(fā)送下面幾樣內(nèi)容:
- 設(shè)備插件的 Unix 套接字。
- 設(shè)備插件的 API 版本。
- ?
ResourceName?是需要公布的。這里 ?ResourceName?需要遵循 擴展資源命名方案, 類似于 ?vendor-domain/resourcetype?。(比如 NVIDIA GPU 就被公布為 ?nvidia.com/gpu?。)
成功注冊后,設(shè)備插件就向 kubelet 發(fā)送它所管理的設(shè)備列表,然后 kubelet 負責(zé)將這些資源發(fā)布到 API 服務(wù)器,作為 kubelet 節(jié)點狀態(tài)更新的一部分。
比如,設(shè)備插件在 kubelet 中注冊了 ?hardware-vendor.example/foo? 并報告了 節(jié)點上的兩個運行狀況良好的設(shè)備后,節(jié)點狀態(tài)將更新以通告該節(jié)點已安裝 2 個 "Foo" 設(shè)備并且是可用的。
然后,用戶可以請求設(shè)備作為 Pod 規(guī)范的一部分。請求擴展資源類似于管理請求和限制的方式, 其他資源,有以下區(qū)別:
- 擴展資源僅可作為整數(shù)資源使用,并且不能被過量使用
- 設(shè)備不能在容器之間共享
示例
假設(shè) Kubernetes 集群正在運行一個設(shè)備插件,該插件在一些節(jié)點上公布的資源為 ?hardware-vendor.example/foo?。 下面就是一個 Pod 示例,請求此資源以運行一個工作負載的示例:
---
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
spec:
containers:
- name: demo-container-1
image: K8S.gcr.io/pause:2.0
resources:
limits:
hardware-vendor.example/foo: 2
#
# 這個 pod 需要兩個 hardware-vendor.example/foo 設(shè)備
# 而且只能夠調(diào)度到滿足需求的節(jié)點上
#
# 如果該節(jié)點中有 2 個以上的設(shè)備可用,其余的可供其他 Pod 使用設(shè)備插件的實現(xiàn)
設(shè)備插件的常規(guī)工作流程包括以下幾個步驟:
- 初始化。在這個階段,設(shè)備插件將執(zhí)行供應(yīng)商特定的初始化和設(shè)置, 以確保設(shè)備處于就緒狀態(tài)。
- 插件使用主機路徑 ?
/var/lib/kubelet/device-plugins/? 下的 Unix 套接字啟動 一個 gRPC 服務(wù),該服務(wù)實現(xiàn)以下接口:
service DevicePlugin {
// GetDevicePluginOptions 返回與設(shè)備管理器溝通的選項。
rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {}
// ListAndWatch 返回 Device 列表構(gòu)成的數(shù)據(jù)流。
// 當(dāng) Device 狀態(tài)發(fā)生變化或者 Device 消失時,ListAndWatch
// 會返回新的列表。
rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
// Allocate 在容器創(chuàng)建期間調(diào)用,這樣設(shè)備插件可以運行一些特定于設(shè)備的操作,
// 并告訴 kubelet 如何令 Device 可在容器中訪問的所需執(zhí)行的具體步驟
rpc Allocate(AllocateRequest) returns (AllocateResponse) {}
// GetPreferredAllocation 從一組可用的設(shè)備中返回一些優(yōu)選的設(shè)備用來分配,
// 所返回的優(yōu)選分配結(jié)果不一定會是設(shè)備管理器的最終分配方案。
// 此接口的設(shè)計僅是為了讓設(shè)備管理器能夠在可能的情況下做出更有意義的決定。
rpc GetPreferredAllocation(PreferredAllocationRequest) returns (PreferredAllocationResponse) {}
// PreStartContainer 在設(shè)備插件注冊階段根據(jù)需要被調(diào)用,調(diào)用發(fā)生在容器啟動之前。
// 在將設(shè)備提供給容器使用之前,設(shè)備插件可以運行一些諸如重置設(shè)備之類的特定于
// 具體設(shè)備的操作,
rpc PreStartContainer(PreStartContainerRequest) returns (PreStartContainerResponse) {}
}Note:
插件并非必須為 ?
GetPreferredAllocation()? 或 ?
PreStartContainer()? 提供有用 的實現(xiàn)邏輯,調(diào)用 ?
GetDevicePluginOptions()? 時所返回的 ?
DevicePluginOptions? 消息中應(yīng)該設(shè)置這些調(diào)用是否可用。?
kubelet?在真正調(diào)用這些函數(shù)之前,總會調(diào)用 ?
GetDevicePluginOptions()? 來查看是否存在這些可選的函數(shù)。
- 插件通過 Unix socket 在主機路徑 ?
/var/lib/kubelet/device-plugins/kubelet.sock? 處向 kubelet 注冊自身。 - 成功注冊自身后,設(shè)備插件將以服務(wù)模式運行,在此期間,它將持續(xù)監(jiān)控設(shè)備運行狀況, 并在設(shè)備狀態(tài)發(fā)生任何變化時向 kubelet 報告。它還負責(zé)響應(yīng) ?
Allocate?gRPC 請求。 在 ?Allocate?期間,設(shè)備插件可能還會做一些設(shè)備特定的準備;例如 GPU 清理或 QRNG 初始化。 如果操作成功,則設(shè)備插件將返回 ?AllocateResponse?,其中包含用于訪問被分配的設(shè)備容器運行時的配置。 kubelet 將此信息傳遞到容器運行時。
處理 kubelet 重啟
設(shè)備插件應(yīng)能監(jiān)測到 kubelet 重啟,并且向新的 kubelet 實例來重新注冊自己。 在當(dāng)前實現(xiàn)中,當(dāng) kubelet 重啟的時候,新的 kubelet 實例會刪除 ?/var/lib/kubelet/device-plugins? 下所有已經(jīng)存在的 Unix 套接字。 設(shè)備插件需要能夠監(jiān)控到它的 Unix 套接字被刪除,并且當(dāng)發(fā)生此類事件時重新注冊自己。
設(shè)備插件部署
你可以將你的設(shè)備插件作為節(jié)點操作系統(tǒng)的軟件包來部署、作為 DaemonSet 來部署或者手動部署。
規(guī)范目錄 ?/var/lib/kubelet/device-plugins? 是需要特權(quán)訪問的,所以設(shè)備插件 必須要在被授權(quán)的安全的上下文中運行。 如果你將設(shè)備插件部署為 DaemonSet,?/var/lib/kubelet/device-plugins? 目錄必須要在插件的 PodSpec 中聲明作為 卷(Volume) 被掛載到插件中。
如果你選擇 DaemonSet 方法,你可以通過 Kubernetes 進行以下操作: 將設(shè)備插件的 Pod 放置在節(jié)點上,在出現(xiàn)故障后重新啟動守護進程 Pod,來進行自動升級。
API 兼容性
Kubernetes 設(shè)備插件支持還處于 beta 版本。所以在穩(wěn)定版本出來之前 API 會以不兼容的方式進行更改。 作為一個項目,Kubernetes 建議設(shè)備插件開發(fā)者:
- 注意未來版本的更改
- 支持多個版本的設(shè)備插件 API,以實現(xiàn)向后/向前兼容性。
如果你啟用 DevicePlugins 功能,并在需要升級到 Kubernetes 版本來獲得較新的設(shè)備插件 API 版本的節(jié)點上運行設(shè)備插件,請在升級這些節(jié)點之前先升級設(shè)備插件以支持這兩個版本。 采用該方法將確保升級期間設(shè)備分配的連續(xù)運行。
監(jiān)控設(shè)備插件資源
FEATURE STATE: Kubernetes v1.15 [beta]
為了監(jiān)控設(shè)備插件提供的資源,監(jiān)控代理程序需要能夠發(fā)現(xiàn)節(jié)點上正在使用的設(shè)備, 并獲取元數(shù)據(jù)來描述哪個指標與容器相關(guān)聯(lián)。 設(shè)備監(jiān)控代理暴露給 Prometheus 的指標應(yīng)該遵循 Kubernetes Instrumentation Guidelines, 使用 ?pod?、?namespace ?和 ?container ?標簽來標識容器。
kubelet 提供了 gRPC 服務(wù)來使得正在使用中的設(shè)備被發(fā)現(xiàn),并且還未這些設(shè)備提供了元數(shù)據(jù):
// PodResourcesLister 是一個由 kubelet 提供的服務(wù),用來提供供節(jié)點上
// Pods 和容器使用的節(jié)點資源的信息
service PodResourcesLister {
rpc List(ListPodResourcesRequest) returns (ListPodResourcesResponse) {}
rpc GetAllocatableResources(AllocatableResourcesRequest) returns (AllocatableResourcesResponse) {}
}List gRPC 端點
這一 ?List ?端點提供運行中 Pods 的資源信息,包括類似獨占式分配的 CPU ID、設(shè)備插件所報告的設(shè)備 ID 以及這些設(shè)備分配所處的 NUMA 節(jié)點 ID。 此外,對于基于 NUMA 的機器,它還會包含為容器保留的內(nèi)存和大頁的信息。
// ListPodResourcesResponse 是 List 函數(shù)的響應(yīng)
message ListPodResourcesResponse {
repeated PodResources pod_resources = 1;
}
// PodResources 包含關(guān)于分配給 Pod 的節(jié)點資源的信息
message PodResources {
string name = 1;
string namespace = 2;
repeated ContainerResources containers = 3;
}
// ContainerResources 包含分配給容器的資源的信息
message ContainerResources {
string name = 1;
repeated ContainerDevices devices = 2;
repeated int64 cpu_ids = 3;
repeated ContainerMemory memory = 4;
}
// ContainerMemory 包含分配給容器的內(nèi)存和大頁信息
message ContainerMemory {
string memory_type = 1;
uint64 size = 2;
TopologyInfo topology = 3;
}
// Topology 描述資源的硬件拓撲結(jié)構(gòu)
message TopologyInfo {
repeated NUMANode nodes = 1;
}
// NUMA 代表的是 NUMA 節(jié)點
message NUMANode {
int64 ID = 1;
}
// ContainerDevices 包含分配給容器的設(shè)備信息
message ContainerDevices {
string resource_name = 1;
repeated string device_ids = 2;
TopologyInfo topology = 3;
}Note:
?
List?端點中的 ?
ContainerResources?中的 cpu_ids 對應(yīng)于分配給某個容器的專屬 CPU。 如果要統(tǒng)計共享池中的 CPU,?
List?端點需要與 ?
GetAllocatableResources?端點一起使用,如下所述:
- 調(diào)用 ?
GetAllocatableResources?獲取所有可用的 CPUs。- 在系統(tǒng)中所有的 ?
ContainerResources?上調(diào)用 ?GetCpuIds?。- 用 ?
GetAllocatableResources?獲取的 CPU 數(shù)減去 ?GetCpuIds?獲取的 CPU 數(shù)。
GetAllocatableResources gRPC 端點
FEATURE STATE: Kubernetes v1.23 [beta]
端點 ?GetAllocatableResources ?提供工作節(jié)點上原始可用的資源信息。 此端點所提供的信息比導(dǎo)出給 API 服務(wù)器的信息更豐富。
Note:
?
GetAllocatableResources?應(yīng)該僅被用于評估一個節(jié)點上的可分配的 資源。如果目標是評估空閑/未分配的資源,此調(diào)用應(yīng)該與 List() 端點一起使用。 除非暴露給 kubelet 的底層資源發(fā)生變化 否則 ?
GetAllocatableResources?得到的結(jié)果將保持不變。 這種情況很少發(fā)生,但當(dāng)發(fā)生時(例如:熱插拔,設(shè)備健康狀況改變),客戶端應(yīng)該調(diào)用 ?
GetAlloctableResources?端點。 然而,調(diào)用 ?
GetAllocatableResources?端點在 cpu、內(nèi)存被更新的情況下是不夠的, Kubelet 需要重新啟動以獲取正確的資源容量和可分配的資源。
// AllocatableResourcesResponses 包含 kubelet 所了解到的所有設(shè)備的信息
message AllocatableResourcesResponse {
repeated ContainerDevices devices = 1;
repeated int64 cpu_ids = 2;
repeated ContainerMemory memory = 3;
}從 Kubernetes v1.23 開始,?GetAllocatableResources ?被默認啟用。 你可以通過關(guān)閉 ?KubeletPodResourcesGetAllocatable ?特性門控 來禁用。
在 Kubernetes v1.23 之前,要啟用這一功能,?kubelet ?必須用以下標志啟動:
?--feature-gates=KubeletPodResourcesGetAllocatable=true?
?ContainerDevices ?會向外提供各個設(shè)備所隸屬的 NUMA 單元這類拓撲信息。 NUMA 單元通過一個整數(shù) ID 來標識,其取值與設(shè)備插件所報告的一致。 設(shè)備插件注冊到 kubelet 時 會報告這類信息。
gRPC 服務(wù)通過 ?/var/lib/kubelet/pod-resources/kubelet.sock? 的 UNIX 套接字來提供服務(wù)。 設(shè)備插件資源的監(jiān)控代理程序可以部署為守護進程或者 DaemonSet。 規(guī)范的路徑 ?/var/lib/kubelet/pod-resources? 需要特權(quán)來進入, 所以監(jiān)控代理程序必須要在獲得授權(quán)的安全的上下文中運行。 如果設(shè)備監(jiān)控代理以 DaemonSet 形式運行,必須要在插件的 PodSpec 中聲明將 ?/var/lib/kubelet/pod-resources? 目錄以 卷的形式被掛載到設(shè)備監(jiān)控代理中。
對“PodResourcesLister 服務(wù)”的支持要求啟用 ?KubeletPodResources ?特性門控。 從 Kubernetes 1.15 開始默認啟用,自從 Kubernetes 1.20 開始為 v1。
設(shè)備插件與拓撲管理器的集成
FEATURE STATE: Kubernetes v1.18 [beta]
拓撲管理器是 Kubelet 的一個組件,它允許以拓撲對齊方式來調(diào)度資源。 為了做到這一點,設(shè)備插件 API 進行了擴展來包括一個 ?TopologyInfo ?結(jié)構(gòu)體。
message TopologyInfo {
repeated NUMANode nodes = 1;
}
message NUMANode {
int64 ID = 1;
}設(shè)備插件希望拓撲管理器可以將填充的 TopologyInfo 結(jié)構(gòu)體作為設(shè)備注冊的一部分以及設(shè)備 ID 和設(shè)備的運行狀況發(fā)送回去。然后設(shè)備管理器將使用此信息來咨詢拓撲管理器并做出資源分配決策。
?TopologyInfo ?支持定義 ?nodes ?字段,允許為 ?nil?(默認)或者是一個 NUMA 節(jié)點的列表。 這樣就可以使設(shè)備插件可以跨越 NUMA 節(jié)點去發(fā)布。
下面是一個由設(shè)備插件為設(shè)備填充 ?TopologyInfo ?結(jié)構(gòu)體的示例:
pluginapi.Device{ID: "25102017", Health: pluginapi.Healthy, Topology:&pluginapi.TopologyInfo{Nodes: []*pluginapi.NUMANode{&pluginapi.NUMANode{ID: 0,},}}}
設(shè)備插件示例
下面是一些設(shè)備插件實現(xiàn)的示例:
- AMD GPU 設(shè)備插件
- Intel 設(shè)備插件 支持 Intel GPU、FPGA 和 QuickAssist 設(shè)備
- KubeVirt 設(shè)備插件 用于硬件輔助的虛擬化
- 為 Container-Optimized OS 所提供的 NVIDIA GPU 設(shè)備插件
- RDMA 設(shè)備插件
- SocketCAN 設(shè)備插件
- Solarflare 設(shè)備插件
- SR-IOV 網(wǎng)絡(luò)設(shè)備插件
- Xilinx FPGA 設(shè)備插件
文章名稱:創(chuàng)新互聯(lián)kubernetes教程:Kubernetes 設(shè)備插件
文章鏈接:http://fisionsoft.com.cn/article/dpdsdge.html


咨詢
建站咨詢
