本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
第三方设备指标达到 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 资源 API - 为什么需要它?
Kubernetes 是一个与供应商无关的平台。如果我们要让它支持设备监控,在 Kubernetes 代码库中添加供应商特定的代码并不是一个理想的解决方案。归根结底,设备是一个需要深入专业知识的领域,在该领域添加和维护代码的最佳人选是设备供应商本身。
Pod 资源 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 报告的指标,例如用于收集 NVIDIA GPU 内存利用率的 container_accelerator_duty_cycle
或 container_accelerator_memory_used_bytes
。
这意味着以前依赖 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 资源 API 的毕业,这些工具可用于生成 GPU 遥测数据,可用于可视化仪表盘,示例如下
Pod 资源 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
端点上查看名为 pod_resources_endpoint_requests_total
的新 kubelet 指标来观察对 Pod Resources 端点发出的请求数量。
设备监控适合生产环境吗?我可以扩展它吗?我可以贡献吗?
是的!此功能于近两年前在 1.13 版本中发布,已被广泛采用,已用于各种云托管服务,并随着其在 Kubernetes 1.20 中毕业到 GA 阶段,已达到生产就绪水平!
如果您是设备供应商,您可以立即开始使用它!如果您只想监控集群中的设备,请获取最新版本的监控插件!
如果您对该领域充满热情,请加入 Kubernetes 社区,帮助改进 API 或贡献设备监控插件!
致谢
我们感谢为本功能做出贡献或提供反馈的社区成员,包括 WG-Resource-Management、SIG-Node 和资源管理论坛的成员!