本文发布时间已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已不正确。
Kubernetes 1.28:节点 podresources API 升级至 GA
podresources API 是 kubelet 在节点本地提供的 API,它公开了专门分配给容器的计算资源。随着 Kubernetes 1.28 的发布,该 API 现已正式发布。
它解决了什么问题?
kubelet 可以为容器分配独占资源,例如CPU,授予对完整内核的独占访问权或内存,包括区域或大页面。需要高性能或低延迟(或两者兼而有之)的工作负载会利用这些功能。kubelet 还可以将设备分配给容器。总的来说,这些支持独占分配的功能被称为“资源管理器”。
如果没有像 podresources 这样的 API,了解资源分配的唯一可能方法是读取资源管理器使用的状态文件。虽然这是出于必要性而做的,但这种方法的问题是这些文件的路径和格式都是内部实现细节。尽管非常稳定,但该项目保留自由更改它们的权利。因此,使用状态文件的内容是脆弱且不受支持的,建议这样做项目考虑迁移到 podresources API 或其他受支持的 API。
API 概述
podresources API 最初被提出用于启用设备监控。为了启用监控代理,一个关键的先决条件是启用对设备分配的内省,这由 kubelet 执行。服务此目的是该 API 的最初目标。API 的第一个迭代只实现了一个函数 List
,用于返回有关设备分配给容器的信息。该 API 被 multus CNI 和 GPU 监控工具使用。
自创建以来,podresources API 扩大了其范围,以涵盖设备管理器以外的其他资源管理器。从 Kubernetes 1.20 开始,List
API 还报告 CPU 内核和内存区域(包括大页面);API 还报告设备的 NUMA 局部性,而 CPU 和内存的局部性可以从系统中推断出来。
在 Kubernetes 1.21 中,API 获得了 GetAllocatableResources
函数。这个较新的 API 补充了现有的 List
API,使监控代理能够确定未分配的资源,从而启用基于 podresources API 构建的新功能,例如NUMA 感知调度器插件。
最后,在 Kubernetes 1.27 中,引入了另一个函数 Get
,以便对 CNI 元插件更加友好,从而简化对分配给特定 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 的容器化监控应用程序时,有几点值得强调以防止出现“gotcha”时刻
- 尽管 API 只公开数据,并且在设计上不允许客户端改变 kubelet 状态,但 gRPC 请求/响应模型需要对 podresources API 套接字进行读写访问。换句话说,不可能将容器挂载限制为
ReadOnly
。 - 允许多个客户端连接到 podresources 套接字并使用 API,因为它是无状态的。
- kubelet 具有内置的速率限制,以缓解来自行为不端或恶意使用者的本地拒绝服务攻击。API 的使用者必须容忍服务器返回的速率限制错误。速率限制当前是硬编码的且全局的,因此行为不端的客户端可能会消耗所有配额,并可能使行为正确的客户端无法正常工作。
未来的增强功能
由于历史原因,podresources API 的规范不如典型的 Kubernetes API(例如 Kubernetes HTTP API 或容器运行时接口)精确。这会导致在极端情况下出现未指定的行为。正在努力纠正这种状态并使其具有更精确的规范。
动态资源分配 (DRA) 基础设施是对资源管理的重大改造。与 podresources API 的集成已经在进行中。
正在努力推荐或创建一个随时可用的参考客户端包。
参与其中
此功能由 SIG Node 驱动。请加入我们,与社区联系,并分享您对上述功能及其他方面的想法和反馈。我们期待您的来信!