news 2026/9/29 2:28:17

CAP Dashboard 的 Kubernetes 服务发现配置指南:节点切换、RBAC 权限与标签过滤

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CAP Dashboard 的 Kubernetes 服务发现配置指南:节点切换、RBAC 权限与标签过滤
  • 后端
  • 消息队列
  • 微服务
  • 消息路由

【免费下载链接】CAP

Distributed transaction solution in micro-service base on eventually consistency, also an eventbus with Outbox pattern

项目地址:https://gitcode.com/gh_mirrors/ca/CAP
点击查看免费下载

本文围绕 CAP(基于 Outbox 模式的分布式事务与事件总线框架)Dashboard 的 Kubernetes(K8s)服务发现能力展开,讲解如何通过UseK8sDiscovery()让 Dashboard 自动发现集群内各 CAP 服务节点、授予 Pod 访问 Kubernetes API 所需的 RBAC 权限、使用标签控制节点可见性与端口选择,以及如何将 Dashboard 作为独立 Pod 部署。读完本文,你将掌握一套可直接落地的 K8s 环境下 CAP Dashboard 多节点数据查看的完整配置方案。

背景:为什么需要 Kubernetes 服务发现

CAP Dashboard 默认只能查看当前进程所在节点的发布/订阅消息数据。在多副本、多节点部署的微服务架构中,运维与排查人员往往需要跨节点查看数据。自 CAP 7.2.0 起,Dashboard 内置了基于 Kubernetes 的服务发现机制:进入 Dashboard 的Nodes页面,选择命名空间后,CAP 会调用 Kubernetes API 列出该命名空间下的所有 Service;点击Switch(切换)按钮后,Dashboard 会先探测目标节点上的 CAP 服务是否可用,可用则通过网关代理切换到该节点查看其数据。

这一能力对应的实现位于仓库 DotNetCore.CAP.Dashboard.K8s 项目中,其核心是K8sNodeDiscoveryProvider,它实现统一的服务发现接口 INodeDiscoveryProvider,提供GetNodes、GetNamespaces、ListServices等能力,供 Dashboard 的 Nodes 页面消费。

快速开始:启用 K8s 服务发现

在配置 CAP 时同时调用UseDashboard()与UseK8sDiscovery()即可启用:

services.AddCap(x => { // ... 其他 CAP 配置(如消息存储、传输) x.UseDashboard(); x.UseK8sDiscovery(); });

UseK8sDiscovery()是无参重载,对应源码见 K8sDiscoveryOptionsExtensions.cs,其内部会注册K8sDiscoveryOptions为单例,并注册GatewayProxyAgent、IHttpRequester、IHttpClientCache、IRequestMapper以及INodeDiscoveryProvider(实现为K8sNodeDiscoveryProvider),从而打通“发现节点 → 代理请求”的完整链路。

启用后,Dashboard 会尝试自动检测自身是否运行在 Kubernetes 集群内部(通过默认的KubernetesClientConfiguration.BuildDefaultConfig()加载集群内配置,见 K8sDiscoveryOptions.cs)。如果运行在集群内部,则必须为 Pod 授予 Kubernetes API 访问权限,否则节点列表无法加载。

ShowOnlyExplicitVisibleNodes:默认是否列出所有 Service

ShowOnlyExplicitVisibleNodes用于控制 Nodes 页面默认是否列出命名空间内的每一个 K8s Service:

  • 文档说明的默认值为false:默认列出所有 Service;
  • 当前仓库源码 K8sDiscoveryOptions.cs 的构造函数中实际初始化为true,即默认只列出带有dotnetcore.cap.visibility: show标签的 Service。

两种配置行为差异明显,建议在部署时显式设置该选项,避免依赖默认值产生歧义:

services.AddCap(x => { // ... x.UseDashboard(); x.UseK8sDiscovery(opt => { opt.ShowOnlyExplicitVisibleNodes = true; }); });

从源码 K8sNodeDiscoveryProvider.cs 的FilterNodesByTags逻辑可以看到该选项的实际处理:当选项为true时,只有携带dotnetcore.cap.visibility: show标签的 Service 才会出现在节点列表中;而显式携带hide标签的 Service 无论如何都会被过滤掉。当选项为false时,只有显式标记为hide的 Service 会被隐藏,其余全部列出。

授予 Pod 访问 Kubernetes API 的权限

组件运行在集群内部时需要调用 Kubernetes API 列出命名空间与 Service,因此若 Deployment 关联的 ServiceAccount 没有对应权限,需要授予namespaces、services资源的get、list(文档示例中同时包含watch)权限。

典型做法是:先创建ServiceAccount与ClusterRole并设置权限,再通过ClusterRoleBinding绑定,最后在 Deployment 中通过serviceAccountName指定。完整示例 YAML 如下(来自官方文档,可直接套用):

apiVersion: v1 kind: ServiceAccount metadata: name: api-access --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: ns-svc-reader rules: - apiGroups: [""] resources: ["namespaces", "services"] verbs: ["get", "watch", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: read-pods subjects: - kind: ServiceAccount name: api-access namespace: default roleRef: kind: ClusterRole name: ns-svc-reader apiGroup: rbac.authorization.k8s.io --- apiVersion: apps/v1 kind: Deployment metadata: name: api-access-deployment spec: replicas: 1 selector: matchLabels: app: api-access-app template: metadata: labels: app: api-access-app spec: serviceAccountName: api-access containers: - name: api-access-container image: your_image --- apiVersion: v1 kind: Service metadata: name: api-access-service spec: selector: app: api-access-app ports: - protocol: TCP port: 80 targetPort: 80

提示:Dashboard 实际读取的是集群内 ServiceAccount 的令牌与 CA 证书(BuildDefaultConfig()),因此确保承载 Dashboard 的 Pod 以正确的 ServiceAccount 运行是关键。

8.3.0 起:使用 Role 限定命名空间内权限

从版本8.3.0开始,可以使用Role替代ClusterRole,让 Dashboard 仅能发现其自身所在命名空间内的 Service,遵循最小权限原则。Role的作用域限定在单个命名空间内。将上述示例中的ClusterRole与ClusterRoleBinding替换为如下内容即可:

apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: ns-svc-reader rules: - apiGroups: [""] resources: ["services"] verbs: ["get", "watch", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: read-pods subjects: - kind: ServiceAccount name: api-access namespace: default roleRef: kind: ClusterRole name: ns-svc-reader apiGroup: rbac.authorization.k8s.io

需要注意的是,文档中的 Role 方案示例依然通过ClusterRoleBinding将 Role 绑定到 ServiceAccount(将 Role 与命名空间内的 ServiceAccount 绑定时也可使用同命名空间的RoleBinding,效果等同且作用域更收敛)。采用 Role 后,GetNamespaces返回的候选列表会受限——源码 K8sNodeDiscoveryProvider.cs 显示:当命名空间列表 API 调用失败时,会回退到返回当前K8SClientConfig.Namespace,保证 Dashboard 仍能正常工作。

通过标签控制节点列表与端口

Kubernetes 标签(Labels)是控制 Dashboard 节点列表最灵活的手段,所有 CAP 相关标签统一使用dotnetcore.cap前缀(源码中定义为TagPrefix,见 K8sNodeDiscoveryProvider.cs)。

节点可见性:dotnetcore.cap.visibility

  • 取值:show|hide
  • 示例:dotnetcore.cap.visibility: show或dotnetcore.cap.visibility: hide

hide优先级最高——无论ShowOnlyExplicitVisibleNodes如何设置,携带hide标签的 Service 都不会出现在列表中(对应 IsNodeHidden 的实现);当选项为true时,未携带任何 visibility 标签或值不是show的 Service 同样被隐藏。

端口选择:dotnetcore.cap.portName

默认情况下,每个 K8s Service 使用其端口列表中的第一个端口(索引 0)作为节点端口。当 Service 暴露多个端口时,可通过端口名称精确指定:

  • 取值:字符串(对应 Service 端口的name字段)
  • 示例:dotnetcore.cap.portName: grpc或dotnetcore.cap.portName: http

端口选择:dotnetcore.cap.portIndex

若未设置portName,或设置的portName在 Service 端口列表中找不到匹配项,则会尝试按索引匹配:

  • 取值:以字符串表示的数组下标,如'2'、'14'
  • 示例:dotnetcore.cap.portIndex: '1'或dotnetcore.cap.portIndex: '3'

若索引越界,则回退到第一个端口(索引 0)。

端口解析的完整优先级可在源码 GetPortByNameOrIndex 中确认:先按portName查找,命中则返回;未命中则按portIndex查找;仍未命中则回退到Ports[0]。标签解析过程位于 FilterNodesByTags,其中portIndex值需要能被int.TryParse成功解析才会生效,多个同名标签同时存在时以最后一个为准。

一个完整的带标签 Service 示例

为便于理解,下面给出一个同时使用可见性与端口标签的 Service 配置:

apiVersion: v1 kind: Service metadata: name: cap-node labels: dotnetcore.cap.visibility: show dotnetcore.cap.portName: http spec: selector: app: cap-node ports: - name: grpc protocol: TCP port: 50051 targetPort: 50051 - name: http protocol: TCP port: 80 targetPort: 80

在该配置下(ShowOnlyExplicitVisibleNodes = true),cap-node会出现在节点列表中,且 Dashboard 通过http://cap-node.<namespace>:80访问其 CAP 服务。

独立使用 Dashboard:无需配置 CAP 的纯查看 Pod

在 Dashboard 仅用于跨节点查看数据的场景下,可以将它作为独立的 Pod 部署,而待查看的业务服务无需再配置cap.UseK8sDiscovery()。只需调用:

services.AddCapDashboardStandalone();

该扩展方法位于 ServiceCollectionExtensions.cs,其内部同时注册了DashboardOptionsExtension与K8sDiscoveryOptionsExtension,并且支持两个可选参数分别配置 Dashboard 与 K8s 发现选项:

services.AddCapDashboardStandalone( opt => { /* Dashboard 配置 */ }, opt => { opt.ShowOnlyExplicitVisibleNodes = true; });

同样,承载独立 Dashboard 的 Pod 也需要为其 ServiceAccount 配置上文提到的 Kubernetes API 访问权限。

源码级工作原理小结

从仓库实现看,K8s 服务发现的完整数据流如下:

  1. Nodes 页面请求命名空间列表与节点列表;
  2. K8sNodeDiscoveryProvider 通过KubernetesClient(当前项目引用KubernetesClient19.0.2,见 DotNetCore.CAP.Dashboard.K8s.csproj)调用ListNamespacedServiceAsync、ReadNamespacedServiceAsync、ListNamespaceAsync等 API;
  3. 每个 Service 被映射为 Node 对象,其中Address形如http://<service>.<namespace>,端口按标签规则解析(见 ListServices);
  4. 点击 Switch 后,Dashboard 通过网关代理(GatewayProxyAgent)探测并转发请求到目标节点的 CAP Dashboard 接口。

值得注意的是,节点计数会被写入CapCache.Global(60 秒缓存),供 Dashboard 的 Nodes 页面展示节点数量;任何一次 API 调用异常都会被捕获并记录日志,返回空列表,不会导致 Dashboard 整体崩溃(见 GetNodes)。

总结

  • 在AddCap中启用UseK8sDiscovery(),即可在 Dashboard Nodes 页面按命名空间发现并切换查看各 CAP 节点的数据;
  • 务必为运行 Dashboard 的 Pod 配置 RBAC 权限:集群范围可用ClusterRole,自 8.3.0 起可用Role收敛到单命名空间;
  • 通过dotnetcore.cap.visibility、dotnetcore.cap.portName、dotnetcore.cap.portIndex三个标签,可精确控制节点的显示/隐藏与端口选择;
  • 纯查看场景可使用AddCapDashboardStandalone()将 Dashboard 独立部署,业务服务无需改动。

完整的英文原版文档见 docs/content/user-guide/en/monitoring/kubernetes.md,相关实现可在 src/DotNetCore.CAP.Dashboard.K8s 目录下深入阅读。

  • 后端
  • 消息队列
  • 微服务
  • 消息路由

【免费下载链接】CAP

Distributed transaction solution in micro-service base on eventually consistency, also an eventbus with Outbox pattern

项目地址:https://gitcode.com/gh_mirrors/ca/CAP
点击查看免费下载
上一篇:终极指南:3步诊断解决AutoGluon Windows GPU配置难题,让机器学习加速5-10倍!
下一篇:OnlookAPI路由:RESTful API设计与实现

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 2:28:13

模型优化器实战:量化、剪枝与算子融合的完整指南

1. 模型优化器到底在优化什么第一次接触 Model-Optimizer 这个概念&#xff0c;很多人会把它和优化算法&#xff08;Optimizer&#xff0c;比如 SGD、Adam&#xff09;搞混。我刚开始也犯过这个错&#xff0c;后来在几个实际项目里踩了坑才彻底理清&#xff1a;优化算法是训练时…

作者头像 李华
网站建设 2026/9/29 2:25:50

ZeroLaunch-rs办公应用:文档快速打开技巧

ZeroLaunch-rs办公应用&#xff1a;文档快速打开技巧 &#x1f680; 痛点&#xff1a;办公文档打开效率低下 在日常办公中&#xff0c;你是否经常遇到这样的场景&#xff1a; 需要快速打开某个Word文档&#xff0c;却在层层文件夹中苦苦寻找想要编辑Excel表格&#xff0c;却要经…

作者头像 李华
网站建设 2026/9/29 2:25:41

网络安全简答题文档的工程化构建方法

简介&#xff1a;本资源是一份面向网络安全初学者与备考学生的高频考点梳理文档&#xff0c;聚焦网络安全部分核心概念与典型简答题&#xff0c;适用于课程复习、期末备考及信息安全基础能力巩固。文件为单个140KB的Word文档&#xff08;.docx&#xff09;&#xff0c;内容结构…

作者头像 李华
网站建设 2026/9/29 2:25:13

FireDAC 下的 Sqlite [5]:插入、更新、删除的配置骨架与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华