W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
FEATURE STATE: Kubernetes v1.10 [beta]
Kubernetes 提供了一個(gè) 設(shè)備插件框架,你可以用它來將系統(tǒng)硬件資源發(fā)布到 Kubelet。
供應(yīng)商可以實(shí)現(xiàn)設(shè)備插件,由你手動(dòng)部署或作為 DaemonSet 來部署,而不必定制 Kubernetes 本身的代碼。目標(biāo)設(shè)備包括 GPU、高性能 NIC、FPGA、 InfiniBand 適配器以及其他類似的、可能需要特定于供應(yīng)商的初始化和設(shè)置的計(jì)算資源。
?kubelet
?提供了一個(gè) ?Registration
?的 gRPC 服務(wù):
service Registration {
rpc Register(RegisterRequest) returns (Empty) {}
}
設(shè)備插件可以通過此 gRPC 服務(wù)在 kubelet 進(jìn)行注冊。在注冊期間,設(shè)備插件需要發(fā)送下面幾樣內(nèi)容:
ResourceName
?是需要公布的。這里 ?ResourceName
?需要遵循 擴(kuò)展資源命名方案, 類似于 ?vendor-domain/resourcetype
?。(比如 NVIDIA GPU 就被公布為 ?nvidia.com/gpu
?。)成功注冊后,設(shè)備插件就向 kubelet 發(fā)送它所管理的設(shè)備列表,然后 kubelet 負(fù)責(zé)將這些資源發(fā)布到 API 服務(wù)器,作為 kubelet 節(jié)點(diǎn)狀態(tài)更新的一部分。
比如,設(shè)備插件在 kubelet 中注冊了 ?hardware-vendor.example/foo
? 并報(bào)告了 節(jié)點(diǎn)上的兩個(gè)運(yùn)行狀況良好的設(shè)備后,節(jié)點(diǎn)狀態(tài)將更新以通告該節(jié)點(diǎn)已安裝 2 個(gè) "Foo" 設(shè)備并且是可用的。
然后,用戶可以請(qǐng)求設(shè)備作為 Pod 規(guī)范的一部分。請(qǐng)求擴(kuò)展資源類似于管理請(qǐng)求和限制的方式, 其他資源,有以下區(qū)別:
假設(shè) Kubernetes 集群正在運(yùn)行一個(gè)設(shè)備插件,該插件在一些節(jié)點(diǎn)上公布的資源為 ?hardware-vendor.example/foo
?。 下面就是一個(gè) Pod 示例,請(qǐng)求此資源以運(yùn)行一個(gè)工作負(fù)載的示例:
---
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
#
# 這個(gè) pod 需要兩個(gè) hardware-vendor.example/foo 設(shè)備
# 而且只能夠調(diào)度到滿足需求的節(jié)點(diǎn)上
#
# 如果該節(jié)點(diǎn)中有 2 個(gè)以上的設(shè)備可用,其余的可供其他 Pod 使用
設(shè)備插件的常規(guī)工作流程包括以下幾個(gè)步驟:
/var/lib/kubelet/device-plugins/
? 下的 Unix 套接字啟動(dòng) 一個(gè) gRPC 服務(wù),該服務(wù)實(shí)現(xiàn)以下接口:service DevicePlugin {
// GetDevicePluginOptions 返回與設(shè)備管理器溝通的選項(xiàng)。
rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {}
// ListAndWatch 返回 Device 列表構(gòu)成的數(shù)據(jù)流。
// 當(dāng) Device 狀態(tài)發(fā)生變化或者 Device 消失時(shí),ListAndWatch
// 會(huì)返回新的列表。
rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
// Allocate 在容器創(chuàng)建期間調(diào)用,這樣設(shè)備插件可以運(yùn)行一些特定于設(shè)備的操作,
// 并告訴 kubelet 如何令 Device 可在容器中訪問的所需執(zhí)行的具體步驟
rpc Allocate(AllocateRequest) returns (AllocateResponse) {}
// GetPreferredAllocation 從一組可用的設(shè)備中返回一些優(yōu)選的設(shè)備用來分配,
// 所返回的優(yōu)選分配結(jié)果不一定會(huì)是設(shè)備管理器的最終分配方案。
// 此接口的設(shè)計(jì)僅是為了讓設(shè)備管理器能夠在可能的情況下做出更有意義的決定。
rpc GetPreferredAllocation(PreferredAllocationRequest) returns (PreferredAllocationResponse) {}
// PreStartContainer 在設(shè)備插件注冊階段根據(jù)需要被調(diào)用,調(diào)用發(fā)生在容器啟動(dòng)之前。
// 在將設(shè)備提供給容器使用之前,設(shè)備插件可以運(yùn)行一些諸如重置設(shè)備之類的特定于
// 具體設(shè)備的操作,
rpc PreStartContainer(PreStartContainerRequest) returns (PreStartContainerResponse) {}
}
Note:
插件并非必須為 ?GetPreferredAllocation()
? 或 ?PreStartContainer()
? 提供有用 的實(shí)現(xiàn)邏輯,調(diào)用 ?GetDevicePluginOptions()
? 時(shí)所返回的 ?DevicePluginOptions
? 消息中應(yīng)該設(shè)置這些調(diào)用是否可用。?kubelet
?在真正調(diào)用這些函數(shù)之前,總會(huì)調(diào)用 ?GetDevicePluginOptions()
? 來查看是否存在這些可選的函數(shù)。
/var/lib/kubelet/device-plugins/kubelet.sock
? 處向 kubelet 注冊自身。Allocate
?gRPC 請(qǐng)求。 在 ?Allocate
?期間,設(shè)備插件可能還會(huì)做一些設(shè)備特定的準(zhǔn)備;例如 GPU 清理或 QRNG 初始化。 如果操作成功,則設(shè)備插件將返回 ?AllocateResponse
?,其中包含用于訪問被分配的設(shè)備容器運(yùn)行時(shí)的配置。 kubelet 將此信息傳遞到容器運(yùn)行時(shí)。設(shè)備插件應(yīng)能監(jiān)測到 kubelet 重啟,并且向新的 kubelet 實(shí)例來重新注冊自己。 在當(dāng)前實(shí)現(xiàn)中,當(dāng) kubelet 重啟的時(shí)候,新的 kubelet 實(shí)例會(huì)刪除 ?/var/lib/kubelet/device-plugins
? 下所有已經(jīng)存在的 Unix 套接字。 設(shè)備插件需要能夠監(jiān)控到它的 Unix 套接字被刪除,并且當(dāng)發(fā)生此類事件時(shí)重新注冊自己。
你可以將你的設(shè)備插件作為節(jié)點(diǎn)操作系統(tǒng)的軟件包來部署、作為 DaemonSet 來部署或者手動(dòng)部署。
規(guī)范目錄 ?/var/lib/kubelet/device-plugins
? 是需要特權(quán)訪問的,所以設(shè)備插件 必須要在被授權(quán)的安全的上下文中運(yùn)行。 如果你將設(shè)備插件部署為 DaemonSet,?/var/lib/kubelet/device-plugins
? 目錄必須要在插件的 PodSpec 中聲明作為 卷(Volume) 被掛載到插件中。
如果你選擇 DaemonSet 方法,你可以通過 Kubernetes 進(jìn)行以下操作: 將設(shè)備插件的 Pod 放置在節(jié)點(diǎn)上,在出現(xiàn)故障后重新啟動(dòng)守護(hù)進(jìn)程 Pod,來進(jìn)行自動(dòng)升級(jí)。
Kubernetes 設(shè)備插件支持還處于 beta 版本。所以在穩(wěn)定版本出來之前 API 會(huì)以不兼容的方式進(jìn)行更改。 作為一個(gè)項(xiàng)目,Kubernetes 建議設(shè)備插件開發(fā)者:
如果你啟用 DevicePlugins 功能,并在需要升級(jí)到 Kubernetes 版本來獲得較新的設(shè)備插件 API 版本的節(jié)點(diǎn)上運(yùn)行設(shè)備插件,請(qǐng)?jiān)谏?jí)這些節(jié)點(diǎn)之前先升級(jí)設(shè)備插件以支持這兩個(gè)版本。 采用該方法將確保升級(jí)期間設(shè)備分配的連續(xù)運(yùn)行。
FEATURE STATE: Kubernetes v1.15 [beta]
為了監(jiān)控設(shè)備插件提供的資源,監(jiān)控代理程序需要能夠發(fā)現(xiàn)節(jié)點(diǎn)上正在使用的設(shè)備, 并獲取元數(shù)據(jù)來描述哪個(gè)指標(biāo)與容器相關(guān)聯(lián)。 設(shè)備監(jiān)控代理暴露給 Prometheus 的指標(biāo)應(yīng)該遵循 Kubernetes Instrumentation Guidelines, 使用 ?pod
?、?namespace
?和 ?container
?標(biāo)簽來標(biāo)識(shí)容器。
kubelet 提供了 gRPC 服務(wù)來使得正在使用中的設(shè)備被發(fā)現(xiàn),并且還未這些設(shè)備提供了元數(shù)據(jù):
// PodResourcesLister 是一個(gè)由 kubelet 提供的服務(wù),用來提供供節(jié)點(diǎn)上
// Pods 和容器使用的節(jié)點(diǎn)資源的信息
service PodResourcesLister {
rpc List(ListPodResourcesRequest) returns (ListPodResourcesResponse) {}
rpc GetAllocatableResources(AllocatableResourcesRequest) returns (AllocatableResourcesResponse) {}
}
這一 ?List
?端點(diǎn)提供運(yùn)行中 Pods 的資源信息,包括類似獨(dú)占式分配的 CPU ID、設(shè)備插件所報(bào)告的設(shè)備 ID 以及這些設(shè)備分配所處的 NUMA 節(jié)點(diǎn) ID。 此外,對(duì)于基于 NUMA 的機(jī)器,它還會(huì)包含為容器保留的內(nèi)存和大頁的信息。
// ListPodResourcesResponse 是 List 函數(shù)的響應(yīng)
message ListPodResourcesResponse {
repeated PodResources pod_resources = 1;
}
// PodResources 包含關(guān)于分配給 Pod 的節(jié)點(diǎn)資源的信息
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 描述資源的硬件拓?fù)浣Y(jié)構(gòu)
message TopologyInfo {
repeated NUMANode nodes = 1;
}
// NUMA 代表的是 NUMA 節(jié)點(diǎn)
message NUMANode {
int64 ID = 1;
}
// ContainerDevices 包含分配給容器的設(shè)備信息
message ContainerDevices {
string resource_name = 1;
repeated string device_ids = 2;
TopologyInfo topology = 3;
}
Note:
?List
?端點(diǎn)中的 ?ContainerResources
?中的 cpu_ids 對(duì)應(yīng)于分配給某個(gè)容器的專屬 CPU。 如果要統(tǒng)計(jì)共享池中的 CPU,?List
?端點(diǎn)需要與 ?GetAllocatableResources
?端點(diǎn)一起使用,如下所述:
- 調(diào)用 ?
GetAllocatableResources
?獲取所有可用的 CPUs。- 在系統(tǒng)中所有的 ?
ContainerResources
?上調(diào)用 ?GetCpuIds
?。- 用 ?
GetAllocatableResources
?獲取的 CPU 數(shù)減去 ?GetCpuIds
?獲取的 CPU 數(shù)。
FEATURE STATE: Kubernetes v1.23 [beta]
端點(diǎn) ?GetAllocatableResources
?提供工作節(jié)點(diǎn)上原始可用的資源信息。 此端點(diǎn)所提供的信息比導(dǎo)出給 API 服務(wù)器的信息更豐富。
Note:
?GetAllocatableResources
?應(yīng)該僅被用于評(píng)估一個(gè)節(jié)點(diǎn)上的可分配的 資源。如果目標(biāo)是評(píng)估空閑/未分配的資源,此調(diào)用應(yīng)該與 List() 端點(diǎn)一起使用。 除非暴露給 kubelet 的底層資源發(fā)生變化 否則 ?GetAllocatableResources
?得到的結(jié)果將保持不變。 這種情況很少發(fā)生,但當(dāng)發(fā)生時(shí)(例如:熱插拔,設(shè)備健康狀況改變),客戶端應(yīng)該調(diào)用 ?GetAlloctableResources
?端點(diǎn)。 然而,調(diào)用 ?GetAllocatableResources
?端點(diǎn)在 cpu、內(nèi)存被更新的情況下是不夠的, Kubelet 需要重新啟動(dòng)以獲取正確的資源容量和可分配的資源。
// AllocatableResourcesResponses 包含 kubelet 所了解到的所有設(shè)備的信息
message AllocatableResourcesResponse {
repeated ContainerDevices devices = 1;
repeated int64 cpu_ids = 2;
repeated ContainerMemory memory = 3;
}
從 Kubernetes v1.23 開始,?GetAllocatableResources
?被默認(rèn)啟用。 你可以通過關(guān)閉 ?KubeletPodResourcesGetAllocatable
?特性門控 來禁用。
在 Kubernetes v1.23 之前,要啟用這一功能,?kubelet
?必須用以下標(biāo)志啟動(dòng):
?--feature-gates=KubeletPodResourcesGetAllocatable=true
?
?ContainerDevices
?會(huì)向外提供各個(gè)設(shè)備所隸屬的 NUMA 單元這類拓?fù)湫畔ⅰ?nbsp;NUMA 單元通過一個(gè)整數(shù) ID 來標(biāo)識(shí),其取值與設(shè)備插件所報(bào)告的一致。 設(shè)備插件注冊到 kubelet 時(shí) 會(huì)報(bào)告這類信息。
gRPC 服務(wù)通過 ?/var/lib/kubelet/pod-resources/kubelet.sock
? 的 UNIX 套接字來提供服務(wù)。 設(shè)備插件資源的監(jiān)控代理程序可以部署為守護(hù)進(jìn)程或者 DaemonSet。 規(guī)范的路徑 ?/var/lib/kubelet/pod-resources
? 需要特權(quán)來進(jìn)入, 所以監(jiān)控代理程序必須要在獲得授權(quán)的安全的上下文中運(yùn)行。 如果設(shè)備監(jiān)控代理以 DaemonSet 形式運(yùn)行,必須要在插件的 PodSpec 中聲明將 ?/var/lib/kubelet/pod-resources
? 目錄以 卷的形式被掛載到設(shè)備監(jiān)控代理中。
對(duì)“PodResourcesLister 服務(wù)”的支持要求啟用 ?KubeletPodResources
?特性門控。 從 Kubernetes 1.15 開始默認(rèn)啟用,自從 Kubernetes 1.20 開始為 v1。
FEATURE STATE: Kubernetes v1.18 [beta]
拓?fù)涔芾砥魇?nbsp;Kubelet 的一個(gè)組件,它允許以拓?fù)鋵?duì)齊方式來調(diào)度資源。 為了做到這一點(diǎn),設(shè)備插件 API 進(jìn)行了擴(kuò)展來包括一個(gè) ?TopologyInfo
?結(jié)構(gòu)體。
message TopologyInfo {
repeated NUMANode nodes = 1;
}
message NUMANode {
int64 ID = 1;
}
設(shè)備插件希望拓?fù)涔芾砥骺梢詫⑻畛涞?nbsp;TopologyInfo 結(jié)構(gòu)體作為設(shè)備注冊的一部分以及設(shè)備 ID 和設(shè)備的運(yùn)行狀況發(fā)送回去。然后設(shè)備管理器將使用此信息來咨詢拓?fù)涔芾砥鞑⒆龀鲑Y源分配決策。
?TopologyInfo
?支持定義 ?nodes
?字段,允許為 ?nil
?(默認(rèn))或者是一個(gè) NUMA 節(jié)點(diǎn)的列表。 這樣就可以使設(shè)備插件可以跨越 NUMA 節(jié)點(diǎn)去發(fā)布。
下面是一個(gè)由設(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)的示例:
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: