--- layout: blog title: 'Kubernetes 1.26:设备管理器正式发布' date: 2022-12-19 slug: devicemanager-ga --- **作者**: Swati Sehgal (Red Hat) **译者**: Jin Li (UOS) 设备插件框架是在 Kubernetes v1.8 版本中引入的,它是一个与供应商无关的框架, 旨在实现对外部设备的发现、公布和分配,而无需修改核心 Kubernetes。 该功能在 v1.10 版本中升级为 Beta 版本。随着 Kubernetes v1.26 的最新发布, 设备管理器现已正式发布(GA)。 在 kubelet 中,设备管理器通过 Unix 套接字使用 gRPC 实现与设备插件的通信。 设备管理器和设备插件都充当 gRPC 服务器和客户端的角色,分别提供暴露的 gRPC 服务并进行连接。 设备插件提供 gRPC 服务,kubelet 连接该服务进行设备的发现、公布(作为扩展资源)和分配。 设备管理器连接到 kubelet 提供的 `Registration` gRPC 服务,以向 kubelet 注册自身。 请查阅文档中的[示例](/zh-cn/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/#example-pod), 了解一个 Pod 如何通过设备插件请求集群中暴露的设备。 以下是设备插件的一些示例实现: - [AMD GPU 设备插件](https://github.com/RadeonOpenCompute/k8s-device-plugin) - [用于 Kubernetes 的 Intel 设备插件集合](https://github.com/intel/intel-device-plugins-for-kubernetes) - [用于 Kubernetes 的 NVIDIA 设备插件](https://github.com/NVIDIA/k8s-device-plugin) - [用于 Kubernetes 的 SRIOV 网络设备插件](https://github.com/k8snetworkplumbingwg/sriov-network-device-plugin) ## 自设备插件框架引入以来的重要进展 ### Kubelet APIs 移至 kubelet 暂存库 在 v1.17 版本中,面向外部的 `deviceplugin` API 包已从 `k8s.io/kubernetes/pkg/kubelet/apis/` 移动到了 `k8s.io/kubelet/pkg/apis/`。有关此变更背后的更多详细信息, 请参阅 [Move external facing kubelet apis to staging](https://github.com/kubernetes/kubernetes/pull/83551) ### 设备插件 API 更新 新增了额外的 gRPC 端点: 1. `GetDevicePluginOptions` 用于设备插件向 `DeviceManager` 传递选项,以指示是否支持 `PreStartContainer`、`GetPreferredAllocation` 或其他将来的可选调用, 并可在向容器提供设备之前进行调用。 2. `GetPreferredAllocation` 允许设备插件将优先分配信息传递给 `DeviceManager`, 使其能够将此信息纳入其分配决策中。`DeviceManager` 在 Pod 准入时向插件请求指定大小的优选设备分配,以便做出更明智的决策。 例如,在为容器分配设备时,指定设备间的约束条件以表明对最佳连接设备集合的偏好。 3. 在注册阶段由设备插件指示时,`PreStartContainer` 会在每次容器启动之前被调用。 它允许设备插件在所请求的设备上执行特定的设备操作。 例如,在容器启动前对 FPGA 进行重新配置或重新编程。 引入这些更改的 PR 为: 1. [Invoke preStart RPC call before container start, if desired by plugin](https://github.com/kubernetes/kubernetes/pull/58282) 1. [Add GetPreferredAllocation() call to the v1beta1 device plugin API](https://github.com/kubernetes/kubernetes/pull/92665) 引入上述端点后,kubelet 中的设备管理器与设备管理器之间的交互如下所示: {{< figure src="deviceplugin-framework-overview.svg" alt="展示设备插件框架,显示 kubelet 与设备插件之间的关系" class="diagram-large" caption="设备插件框架概述" >}} ### 设备插件注册流程的语义变更 设备插件的代码经过重构,将 'plugin' 包独立于 `devicemanager` 包之外, 为引入 `v1beta2` 设备插件 API 做好了前期准备。 这将允许在 `devicemanager` 中添加支持,以便同时为多个设备插件 API 提供服务。 通过这次重构工作,现在设备插件必须在向 kubelet 注册之前开始提供其 gRPC 服务。 之前这两个操作是异步的,设备插件可以在启动其 gRPC 服务器之前注册自己,但现在不再允许。 更多细节请参考 [PR #109016](https://github.com/kubernetes/kubernetes/pull/109016) 和 [Issue #112395](https://github.com/kubernetes/kubernetes/issues/112395)。 ### 动态资源分配 在 Kubernetes 1.26 中,受 Kubernetes 处理[持久卷](/zh-cn/docs/concepts/storage/persistent-volumes)方式的启发, 引入了[动态资源分配](/zh-cn/docs/concepts/scheduling-eviction/dynamic-resource-allocation/), 以满足那些具有更复杂资源需求的设备,例如: 1. 将设备的初始化和分配与 Pod 生命周期解耦。 1. 促进容器和 Pod 之间设备的动态共享。 1. 支持自定义特定资源参数。 1. 启用特定资源的设置和清理操作。 1. 实现对网络附加资源的支持,不再局限于节点本地资源。 ## 设备插件 API 目前已经稳定了吗? 不,设备插件 API 仍然不稳定;目前最新的可用设备插件 API 版本是 `v1beta1`。 社区计划引入 `v1beta2` API,以便同时为多个插件 API 提供服务。 对每个 API 的调用都具有请求/响应类型,可以在不明确升级 API 的情况下添加对新 API 版本的支持。 除此之外,社区中存在一些提案,打算引入额外的端点 [KEP-3162: Add Deallocate and PostStopContainer to Device Manager API](https://github.com/kubernetes/enhancements/issues/3162)。