k8s的擴充套件資源設計和device plugin

2021-09-10 18:44:53 字數 3367 閱讀 6109

extended-resources在k8s1.9中是乙個stable的特性。可以用一句話來概括這個特性:

通過向apiserver傳送乙個patch node 的請求,為這個node增加乙個自定義的資源型別,用於以該資源的配額統計和相應的qos的配置。

patch node 的請求:

舉例:--request patch \

如上,我們為10.123.123.123這個node增加了乙個resource:example.com/dongle (命令中的 ~1 會轉化為 / ) ,這個node的capicity/allocable中會展示其有4個example.com/dongle資源:

qos配置:

先假設整個k8s集群中我們只對10.123.123.123這個node動了手腳,當我們建立pod時,在spec.containers.resources.requests/limits中可以設定

"example.com/dongle": "2"從而讓pod被排程到10.123.123.123上並消耗其2個example.com/dongle資源。這個資源將與cpu、memory一樣,被排程器進行統計,並用在pod的排程演算法中。如果node上的example.com/dongle資源耗盡,這類pod將無法成功排程。

裝置外掛程式從1.8版本開始加入,到1.9目前仍是alpha特性,裝置外掛程式的作用是在不更改k8s**的情況下,向k8s提供各種資源的統計資訊和使用預備工作。這裡說的資源如gpu、高效能nic、fpga、infiniband或其他。

device-plugin的註冊和實施

device-plugin功能由deviceplugins這個引數控制,預設是禁用的,啟用這個引數後就可以令kubelet開放register 的grpc服務。 device-plugin可以通過這個服務向kubelet註冊自己,註冊時要告知kubelet:

註冊成功後,kubelet會向device-plugin呼叫listandwatch方法獲取裝置的列表,此處裝置的列表以該資源所有裝置的描述資訊(id、健康狀態)組成陣列返回。kubelet將這個資源及其對應的裝置個數記錄到node.status.capicity/allocable 更新到apiserver。該方法會一直迴圈檢查,一旦裝置異常或者從機器上拔出,會將最新的裝置列表返回給kubelet。

如此一來,建立pod時,spec.containers.resource.limits/requests 中就可以增加如 "nvidia.com/gpu" : 2 這樣的字段,來告知k8s將pod排程到有超過2個nvidia.com/gpu資源餘量的nodes上(這裡與上文的extended-resources中qos是乙個道理)。當node上要執行該pod時,kubelet會向device-plugin呼叫allocate方法,device-plugin在這裡可能會做一些初始化的操作,比如gpu清理或qrng初始化之類。如果初始化成功。該方法會返回分配給該pod使用的裝置在容器建立時需要如何配置,這個配置會被傳遞到container runtime。用於run 容器時作為引數進行配置。

device-plugin 使用的**解析

我們從建立pod的整個流程中一步步解析**執行:

建立帶特殊資源裝置的pod;

排程器從cache中選擇滿足要求的node;

node收到add pod, 對pod執行admit方法進行可執行的判斷。

kubelet初始化時增加了乙個admithandler

klet.admithandlers.addpodadmithandler(lifecycle.newpredicateadmithandler(klet.getnodeanyway, criticalpodadmissionhandler, klet.containermanager.updatepluginresources))
其中就包括了klet.containermanager.updatepluginresources方法,該方法會執行devicepluginmanager中的allocate方法:

func (cm *containermanagerimpl) updatepluginresources(node *schedulercache.nodeinfo, attrs *lifecycle.podadmitattributes) error
上述的allocate方法,會將kubelet本身快取記錄的資源可用量進行判斷和計算;

然後選定要使用的裝置,向device-plugin傳送allocate呼叫,device-plugin會針對request中的裝置id,檢查是否可用,並將使用這幾個裝置需要的使用引數返回給kubelet,返回的格式是:

type allocateresponse struct
最後將要這個pod要使用哪幾個資源裝置(裝置id、以及deviceplugin返回的裝置使用引數)記錄在poddevices中,poddevices就是乙個從pod到資源裝置詳細資訊的對映,是乙個多層次的map結構。

kubelet要建立pod的容器時,會呼叫到generateruncontaineroptions方法,用於生成容器runtime要的引數,該方法中會首先呼叫:

opts, err := kl.containermanager.getresources(pod, container)
containermanagergetresources會呼叫devicepluginmanager中的getdeviceruncontaineroptions方法,最後執行deviceruncontaineroptions方法,從poddevices中獲取這個pod相應的容器需要使用的裝置,並組織成容器執行時引數的物件opts,最終run container時會被用到。比如gpu容器,會在opts中增加devices引數的指定,最後容器建立時會帶有需要的裝置。

device-plugin的部署

部署device-plugin外掛程式最佳的方法是使用k8s的daemonset,因為daemonset可以在外掛程式失敗是重新啟動之,且會自動分布到滿足條件的所有node節點上。

社群參考文件

k8s的擴充套件資源設計和device plugin

extended resources在k8s1.9中是乙個stable的特性。可以用一句話來概括這個特性 通過向apiserver傳送乙個patch node 的請求,為這 個node增加乙個自定義的資源型別,用於以該資源的配額統計和相應的qos的配置。舉例 request patch 如上,我們為...

k8s資源限制

注 以下只是在yaml檔案中進行資源限制的乙個片段,並不是完整的yaml檔案,僅是自己的乙個隨筆。root master limit vim cgroup pod.yaml spec containers name image ports protocol tcp containerport 80 ...

k8s資源清單

自主式的pod無法自癒 編輯檔案vim pod.yaml apiversion v1 指定api的版本 kind pod 檔案自定義的資源型別和角色,控制器型別 metadata 元資料物件 name demo 命名空間 labels 標籤 spec 固定物件容器的控制 containers nam...