第三方设备指标达到GA

作者: Renaud Gaubert(NVIDIA),David Ashpole(Google)和Pramod Ramarao(NVIDIA)

使用Kubernetes 1.20,管理大规模Kubernetes集群的基础架构团队看到了两个令人兴奋且期待已久的功能的毕业:

  • Pod Resources API(在1.13版中引入)最终将向GA毕业。这使Kubernetes插件可以获取有关节点资源使用和分配的信息;例如:哪个容器/容器消耗哪个设备。
  • DisableAcceleratorMetrics feature (introduced in 1.19) is graduating 至 beta and will be enabled by default. This removes device metrics reported by the kubelet in favor of the new plugin architecture.

与基本设备支持有关的许多功能(设备发现,插件和监视)都达到了很高的稳定性。 Kubernetes用户应该将这些功能视为踏脚石,以启用更复杂的用例(网络,调度,存储等)!

一个这样的例子是非均匀存储器访问(NUMA)放置,其中,选择一个装置时,应用程序通常要确保CPU存储器和设备存储器之间的数据传输是尽可能地快。在某些情况下,错误的NUMA放置可能会使将计算卸载到外部设备的好处无效。

如果您感兴趣这些主题,请考虑加入 Kubernetes节点特别Insterest组 (SIG),用于与Kubernetes节点相关的所有主题,针对与运行时相关的主题的COD(容器编排设备)工作组,或针对与资源管理相关的主题的资源管理论坛!

Pod资源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导出器 或使用 绑定 至 gather more accurate and complete metrics about NVIDIA GPUs. This deprecation means that you can no longer rely on metrics that were reported by kubelet, such as container_accelerator_duty_cycle or container_accelerator_memory_used_bytes which were used 至 gather NVIDIA GPU memory utilization.

这意味着过去依靠kubelet报告的NVIDIA GPU指标的用户将需要更新其参考并部署NVIDIA插件。即Kubernetes报告的不同指标映射到以下指标:

Kubernetes指标NVIDIA dcgm-exporter指标
container_accelerator_duty_cycleDCGM_FI_DEV_GPU_UTIL
container_accelerator_memory_used_bytesDCGM_FI_DEV_FB_USED
container_accelerator_memory_total_bytesDCGM_FI_DEV_FB_FREE + DCGM_FI_DEV_FB_USED

You might also be interested in other metrics such as DCGM_FI_DEV_GPU_TEMP (the GPU temperature) or DCGM_FI_DEV_POWER_USAGE (the power usage). 的 默认设置 在Nvidia的 数据中心GPU Manager文档.

请注意,对于此版本,您仍然可以设置 DisableAcceleratorMetrics 功能门,有效地使kubelet能够报告NVIDIA GPU指标。

结合Pod Resources API的毕业设计,这些工具可用于生成GPU遥测 可以在可视化仪表板中使用,下面是一个示例:

设备指标的Grafana可视化

Pod资源API-我该怎么办?

引入此接口后,许多供应商开始将其用于各种不同的用例!列举一些例子:

库里尔·库伯内特斯 与CNI插件串联 英特尔-sriov设备插件。这使CNI插件可以知道kubelet进行了SR-IOV虚拟功能(VF)的分配,并使用该信息正确设置了容器网络名称空间,并使用具有适当NUMA节点的设备。我们还希望该接口可用于跟踪有关工作节点NUMA拓扑的信息的分配和可用资源。

Another use-case is GPU telemetry, where GPU metrics can be associated with the containers and pods that the GPU is assigned 至 . One such example is the NVIDIA dcgm-exporter, but others can be easily built in the same paradigm.

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)
}

Finally, note that you can watch the number of requests made 至 the Pod Resources endpoint by watching the new kubelet metric called pod_resources_endpoint_requests_total on the kubelet's /metrics endpoint.

设备监控是否适合生产?我可以扩展吗?我可以捐款吗?

是!该功能在将近2年前于1.13中发布,现已得到广泛采用,已被其他云托管服务所使用,随着它在Kubernetes 1.20中升级为G.A,就可以投入生产了!

如果您是设备供应商,则可以立即开始使用它!如果您只想监视群集中的设备,请获取最新版本的监视插件!

如果您对该领域充满热情,请加入kubernetes社区,帮助改进API或贡献设备监视插件!

致谢

我们感谢对该功能做出贡献或给予反馈的社区成员,包括WG-Resource-Management,SIG-Node和Resource Management论坛的成员!