Annotation 解析器深度
把 pkg/ingress/kube/annotations/ 的 24 个文件按主题拆开讲清楚。读完你能"加一个新注解"——这是给 Higress 添新功能最常见的姿势。
annotations/ 目录
annotations/
annotations.go # 入口:聚合所有 Parser
interface.go # 接口定义
parser.go、util.go # 工具
auth.go # 鉴权类(basic/key/jwt 聚合)
canary.go、cors.go、rewrite.go、redirect.go、timeout.go、
retry.go、mirror.go、header_control.go、ip_access_control.go、
local_rate_limit.go、loadbalance.go、match.go、ignore_case.go、
default_backend.go、destination.go、downstreamtls.go、upstreamtls.go、
http2rpc.go、mcpserver.go
24 个文件,按"一个能力一个文件"组织。注解前缀统一为 higress.io/ 或 nginx.ingress.kubernetes.io/(兼容 Nginx Ingress)。
interface.go 两接口
type AnnotationsParser interface {
Parse(annotations Annotations, config *Ingress, globalContext *GlobalContext) error
}
type AnnotationHandler interface {
Parse(meta metav1.ObjectMeta) (*Ingress, error)
ApplyRoute(route *networking.HTTPRoute, ingress *Ingress)
ApplyCluster(cluster *networking.DestinationRule, ingress *Ingress)
ApplyGateway(gw *networking.Gateway, ingress *Ingress)
}
两阶段:Parser 把字符串注解读到 Ingress IR;Applier 把 IR 字段写入 Istio 资源。这样每个能力只关心自己的字段,互不干扰。
annotations.go 入口
它实例化一份 AnnotationHandler,内部维护 Parser 列表(按字段名一一对应)。Parse 流程:循环 parser.Parse() 把所有注解填到一个 Ingress 结构体。ApplyXxx 时再调每个 Parser 的同名 Apply 方法。
parser.go 工具
通用工具:解析整数 / 布尔 / 字符串列表 / 时长。每个具体 parser 调用它从 Annotations map 里取值,简化错误处理。
val, err := parseIntAnnotation(annotations, "rate-limit-qps")
duration, err := parseDuration(annotations, "timeout")
list := parseStringList(annotations, "ip-whitelist")canary 灰度
注解:higress.io/canary、canary-weight、canary-by-header、canary-by-cookie。Parser 读取后存到 Ingress.Canary 字段。Apply 阶段配合 applyCanaryIngresses 改写 HTTPRoute 的 route[] + match.headers。
cors
注解:cors-allow-origins、cors-allow-methods、cors-allow-headers、cors-max-age。ApplyRoute 把它转成 HTTPRoute.CorsPolicy。Higress 与 Nginx Ingress 字段一一对应,迁移成本低。
* 与具体 origin 列表谁更安全?rewrite
注解:rewrite-target、upstream-vhost。Apply 阶段写入 HTTPRewrite.URI / Authority,让 Envoy 在路由后改写 URL。注意:rewrite 与 redirect 区别——前者改后端请求,客户端无感;后者返回 3xx。
pattern_match。redirect
注解:permanent-redirect、permanent-redirect-code、temporal-redirect。直接返回 301/302/307/308。还支持 HTTPS 强制重定向 ssl-redirect。
timeout
注解:proxy-connect-timeout、proxy-read-timeout、proxy-send-timeout、request-timeout。Apply 分别落到 HTTPRoute.Timeout(请求级)和 DestinationRule.ConnectionPool(连接级)。
retry
注解:proxy-next-upstream-tries、proxy-next-upstream(条件)。Apply 写到 HTTPRoute.Retries。Higress 默认对 5xx / connect-failure / refused-stream 自动重试。
mirror
注解:mirror-target-service、mirror-percentage。流量复制到镜像服务,但响应丢弃。常用于灰度验证。Apply 落 HTTPRoute.Mirror。
header_control
统一支持请求/响应方向上的 Add/Remove/Set。Apply 落到 HTTPRoute.Headers。注意 Envoy 对 header 名大小写不敏感、值大小写敏感。
ip_access_control
注解:whitelist-source-range、denylist-source-range。Apply 走 EnvoyFilter(不是 HTTPRoute,因为 Istio 原生 VS 不支持 IP ACL),patch listener 加 envoy.filters.http.rbac。
local_rate_limit
注解:route-limit-rps、route-limit-burst。本地 token bucket,无需 Redis,写到 EnvoyFilter envoy.filters.http.local_ratelimit。
分布式限流另见 cluster-key-rate-limit 插件(第 09 期)。
loadbalance
注解:load-balance(roundrobin/leastrequest/random/maglev/ringhash),ApplyCluster 写到 DestinationRule.TrafficPolicy.LoadBalancer。Higress 还扩展了"按 header 哈希一致性"用于 AI Provider 粘性会话。
auth (jwt/basic/key)
auth.go 聚合多种鉴权:
- basic-auth:Higress 原生支持,IngressConfig 合成 EnvoyFilter。
- key-auth / jwt-auth:通过 WasmPlugin 注解
auth-enabled关联。 - ext-auth:调外部 authz service。
upstream/downstream TLS
downstreamtls.go 处理客户端到 Higress 的 TLS(证书引用、最小 TLS 版本、SNI);upstreamtls.go 处理 Higress 到 upstream 的 mTLS(CA / cert / SNI / 验证模式)。
destination 转写
destination.go:注解 destination 可把 backend 重写到任意 host(含 Nacos 服务、外部 FQDN)。这是 Higress 让"Ingress 直连任意服务"的核心扩展。
http2rpc / mcpserver
这两个注解把 Ingress 路由"绑定到"对应 CRD:
higress.io/http2rpc: my-h2r→ 关联 Http2Rpc CRD,触发 Dubbo 协议转换。higress.io/mcp-server-config-name: ...→ 关联 McpServer CRD,转发到 MCP Server。
扩展新注解
5 步走:
- 在
annotations/新建myfeat.go,定义 MyFeatConfig 字段。 - 实现
AnnotationsParser与 Apply 方法。 - 在
annotations.go注册到 parser 列表。 - 在
WrapperConfig.Ingress增加字段引用。 - 选择落到 Route / Cluster / Gateway 还是 EnvoyFilter,补 Apply 调用。
整套过程不需要触碰 IngressConfig 主流程,符合"开闭原则"。