本文已超过一年。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否已不再准确。
Kubernetes 1.28: Node podresources API 晋升至正式可用 (GA)
podresources API 是 kubelet 在节点本地提供的一个 API,它暴露了专门分配给容器的计算资源。随着 Kubernetes 1.28 版本的发布,该 API 现已正式发布(Generally Available)。
它解决了什么问题?
kubelet 可以为容器分配专属资源,例如 CPU,授予对完整核心的独占访问权限,或 内存,无论是区域还是大页。需要高性能或低延迟(或两者兼备)的工作负载会利用这些特性。kubelet 还可以将 设备分配给容器。总的来说,这些实现专属分配的功能被称为“资源管理器”。
如果没有 podresources 这样的 API,了解资源分配的唯一可能方式是读取资源管理器使用的状态文件。虽然这是出于必要而为之,但这种方法的问题在于,这些文件的路径和格式都是内部实现细节。尽管这些细节非常稳定,但项目保留了随意更改它们的权利。因此,消费状态文件内容的方法既脆弱又不被支持,建议正在这样做的项目考虑迁移到 podresources API 或其他受支持的 API。
API 概述
podresources API 最初被提议用于启用设备监控。为了启用监控代理,一个关键的前提是能够对设备分配进行自省(introspection),这由 kubelet 执行。满足这一目的是该 API 的最初目标。该 API 的第一个迭代版本只实现了一个函数,即 List
,用于返回有关设备分配给容器的信息。该 API 被 multus CNI 和 GPU 监控工具使用。
自诞生以来,podresources API 的范围有所增加,除了设备管理器外,还涵盖了其他资源管理器。从 Kubernetes 1.20 开始,List
API 也报告 CPU 核心和内存区域(包括大页);该 API 还报告设备的 NUMA 本地性(locality),而 CPU 和内存的本地性可以从系统中推断出来。
在 Kubernetes 1.21 中,该 API 增加了 GetAllocatableResources
函数。这个新的 API 补充了现有的 List
API,并使监控代理能够确定未分配的资源,从而支持基于 podresources API 构建的新功能,例如 NUMA 感知调度器插件。
最后,在 Kubernetes 1.27 中,引入了另一个函数 Get
,以便更友好地与 CNI meta-plugins 交互,从而更容易地访问分配给特定 Pod 的资源,而不必筛选节点上所有 Pod 的资源。Get
函数目前处于 Alpha 级别。
使用 API
podresources API 由 kubelet 在运行它的同一节点上本地提供服务。在 Unix 类系统上,端点通过 Unix 域套接字提供;默认路径是 /var/lib/kubelet/pod-resources/kubelet.sock
。在 Windows 上,端点通过命名管道提供;默认路径是 npipe://\\.\pipe\kubelet-pod-resources
。
为了让容器化的监控应用消费该 API,应将套接字挂载到容器内部。一个好的做法是挂载 podresources 套接字端点所在的目录,而不是直接挂载套接字文件。这将确保在 kubelet 重启后,容器化监控应用能够重新连接到套接字。
一个假设的监控代理消费 podresources API 并作为 DaemonSet 部署的示例清单如下:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: podresources-monitoring-app
namespace: monitoring
spec:
selector:
matchLabels:
name: podresources-monitoring
template:
metadata:
labels:
name: podresources-monitoring
spec:
containers:
- args:
- --podresources-socket=unix:///host-podresources/kubelet.sock
command:
- /bin/podresources-monitor
image: podresources-monitor:latest # just for an example
volumeMounts:
- mountPath: /host-podresources
name: host-podresources
serviceAccountName: podresources-monitor
volumes:
- hostPath:
path: /var/lib/kubelet/pod-resources
type: Directory
name: host-podresources
我希望您发现以编程方式使用 podresources API 很直接。kubelet API 包提供了协议文件和 Go 类型定义;然而,项目目前尚未提供客户端包,并且现有代码不应直接使用。建议 的方法是在您的项目中重新实现客户端,复制代码中的相关函数,例如 multus 项目正在这样做。
在操作消费 podresources API 的容器化监控应用时,有几点值得强调,以防止出现“陷阱”时刻:
- 即使该 API 按设计仅暴露数据,并且不允许客户端修改 kubelet 状态,但 gRPC 请求/响应模型要求对 podresources API 套接字具有读写访问权限。换句话说,不可能将容器挂载限制为
ReadOnly
。 - 允许多个客户端连接到 podresources 套接字并消费该 API,因为它是一个无状态的 API。
- kubelet 具有 内置的速率限制,以减轻来自行为不当或恶意消费者的本地拒绝服务攻击。API 的消费者必须容忍服务器返回的速率限制错误。目前的速率限制是硬编码且全局的,因此行为不当的客户端可能会消耗所有配额,并可能饿死正常行为的客户端。
未来增强功能
出于历史原因,podresources API 的规范不如典型的 Kubernetes API(例如 Kubernetes HTTP API 或容器运行时接口)精确。这导致在某些极端情况下行为不明确。目前正在 努力纠正这种状况,并制定更精确的规范。
动态资源分配 (DRA) 基础设施是对资源管理的重大改革。与 podresources API 的集成 正在进行中。
目前正在 努力 推荐或创建一个可供使用的参考客户端包。
参与其中
此功能由 SIG Node 推动。请加入我们,与社区联系,并分享您对上述功能及其他方面的想法和反馈。我们期待您的来信!