Day 14 / 共 20 天 · 第 3 周 AI/插件/消费者

路由 · 服务 · 服务来源

今天理清三个容易混的概念:路由(怎么转发)、服务(转发到哪,只读)、服务来源(从哪发现服务)。重点在服务来源——8 种注册中心如何全部塞进一个名为 default 的 McpBridge CR。

📍 你在整门课的位置 · 第 3 周 AI/插件/消费者(Day 11-15)
D11 AI供应商/路由 D12 插件管理 D13 消费者鉴权 D14 路由/服务源 D15 MCP管理
L01

三个概念的关系

🤔 痛点:三个词天天混,到底谁生谁? 很多人分不清"服务来源""服务""路由"——建路由时想选后端,却发现列表是空的,一头雾水:到底该先配哪个?
💡 本质:进货 → 货架 → 菜谱 用做饭打比方:服务来源 = "去哪个菜市场进货"(Nacos/K8s…);服务 = 菜市场里现有的菜(只能看,不能凭空造);路由 = 菜谱,指定"这道菜用货架上的哪样货"。没进货渠道就没菜,没菜路由就没得选后端——三者是严格的上下游。
📝 举个例子 配一个 nacos 服务来源(指向公司 Nacos)→ Higress 自动发现 order-serviceuser-service 等服务(只读)→ 你建路由 /order 时,从这些服务里挑 order-service 当后端。
  • 服务来源(ServiceSource):告诉 Higress"去哪个注册中心发现服务"(Nacos/K8s/…)。
  • 服务(Service):从服务来源发现到的服务,只读。
  • 路由(Route):把匹配的请求转发到某个(些)服务。
一条链:来源 → 服务 → 路由 先配服务来源("去 Nacos 找服务")→ Higress 发现一堆服务 → 你建路由时从这些服务里挑一个当后端。三者是上下游关系:没有服务来源就发现不到服务,没有服务就没得给路由当后端。
L02

路由回顾

路由第 2 周已深入(Day 10)。快速回顾:RoutesController/v1/routes)→ RouteServiceImpl(依赖 K8sClient/ModelConverter/WasmPluginInstanceService/ConsumerService)→ route2Ingress 转成 Ingress + 注解。

读法:Route 的高级能力(CORS/rewrite/header 控制/path 匹配类型)都通过 Higress 定制注解承载;rewrite 分"精确/前缀路径用 rewrite-path、正则用 rewrite-target";path 类型 EXACT/PRE/REGULAR 对应 Ingress 的 Exact/Prefix + use-regex 注解。
L03

服务只读

👶 小白 vs 👨‍🏫 老师 👶:为什么服务页只能看、不能"新建服务"?是功能没做完吗?
👨‍🏫:不是。服务不是你在 Console 里造出来的,而是网关从注册中心实时发现的——实例上线下线由各服务自己决定,Console 只是"看客"。
👶:那我想让列表里出现新服务怎么办?
👨‍🏫:去动服务来源(换注册中心 / 加过滤),而不是改服务本身。所以"服务只读"完全符合服务发现的语义。

ServicesController.java/v1/services:36)仅 GET list:44)。ServiceServiceImpl.list:61)的数据来自 Istio 的 registryz/endpoint。Service.java:name/namespace/port/version/endpoints/protocol。

为什么服务不能增删改? 服务不是你在 Console 里"创建"的,而是网关从注册中心实时发现的——服务实例上线下线由各服务自己决定,Console 只是"看客"。你想改变有哪些服务,得去改"服务来源"(换注册中心 / 加过滤),而不是直接改服务本身。所以服务只读,符合服务发现的语义。回想 Day 06 的"二选一":这个列表可能来自 Higress 控制器的 registryz,也可能直接列 K8s Service。
L04

服务来源 Controller

ServiceSourceController.java/v1/service-sources:46):list(:53stripSensitiveInfo 抹掉认证信息)、add(:65)、addOrUpdate(:81)、delete(:99)、query(:112)。

读法:list 时 stripSensitiveInfo 把认证密码/token 抹掉再返回前端——敏感信息只写不读回,避免密码在界面泄露。这是安全设计的常见做法。
L05

8 种注册中心

ServiceSource.javaALLOWABLE_TYPES:52-55)= nacos / nacos2 / nacos3 / zookeeper / consul / eureka / static / dnsvalidate:121-196)按类型分派专用校验器(Nacos/Consul/Static/Dns)。

读法:static = 直接写死 IP,dns = 用域名,其余是主流注册中心。proxy 只支持 static/dns(通过代理访问的场景)。注意只有 nacos3 支持 MCP Server(V1McpBridge.MCP_SUPPORTED_REGISTRY_TYPES,Day 15 用到)。
L06

全部存进一个 McpBridge CR

nacos 来源 zookeeper 来源 static / dns … (8 种注册中心) McpBridge CRname = default(唯一一个)spec.registries[] Higress 控制器只 watch default 读-改-写 认证信息 → K8s Secret
8 种来源全塞进唯一一个 default McpBridge 的 registries 数组;控制器只 watch 它。认证密码单独存 Secret,registry 里只放 authSecretName 引用(L07)。

关键设计:所有服务来源存进一个名为 default 的 McpBridge CR 的 spec.registries[] 数组ServiceSourceServiceImpl

list  :61    // 读 default McpBridge 的 registries
add   :169   // readMcpBridge(default) → addV1McpBridgeRegistry → replace
// 转换:KubernetesModelConverter.addV1McpBridgeRegistry :1728
//       removeV1McpBridgeRegistry :1752 / fillV1RegistryConfig :1860

CRD 常量 crd/mcp/V1McpBridge.java:27-35:group networking.higress.io、kind McpBridge、plural mcpbridgesDEFAULT_NAME=default

为什么全塞一个 CR,而不是一个来源一个 CR? McpBridge 是 Higress 定义的"服务来源汇总表"CRD。Higress 控制器只 watch 这一个名为 default 的 McpBridge,读它的 registries 数组就知道所有服务来源。Console 每次加/删来源,都是"读出这个 CR → 改数组 → 写回"(Day 07 说过的读-改-写)。单一资源好管理,也符合 Higress 控制器的约定。
L07

认证单独存 Secret

ServiceSourceServiceImpl.syncAuthSecret:207)把注册中心的认证信息(用户名/密码/token)单独存进 K8s Secret,McpBridge 的 registry 项里只存 authSecretName(引用)。

读法:又是"敏感数据存 Secret"的体现(Day 07 表格)。McpBridge CR 里只放 Secret 的名字,真正的密码在 Secret 里(受 K8s 加密保护)。这样看 McpBridge 的人看不到明文密码,安全。
L08

今日小结 + 动手

🧠 今天你应该能回答

  • 服务来源、服务、路由三者的上下游关系?
  • 为什么服务只读?想改变服务列表该动什么?
  • 8 种注册中心有哪些?哪个支持 MCP?
  • 服务来源为什么全存进一个 default McpBridge?认证信息存哪?

✋ 动手

cd /Users/bitmart/work/codes/github/higress-group/higress-console/backend/sdk/src/main/java/com/alibaba/higress/sdk
sed -n '52,55p' model/ServiceSource.java
sed -n '61,210p' service/ServiceSourceServiceImpl.java
sed -n '27,81p' service/kubernetes/crd/mcp/V1McpBridge.java
明天预告 · Day 15(第 3 周收官)MCP 管理——MCP Server 的三种类型(OpenAPI/Database/DirectRoute)、双策略工厂(save/detail)、以及"MCP Server 不是独立 CRD 而是 Route + ConfigMap"的存储设计。
← Day 13 Day 15 · MCP 管理 →