本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.26: Device Manager 进阶至 GA

设备插件(Device Plugin)框架在 Kubernetes v1.8 版本中引入,作为一个独立于供应商的框架,无需修改 Kubernetes 核心代码即可实现外部设备的发现、通告和分配。该功能在 v1.10 版本中升级为 Beta。随着 Kubernetes v1.26 的最新发布,设备管理器(Device Manager)现已正式可用(GA)。

在 kubelet 内部,设备管理器通过 Unix 套接字使用 gRPC 与设备插件进行通信。设备管理器和设备插件都通过分别提供和连接到暴露的 gRPC 服务,同时充当 gRPC 的服务器和客户端。设备插件提供一个 gRPC 服务,kubelet 连接该服务以进行设备发现、通告(作为扩展资源)和分配。设备管理器连接到由 kubelet 提供的 Registration gRPC 服务,以向 kubelet 注册自身。

有关 Pod 如何请求由设备插件暴露给集群的设备的示例,请参阅文档。

以下是一些设备插件的实现示例:

自设备插件框架引入以来的显著发展

Kubelet API 移至 kubelet staging 仓库

面向外部的 deviceplugin API 包在 v1.17 中从 k8s.io/kubernetes/pkg/kubelet/apis/ 移至 k8s.io/kubelet/pkg/apis/。有关此更改背后原因的更多详细信息,请参阅 将面向外部的 kubelet API 移至 staging

设备插件 API 更新

引入了额外的 gRPC 端点

  1. GetDevicePluginOptions 由设备插件用于向 DeviceManager 传达选项,以指示是否支持 PreStartContainerGetPreferredAllocation 或其他未来的可选调用,并可以在将设备提供给容器之前调用这些接口。
  2. GetPreferredAllocation 允许设备插件将分配偏好转发给 DeviceManager,以便后者可以在其分配决策中纳入此信息。DeviceManager 将在 Pod 准入时调用插件,请求从可用设备列表中为给定大小的请求提供首选的设备分配,从而做出更明智的决策。例如,在为容器分配设备时,指定设备间的约束以表明对连接性最佳的设备集的偏好。
  3. 如果在注册阶段由设备插件指定,PreStartContainer 会在每个容器启动前被调用。它允许设备插件在所请求的设备上运行特定于设备的操作。例如,在容器开始运行前重新配置或重新编程 FPGA。

引入这些更改的拉取请求如下:

  1. 如果插件需要,在容器启动前调用 preStart RPC
  2. 向 v1beta1 设备插件 API 添加 GetPreferredAllocation() 调用

随着上述端点的引入,kubelet 中的设备管理器与设备插件之间的交互如下图所示:

Representation of the Device Plugin framework showing the relationship between the kubelet and a device plugin

设备插件框架概述

设备插件注册流程的语义变化

设备插件代码被重构,将 `plugin` 包分离到 devicemanager 包下,为引入 v1beta2 设备插件 API 奠定基础。这将允许在 devicemanager 中增加同时为多个设备插件 API 提供支持的能力。

通过这次重构工作,设备插件现在必须在向 kubelet 注册之前启动其 gRPC 服务。以前,这两个操作是异步的,设备插件可以在启动其 gRPC 服务器之前注册自己,但现在情况已不再如此。更多详情,请参阅 PR #109016Issue #112395

动态资源分配

在 Kubernetes 1.26 中,受 Kubernetes 中处理持久卷(Persistent Volumes)方式的启发,引入了动态资源分配(Dynamic Resource Allocation),以满足具有更复杂资源需求的设备,例如:

  1. 将设备初始化和分配与 Pod 生命周期解耦。
  2. 促进容器和 Pod 之间设备的动态共享。
  3. 支持自定义的特定于资源的参数。
  4. 启用特定于资源的设置和清理操作。
  5. 不仅支持节点本地资源,还支持网络附加资源。

设备插件 API 现在稳定了吗?

不,设备插件 API 仍然不稳定;当前可用的最新设备插件 API 版本是 v1beta1。社区计划引入 v1beta2 API,以同时为多个插件 API 提供服务。每个 API 调用都带有请求/响应类型,这将允许在不明确提升 API 版本的情况下增加对新 API 版本的支持。

除此之外,社区中还有一些现有的提议,旨在引入额外的端点 KEP-3162:向设备管理器 API 添加 Deallocate 和 PostStopContainer