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

资讯详情

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

Feast Operator Namespace Registry:跨命名空间的 Feast 实例自动发现与集中注册机制

Feast Operator Namespace Registry:跨命名空间的 Feast 实例自动发现与集中注册机制 Feast Operator Namespace Registry跨命名空间的 Feast 实例自动发现与集中注册机制【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feastFeast Operator 的 Namespace Registry 特性会自动创建并维护一个集中式 ConfigMap登记集群中所有由 Operator 部署的 Feast 特征存储实例使 Dashboard 等外部应用能够跨命名空间发现并连接这些实例。本文基于 Feast 仓库中 namespace-registry.md 文档展开并结合 namespace_registry.go 与 featurestore_controller.go 的源码实现完整讲解其配置项、RBAC 访问控制、注册/清理生命周期以及如何用 kubectl 读取注册数据。读完本文你将掌握Namespace Registry 的 ConfigMap 位置、数据格式与命名规则feast-configs-registryKubernetes 下位于feast-operator-system命名空间实例自动注册与删除清理的完整触发链路从 Reconcile 主流程到AddToNamespaceRegistry/RemoveFromNamespaceRegistryOperator 为读取权限创建的 Role/RoleBinding 规则细节以及外部应用如何消费该注册表。1. 功能定位为什么需要 Namespace Registry在多团队、多命名空间部署 Feast 的场景中每个 FeatureStore 自定义资源CR各自独立地部署在线/离线/Registry 服务与客户端配置。仪表盘或工具类应用若要枚举“集群里都有哪些 Feast 实例、每个实例的客户端配置client config叫什么”就需要一个全局可查的索引。Namespace Registry 就是这样一个索引当任意一个 Feast 实例被创建时Operator 自动在约定命名空间中创建/更新一个 ConfigMap该实例把自己的命名空间与客户端配置名写入 ConfigMap实例被删除时其条目自动移除无需任何额外配置——文档明确说明“The namespace registry is automatically deployed when any Feast feature store instance is created. No additional configuration is required.”相关实现集中在 namespace_registry.go核心常量定义在 services_types.go// Namespace registry ConfigMap constants NamespaceRegistryConfigMapName feast-configs-registry NamespaceRegistryDataKey namespaces DefaultKubernetesNamespace feast-operator-system2. ConfigMap 的创建位置平台相关的目标命名空间文档给出的位置规则是平台目标命名空间OpenShift AIredhat-ods-applications命名空间或 DSCi 配置的命名空间Kubernetesfeast-operator-system命名空间从源码结构看目标命名空间由getNamespaceRegistryNamespace()决定见 namespace_registry.go#L225-L243当 Operator 运行在 OpenShift 上isOpenShift为真时代码读取 Operator 自身 ServiceAccount 的命名空间文件/var/run/secrets/kubernetes.io/serviceaccount/namespace即以 Operator 实际运行的命名空间为准源码中还留有TODO: Add support for reading DSCi configuration注释说明 DSCi 配置的命名空间读取尚未完整实现其他原生 Kubernetes情况则固定返回DefaultKubernetesNamespace即feast-operator-system。值得注意的容错设计如果无法确定目标命名空间deployNamespaceRegistry()会记录日志并直接返回nilnamespace_registry.go#L46-L61即跳过注册表部署而不让整个 Feast 实例的部署失败——注册表属于“尽力而为”的附属能力不阻断主流程。此外被标记为受保护项目CR 上带有feast.dev/protected-project: true注解常量ProtectedProjectAnnotation见 services_types.go#L51-L57的实例会整体跳过注册表isProtectedProject()检查该注解deployNamespaceRegistry、AddToNamespaceRegistry均对其提前返回。注释说明这是为了防止外部管理的受保护项目暴露给其他实例。创建动作本身使用controllerutil.CreateOrUpdate实现幂等调和createNamespaceRegistryConfigMap()namespace_registry.go#L76-L96无论 ConfigMap 是否已存在都会执行setNamespaceRegistryConfigMap()重新计算数据并写回因此重复 Reconcile 不会产生脏数据。3. ConfigMap 的数据结构注册表 ConfigMap名为feast-configs-registry中保存的数据键为namespaces即NamespaceRegistryDataKey其值是一个 JSON 字符串结构为“命名空间名 → 客户端配置名列表”{ namespaces: { namespace-1: [client-config-1, client-config-2], namespace-2: [client-config-3] } }对应的 Go 结构体非常简洁namespace_registry.go#L34-L37// NamespaceRegistryData represents the structure of data stored in the namespace registry ConfigMap type NamespaceRegistryData struct { Namespaces map[string][]string json:namespaces }其中两个键值来源见setNamespaceRegistryConfigMap()与AddToNamespaceRegistry()命名空间键FeatureStore CR 所在命名空间feast.Handler.FeatureStore.Namespace配置名值Status.ClientConfigMap字段的值featurestore_types.go#L1104。该字段由客户端 ConfigMap 的调和过程写入——client.go#L48-L56 中setClientConfigMap将cm.Name赋值给Status.ClientConfigMap而客户端 ConfigMap 内包含该实例专属的feature_store.yaml客户端配置FeatureStoreYamlCmKey。注册时具有幂等性写入前会遍历现有列表检查该 client config 是否已存在found标志不存在才append避免重复条目。读取现有数据时若 JSON 反序列化失败实现会选择“从空数据重新开始”而不是报错失败保证容错。4. 访问控制让已认证用户可读取注册表文档第 2 点指出Operator 会创建一个 RoleBinding允许system:authenticated用户读取该 ConfigMap。实现细节在createNamespaceRegistryRoleBinding()与setNamespaceRegistryRoleBinding()namespace_registry.go#L156-L223它实际创建两个对象Rolefeast-configs-registry-reader规则精确限定到单个资源名desiredRules : []rbacv1.PolicyRule{ { APIGroups: []string{}, Resources: []string{configmaps}, ResourceNames: []string{NamespaceRegistryConfigMapName}, // 仅 feast-configs-registry Verbs: []string{get, list}, }, }即仅授予对feast-configs-registry这一个 ConfigMap 的get/list权限不开放写权限也不波及其他 ConfigMap。RoleBindingfeast-configs-registry-reader主体Subject为组system:authenticatedrb.Subjects []rbacv1.Subject{ { APIGroup: rbac.authorization.k8s.io, Kind: Group, Name: system:authenticated, }, }system:authenticated是 Kubernetes/OpenShift 中所有通过身份认证用户的内置组因此任何已登录用户无论是否属于该 Feast 项目都能读取注册表——这是“实例发现”语义的设计选择知道有哪些实例是公开信息连接细节仍由各自的客户端配置控制。5. 自动注册与清理完整生命周期文档“Lifecycle Management”一节列出的四个阶段在源码中对应如下调用链5.1 创建/更新部署成功后注册featurestore_controller.go 的Reconcile主流程中在deployFeast成功且 CR 未被删除后执行注册// Add to namespace registry and OpenLineage discovery if deployment was successful if recErr nil cr.DeletionTimestamp nil { feast : services.FeastServices{...} if err : feast.AddToNamespaceRegistry(); err ! nil { logger.Error(err, Failed to add FeatureStore to namespace registry) } ... }即只有部署成功才注册注册失败仅记录错误日志不导致 Reconcile 失败。同时deployFeast内部services.go#L151也会先调用deployNamespaceRegistry()确保 ConfigMap 与 RBAC 对象就位。这解释了文档中“更新时条目保留”的行为——每次 Reconcile 都会幂等地重新写入实例更新如镜像升级不会丢失条目。AddToNamespaceRegistry()的逻辑namespace_registry.go#L245-L334受保护项目直接跳过若目标 ConfigMap 尚不存在IsNotFound记录日志并返回等待下一轮 Reconcile解析现有 JSON把Status.ClientConfigMap去重后追加到对应命名空间列表Update写回。5.2 删除两个清理入口删除路径有两个触发点featurestore_controller.go#L100-L142CR 已不存在IsNotFound即请求入队后资源已被删除时构造一个仅含 Name/Namespace 的deletedCR并调用cleanupNamespaceRegistryCR 带有DeletionTimestamp正在删除时直接以该 CR 调用cleanupNamespaceRegistry。RemoveFromNamespaceRegistry()namespace_registry.go#L336-L448的执行逻辑计算expectedClientConfigName : feast- featureStoreName -client——这是客户端 ConfigMap 的标准命名模式遍历该实例所在命名空间下的配置列表凡与Status.ClientConfigMap或expectedClientConfigName匹配的条目均移除。之所以匹配两种形态是因为删除场景下 CR 的 Status 可能已经丢失此时只能靠命名约定兜底命名空间清理若移除后该命名空间列表为空则执行delete(existingData.Namespaces, featureStoreNamespace)删除整个命名空间键——这正是文档中“Namespace Cleanup当一个命名空间内所有特征存储都被删除命名空间条目也随之移除”的实现序列化后Update写回。5.3 测试佐证端到端行为由 featurestore_controller_namespace_registry_test.go 用 Ginkgo/Gomega 验证覆盖四个场景Reconcile 后在feast-operator-system命名空间中feast-configs-registryConfigMap 应存在L94-L114feast-configs-registry-readerRole 与 RoleBinding 应存在L116-L145实例应以其Status.ClientConfigMap登记在自身命名空间下L147-L221删除 FeatureStore 并再次 Reconcile 后feast-name-client条目应被清除L223-L318。同文件后半部分还包含纯数据操作的单元测试L321-L452验证NamespaceRegistryData的 JSON 往返序列化、空数据处理、单条配置移除不影响其他命名空间、以及“最后一个配置被移除时整个命名空间条目被删除”的规则——与生产实现的行为一一对应。6. 外部应用如何消费注册表外部应用如 Dashboard只需读取该 ConfigMap 即可枚举集群中的 Feast 实例。文档给出的命令此处原样保留按平台选择命名空间# For OpenShift kubectl get configmap feast-configs-registry -n redhat-ods-applications -o jsonpath{.data.namespaces} # For Kubernetes kubectl get configmap feast-configs-registry -n feast-operator-system -o jsonpath{.data.namespaces}返回内容即{namespace-1:[client-config-1,...], ...}的 JSON。拿到每个命名空间下的客户端配置名后应用可进一步读取对应命名空间中该名字的 ConfigMap其中含feature_store.yaml客户端配置参见 client.go#L48-L56从而获得连接各实例所需的服务地址等信息。由于 Role 将get/list开放给了system:authenticated任何已认证用户或 Pod 内的已认证身份均可直接读取无需额外授权。7. 关键事实速查项目值出处注册表 ConfigMap 名feast-configs-registryservices_types.go#L41数据键namespacesJSON 字符串services_types.go#L42Kubernetes 目标命名空间feast-operator-systemservices_types.go#L43OpenShift 目标命名空间redhat-ods-applications文档代码实际取 Operator 自身 SA 命名空间namespace-registry.md、namespace_registry.go#L225-L243读取权限主体组system:authenticatedget、list仅限该 ConfigMapnamespace_registry.go#L178-L223客户端配置命名模式feast-featurestore-name-clientnamespace_registry.go#L381排除机制CR 注解feast.dev/protected-project: trueservices_types.go#L578. 小结Namespace Registry 是 Feast Operator 面向多租户/多命名空间部署提供的实例发现机制它零配置生效通过一个集中 ConfigMapfeast-configs-registry以“命名空间 → 客户端配置列表”的 JSON 结构维护集群内全部 Feast 实例索引并配套最小权限的 RBACsystem:authenticated只读。其注册发生在部署成功的 Reconcile 末尾清理发生在删除路径的两处入口命名空间级条目在最后一个实例移除后自动消失。对于需要构建 Feast 集群级 Dashboard 或治理工具的开发团队理解 namespace_registry.go 的注册/清理语义与 featurestore_controller_namespace_registry_test.go 中的断言即可准确预测该机制在任何部署/删除操作后的最终状态。【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表