这篇文章已经超过一年了。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。
第三方设备指标达到 GA
随着 Kubernetes 1.20 的发布,管理大规模 Kubernetes 集群的基础设施团队迎来了两个令人激动且期待已久的功能的正式发布。
- Pod Resources API(在 1.13 中引入)最终正式发布(GA)。这使得 Kubernetes 插件可以获取有关节点资源使用情况和分配的信息;例如:哪个 Pod/容器消耗了哪个设备。
DisableAcceleratorMetrics
功能(在 1.19 中引入)将升级为 Beta 版,并且默认启用。 这将移除 kubelet 报告的设备指标,转而使用新的插件架构。
许多与基本设备支持(设备发现、插件和监控)相关的功能已经达到了很高的稳定性。 Kubernetes 用户应该将这些功能视为实现更复杂用例(网络、调度、存储等)的基石!
一个这样的例子是非统一内存访问 (NUMA) 放置,在选择设备时,应用程序通常希望确保 CPU 内存和设备内存之间的数据传输尽可能快。在某些情况下,不正确的 NUMA 放置可能会抵消将计算卸载到外部设备的好处。
如果您对这些主题感兴趣,请考虑加入 Kubernetes Node 特别兴趣小组 (SIG),了解所有与 Kubernetes 节点相关的主题;加入 COD(容器编排设备)工作组,了解与运行时相关的主题;或者加入资源管理论坛,了解与资源管理相关的主题!
Pod Resources API - 为什么需要它?
Kubernetes 是一个供应商中立的平台。 如果我们希望它支持设备监控,那么在 Kubernetes 代码库中添加特定于供应商的代码并不是一个理想的解决方案。 最终,设备是一个需要深厚专业知识的领域,而添加和维护该领域代码的最佳人选是设备供应商本身。
Pod Resources API 是为了解决这个问题而构建的。 每个供应商都可以构建和维护自己的树外监控插件。 这个监控插件通常作为集群中的一个单独的 Pod 部署,然后可以将设备发出的指标与使用它的相关 Pod 关联起来。
例如,使用 NVIDIA GPU dcgm-exporter 来抓取 Prometheus 格式的指标
$ curl -sL http://127.0.01:8080/metrics
# HELP DCGM_FI_DEV_SM_CLOCK SM clock frequency (in MHz).
# TYPE DCGM_FI_DEV_SM_CLOCK gauge
# HELP DCGM_FI_DEV_MEM_CLOCK Memory clock frequency (in MHz).
# TYPE DCGM_FI_DEV_MEM_CLOCK gauge
# HELP DCGM_FI_DEV_MEMORY_TEMP Memory temperature (in C).
# TYPE DCGM_FI_DEV_MEMORY_TEMP gauge
...
DCGM_FI_DEV_SM_CLOCK{gpu="0", UUID="GPU-604ac76c-d9cf-fef3-62e9-d92044ab6e52",container="foo",namespace="bar",pod="baz"} 139
DCGM_FI_DEV_MEM_CLOCK{gpu="0", UUID="GPU-604ac76c-d9cf-fef3-62e9-d92044ab6e52",container="foo",namespace="bar",pod="baz"} 405
DCGM_FI_DEV_MEMORY_TEMP{gpu="0", UUID="GPU-604ac76c-d9cf-fef3-62e9-d92044ab6e52",container="foo",namespace="bar",pod="baz"} 9223372036854775794
每个代理都应遵守节点监控指南。 换句话说,插件应以 Prometheus 格式生成指标,并且新指标不应直接依赖于 Kubernetes 基础。
这允许指标的使用者使用兼容的监控管道来收集和分析来自各种代理的指标,即使它们由不同的供应商维护。
禁用 NVIDIA GPU 指标 - 警告
随着插件监控系统的正式发布,Kubernetes 正在弃用由 kubelet 报告的 NVIDIA GPU 指标。
由于 DisableAcceleratorMetrics 功能在 Kubernetes 1.20 中默认启用,NVIDIA GPU 在 Kubernetes 中不再是特殊的“公民”。 从供应商中立的角度来看,这是一件好事,它使最合适的人能够按照自己的发布计划维护他们的插件!
用户现在需要安装 NVIDIA GDGM exporter 或使用 bindings 来收集有关 NVIDIA GPU 的更准确和完整的指标。 这种弃用意味着您不能再依赖 kubelet 报告的指标,例如 container_accelerator_duty_cycle
或 container_accelerator_memory_used_bytes
,这些指标用于收集 NVIDIA GPU 内存利用率。
这意味着,过去依赖 kubelet 报告的 NVIDIA GPU 指标的用户,将需要更新其引用并部署 NVIDIA 插件。 具体来说,Kubernetes 报告的不同指标映射到以下指标
Kubernetes 指标 | NVIDIA dcgm-exporter 指标 |
---|---|
container_accelerator_duty_cycle | DCGM_FI_DEV_GPU_UTIL |
container_accelerator_memory_used_bytes | DCGM_FI_DEV_FB_USED |
container_accelerator_memory_total_bytes | DCGM_FI_DEV_FB_FREE + DCGM_FI_DEV_FB_USED |
您可能还对其他指标感兴趣,例如 DCGM_FI_DEV_GPU_TEMP
(GPU 温度)或 DCGM_FI_DEV_POWER_USAGE(功耗)。 默认集可在 Nvidia 的 数据中心 GPU 管理器文档中找到。
请注意,对于此版本,您仍然可以将 DisableAcceleratorMetrics
功能门设置为 _false_,从而有效地重新启用 kubelet 报告 NVIDIA GPU 指标的功能。
与 Pod Resources API 的正式发布相结合,这些工具可用于生成 GPU 遥测数据,这些数据可用于可视化仪表板,以下是一个示例
Pod Resources API - 我可以用它做什么?
一旦引入此接口,许多供应商就开始将其用于各种不同的用例! 列举几个例子
kuryr-kubernetes CNI 插件与 intel-sriov-device-plugin 结合使用。 这使得 CNI 插件可以知道 kubelet 进行了哪些 SR-IOV 虚拟功能 (VF) 分配,并使用该信息正确设置容器网络命名空间并使用具有适当 NUMA 节点的设备。 我们还希望使用此接口来跟踪已分配和可用的资源,以及有关工作节点 NUMA 拓扑的信息。
另一个用例是 GPU 遥测,其中 GPU 指标可以与分配给 GPU 的容器和 Pod 相关联。 一个这样的例子是 NVIDIA dcgm-exporter
,但其他例子也可以在相同的范例中轻松构建。
Pod Resources API 是一个简单的 gRPC 服务,它通知客户端 kubelet 知道的 Pod。 该信息涉及 kubelet 进行的设备分配和 CPU 分配。 这些信息分别从 kubelet 的设备管理器和 CPU 管理器的内部状态中获取。
您可以在下面看到 API 的示例,以及 go 客户端如何在几行代码中使用该信息
service PodResourcesLister {
rpc List(ListPodResourcesRequest) returns (ListPodResourcesResponse) {}
rpc GetAllocatableResources(AllocatableResourcesRequest) returns (AllocatableResourcesResponse) {}
// Kubernetes 1.21
rpc Watch(WatchPodResourcesRequest) returns (stream WatchPodResourcesResponse) {}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout)
defer cancel()
socket := "/var/lib/kubelet/pod-resources/kubelet.sock"
conn, err := grpc.DialContext(ctx, socket, grpc.WithInsecure(), grpc.WithBlock(),
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("unix", addr, timeout)
}),
)
if err != nil {
panic(err)
}
client := podresourcesapi.NewPodResourcesListerClient(conn)
resp, err := client.List(ctx, &podresourcesapi.ListPodResourcesRequest{})
if err != nil {
panic(err)
}
net.Printf("%+v\n", resp)
}
最后,请注意,您可以通过查看 kubelet 的 /metrics
端点上的新 kubelet 指标 pod_resources_endpoint_requests_total
来监视对 Pod Resources 端点发出的请求数量。
设备监控是否适合生产环境? 我可以扩展它吗? 我可以贡献代码吗?
是的! 此功能在 1.13 中发布,大约 2 年前,已被广泛采用,已被不同的云托管服务使用,并且随着其在 Kubernetes 1.20 中正式发布 (GA) 已准备好用于生产环境!
如果您是设备供应商,您可以立即开始使用它! 如果您只是想监控集群中的设备,请获取最新版本的监控插件!
如果您对该领域充满热情,请加入 Kubernetes 社区,帮助改进 API 或贡献设备监控插件!
致谢
我们感谢为该功能做出贡献或提供反馈的社区成员,包括 WG-Resource-Management、SIG-Node 和资源管理论坛的成员!