十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ray on Kubernetes 平台事件(Platform Events)接入指南:从 RBAC 配置到 Dashboard 可视化的完整实践

Ray on Kubernetes 平台事件(Platform Events)接入指南:从 RBAC 配置到 Dashboard 可视化的完整实践 Ray on Kubernetes 平台事件Platform Events接入指南从 RBAC 配置到 Dashboard 可视化的完整实践【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray导读本文基于 Ray 官方 Kubernetes 用户指南完整讲解如何在 Kubernetes 上启用 Ray Dashboard 的**平台事件Platform Events**功能通过 RBAC 授权与一个环境变量让 Ray 的 dashboard 后端实时监听 KubeRay 自定义资源RayCluster、RayJob、RayService以及 Pod 的生命周期事件并在 Dashboard 的Platform Events标签页中与应用的指标、日志并排展示。读完本文你将掌握完整的 RBAC 配置、环境变量注入、验证方法与故障排查手段并理解该功能在 Ray 源码中的底层实现原理事件监听、缓存与导出链路。一、什么是 Ray 平台事件平台事件是 Ray 观测体系中的一类特殊事件它把基础设施层的生命周期事件例如 Created RayCluster default/xxx、Created head Pod xxx纳入 Ray 的统一事件流。在 Kubernetes 上这些事件由 KubeRay 控制器rayjob-controller、raycluster-controller以及kubelet写入 Kubernetes 的 Event APIRay 的 dashboard 后端负责把它们拉取、解析并展示出来。其价值在于关联集群行为与应用行为当你的 Ray 应用出现异常时可以在 Dashboard 的 Platform Events 页中同时看到 Pod 被删除Worker 启动失败RayCluster 被创建 等基础设施事件与任务的日志、指标放在一起排查快速定位问题根因。从源码结构看该功能由 dashboard 的独立模块实现模块入口platform_event_head.py —— Dashboard Head 上的 REST 控制器与内存缓存对外提供统一查询 APIKubernetes 数据源k8s_provider.py —— 平台特定的事件监听 Provider前端查询封装platform.ts —— Dashboard 前端调用 API 的客户端。二、前置条件启用该功能前需要满足以下条件条件说明Ray 版本Ray 2.56.0 或更高版本Kubernetes Python 客户端需在 Ray head pod 的 Python 环境中安装kubernetes包pip install kubernetes。注意官方rayproject/ray镜像默认不包含该依赖必须自行安装Kubernetes 集群一个可部署 Ray 工作负载的集群head pod 内可访问 Kubernetes API默认通过 in-cluster config 加载从源码看k8s_provider.py 对kubernetes依赖做了软依赖处理导入失败时 Provider 相关变量置为None此时日志会提示 Kubernetes dependencies not found. Kubernetes events will be disabled.功能静默降级而不是崩溃。三、配置 RBAC 权限Ray head pod 需要调用 Kubernetes API 来监听事件因此必须先为其授予对应权限。创建一个名为ray-rbac.yaml的文件apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: ray-head-watch-role rules: - apiGroups: [] resources: [events] verbs: [get, list, watch] - apiGroups: [ray.io] resources: [rayclusters] verbs: [get] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: ray-head-watch-role-binding subjects: - kind: ServiceAccount name: default # IMPORTANT: Change this if your Ray Head Pod uses a different ServiceAccount namespace: default # IMPORTANT: Change this to the namespace where your Ray cluster runs roleRef: kind: Role name: ray-head-watch-role apiGroup: rbac.authorization.k8s.io将其应用到 Ray 集群所在的命名空间kubectl apply -f ray-rbac.yaml -n your-ray-namespace该 Role 授予两类权限缺一不可eventsget/list/watch核心权限用于流式读取 Kubernetes 事件rayclustersget用于让 dashboard 找到RayJob或RayService等父资源进而监听它们的事件。从源码看k8s_provider.py 会通过 CustomObjectsApi 读取ray.io/v1组的rayclusters自定义资源解析其ownerReferences来发现父级RayJob/RayService的名称。四、启用平台事件在 Ray head pod 容器上设置环境变量RAY_DASHBOARD_INGEST_PLATFORM_EVENTS为trueenv: - name: RAY_DASHBOARD_INGEST_PLATFORM_EVENTS value: true该环境变量用于启动 dashboard 后端的平台事件监听器watcher。从 platform_event_head.py 的实现看PlatformEventsHead.is_enabled()读取该变量取值为true或1不区分大小写时启用未设置时默认值为False模块会被整体跳过并打印日志。非 KubeRay 部署Ray 2.58额外注入如果使用 KubeRay 部署KubeRay Operator 会自动向 RayCluster 的 Pod 注入RAY_CLUSTER_NAME与RAY_CLUSTER_NAMESPACE两个环境变量。但如果你不使用 KubeRay、直接手工部署 Ray 到 Kubernetes则需要手动注入这两个变量否则 Dashboard 无法展示 Kubernetes Pod 事件env: - name: RAY_CLUSTER_NAME value: your-ray-cluster-name # Must match the target Ray cluster name - name: RAY_CLUSTER_NAMESPACE value: your-namespace # Must match the target namespace从源码看k8s_provider.py 的客户端初始化逻辑会强制校验这两个变量缺少任意一个都会返回失败并打印 RAY_CLUSTER_NAME not found. Kubernetes events will not be available. 之类的告警。同时platform_event_head.py 通过检测KUBERNETES_SERVICE_HOST环境变量来判定当前是否运行在 Kubernetes 平台内只有检测到才会初始化 Kubernetes Provider。五、完整部署示例KubeRay 仓库中提供了可直接运行的完整示例清单文件名分别为ray-cluster.platform-events.yaml与ray-job.platform-events.yaml位于 KubeRay 的ray-operator/config/samples/目录下# RayCluster 示例 kubectl apply -f ray-cluster.platform-events.yaml 的完整地址 # RayJob 示例 kubectl apply -f ray-job.platform-events.yaml 的完整地址这两个示例清单已包含上述全部配置RBAC、RAY_DASHBOARD_INGEST_PLATFORM_EVENTStrue环境变量等适合作为部署的起点模板示例完整内容以 KubeRay 仓库实际文件为准。六、验证配置是否生效完成部署后按以下步骤验证平台事件是否真正进入 Ray Dashboard。1. 端口转发 Dashboard# 找到你的 Ray head pod kubectl get pods -n your-ray-namespace | grep head # 端口转发 kubectl port-forward head-pod-name -n your-ray-namespace 8265:82652. 查询 API可选但推荐调用/api/v0/platform_events端点确认 Ray 已收集到事件curl http://localhost:8265/api/v0/platform_events成功时返回一个包含近期事件的 JSON 对象以下为真实响应示例字段完整保留{ result: true, msg: Retrieved platform events, data: { events: [ { eventId: Y2JiMzkxMWQtM2YxZS00YzAwLWFmYWMtN2IxNGU1ZjgwZDZk, sourceType: CLUSTER_LIFECYCLE, eventType: PLATFORM_EVENT, timestamp: 2026-06-16T21:49:08Z, severity: INFO, message: Created RayCluster default/rayjob-test-f52vq, platformEvent: { source: { platform: KUBERNETES, component: rayjob-controller, metadata: { namespace: default, rayClusterName: rayjob-test-f52vq } }, objectKind: RayJob, objectName: rayjob-test, message: Created RayCluster default/rayjob-test-f52vq, reason: CreatedRayCluster, customFields: {} }, sessionName: , nodeId: }, { eventId: MDk1MmYxNzUtY2I3MC00NDU3LWExNzktMTBkYjYwZGZkMDA0, sourceType: CLUSTER_LIFECYCLE, eventType: PLATFORM_EVENT, timestamp: 2026-06-16T21:49:08Z, severity: INFO, message: Created service default/rayjob-test-f52vq-head-svc, platformEvent: { source: { platform: KUBERNETES, component: raycluster-controller, metadata: { namespace: default, rayClusterName: rayjob-test-f52vq } }, objectKind: RayCluster, objectName: rayjob-test-f52vq, message: Created service default/rayjob-test-f52vq-head-svc, reason: CreatedService, customFields: {} }, sessionName: , nodeId: }, { eventId: YTEzMWM1MDQtNWMyNS00NGFkLTkwMmMtNTlmOTQ0ZDFlOGNi, sourceType: CLUSTER_LIFECYCLE, eventType: PLATFORM_EVENT, timestamp: 2026-06-16T21:49:08Z, severity: INFO, message: Created head Pod default/rayjob-test-f52vq-head-vmlwz, platformEvent: { source: { platform: KUBERNETES, component: raycluster-controller, metadata: { namespace: default, rayClusterName: rayjob-test-f52vq } }, objectKind: RayCluster, objectName: rayjob-test-f52vq, message: Created head Pod default/rayjob-test-f52vq-head-vmlwz, reason: CreatedHeadPod, customFields: {} }, sessionName: , nodeId: }, { eventId: NWRhNjhmNmEtYjFhMi00MWZiLWE0YWQtN2IwNjIyNmM1YjAw, sourceType: CLUSTER_LIFECYCLE, eventType: PLATFORM_EVENT, timestamp: 2026-06-16T21:49:08Z, severity: INFO, message: Created worker Pod default/rayjob-test-f52vq-small-group-worker-j7gtf, platformEvent: { source: { platform: KUBERNETES, component: raycluster-controller, metadata: { namespace: default, rayClusterName: rayjob-test-f52vq } }, objectKind: RayCluster, objectName: rayjob-test-f52vq, message: Created worker Pod default/rayjob-test-f52vq-small-group-worker-j7gtf, reason: CreatedWorkerPod, customFields: {} }, sessionName: , nodeId: } ] } }3. 查看 Dashboard浏览器打开http://localhost:8265在顶部导航栏找到Platform Events标签页Dashboard 会以表格形式展示事件列包含时间、严重级别、来源、对象、原因、消息见本文开头的界面截图。七、底层原理事件从 Kubernetes 到 Dashboard 的完整链路理解源码有助于排障与调优。整个链路分为五个环节平台检测与客户端初始化PlatformEventsHead.run()检测KUBERNETES_SERVICE_HOST后实例化KubernetesEventProviderProvider 的_init_k8s_client()优先使用load_incluster_config()Pod 内运行时失败后回退到load_kube_config()本地开发并校验RAY_CLUSTER_NAME/RAY_CLUSTER_NAMESPACE。目标发现Provider 通过 CustomObjectsApi 读取ray.io/v1的rayclusters对象从ownerReferences中发现父级RayJob/RayService从而确定需要监听的目标列表[(RayCluster, name), (RayJob, name), (RayService, name)]k8s_provider.py。多路事件监听每个目标启动一个独立的守护线程通过watch.Watch()配合field_selectorinvolvedObject.kindX,involvedObject.nameY精确监听该对象的事件k8s_provider.py。从 Ray 2.58 起额外增加两类监听Pod 成员关系监听按ray.io/clustercluster_name标签维护本集群 Pod 名称集合Pod 事件监听Kubernetes 字段选择器不支持按多个 Pod 名称做集合过滤因此 Provider 打开一条involvedObject.kindPod的命名空间级监听在客户端按成员集合过滤k8s_provider.py并通过带上限默认 1024 条FIFO 淘汰的非本集群 Pod 缓存控制内存占用。事件解析与去重缓存原始 K8s 事件被解析为统一的RayEventprotobufevent_typePLATFORM_EVENT、source_typeCLUSTER_LIFECYCLE、severity由 K8s 事件类型映射Warning→ WARNING其余 → INFOevents.k8s.io/v1写入的事件会回退读取reportingComponent作为组件名count 1时写入customFields[count]k8s_provider.py。随后事件进入 head 模块的内存缓存platform_event_head.py以eventId即 K8s 事件 UID去重容量上限为MAX_EVENTS_TO_CACHE 1000条超出后淘汰最旧的。对外提供GET /api/v0/platform_events按时间戳倒序返回缓存事件platform_event_head.pyDashboard 前端 platform.ts 拉取并渲染到 Platform Events 标签页。该链路的行为均有单元测试覆盖例如 test_k8s_provider.py 验证了事件类型/来源类型映射、Kubernetes 平台标记、组件名回退等逻辑test_platform_event_head.py 验证了 head 模块的启用判断与 API 行为。八、故障排查与注意事项版本行为差异重要在Ray 2.56 与 2.57中本功能只跟踪 KubeRay 自定义资源RayCluster、RayJob、RayService的事件。从Ray 2.58开始覆盖范围扩展到通用的 KubernetesPod 级事件。对于非 KubeRay 部署请务必在 head pod 上手动设置RAY_CLUSTER_NAME与RAY_CLUSTER_NAMESPACE否则 Pod 事件不会出现在 Dashboard 中。RBAC 权限不足的典型现象如果 ServiceAccount 缺少ray.ioAPI 组中rayclusters的get权限Ray 就无法将事件关联到父级RayJob或RayService资源此时 Dashboard 只能展示直接针对 RayCluster 本身的事件。请核对 Role 中是否同时包含上文的两条规则。常见排查清单确认环境变量已注入 head podkubectl exec head-pod -- env | grep RAY_DASHBOARD确认RAY_DASHBOARD_INGEST_PLATFORM_EVENTStrue生效确认kubernetes包已安装在 head pod 内执行pip show kubernetes缺失时该功能会被静默禁用查看 head 日志模块启动、Provider 初始化、watch 中断如 resource version 过期 410 后自动重建流等关键节点均有对应日志可直接定位问题确认命名空间与集群名匹配RAY_CLUSTER_NAME/RAY_CLUSTER_NAMESPACE必须与实际部署一致。九、将平台事件导出到外部系统默认情况下Ray 以事件类型PLATFORM_EVENT将平台事件送入自身的可观测系统One-Event Framework。如果需要转发到外部日志或监控系统可做两件事设置自定义事件导出地址通过环境变量RAY_DASHBOARD_AGGREGATOR_AGENT_EVENTS_EXPORT_ADDR指定导出的目标地址该变量在 aggregator_agent.py 中默认值为空字符串为空即不启用外部导出具体导出协议与配置详见仓库文档 Ray Event Export。确保事件类型过滤器包含PLATFORM_EVENT若你通过RAY_ENABLE_PYTHON_RAY_EVENT_TYPES过滤事件类型必须把PLATFORM_EVENT加入列表例如RAY_ENABLE_PYTHON_RAY_EVENT_TYPESPLATFORM_EVENT,SYSTEM_EVENT从 ray_constants.py 的实现看该变量是逗号分隔的事件类型集合默认值就是PLATFORM_EVENT——也就是说只要你不显式设置它平台事件就会被包含但一旦你设置了该变量并遗漏了PLATFORM_EVENT平台事件便不会被导出这一点在排查外部导出问题时需要特别留意。十、总结启用 Ray 平台事件只需三步装好kubernetes依赖 → 授予events与rayclusters的 RBAC 权限 → 在 head pod 设置RAY_DASHBOARD_INGEST_PLATFORM_EVENTStrue非 KubeRay 部署还需手动注入集群名与命名空间。验证时可依次检查 Dashboard 的 Platform Events 标签页与/api/v0/platform_eventsAPI。理解 head 模块与 Provider 的源码实现后你还能对 watch 断线重连、事件缓存上限1000 条、Pod 成员过滤、外部事件导出等行为做到心中有数从而在生产环境稳定地使用这一观测能力。【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表