土法炼钢 · 系统与基础设施

【Linkerd】ServiceProfile:L7 路由、重试与 sp-validator

文章导航

分类入口
kubernetesnetwork
标签入口
#linkerd#serviceprofile#sp-validator#l7-routing#retry#v2.20

目录

第 8 篇 钉入站 AuthorizationPolicy 与 policy 容器;出站 发现destination.Get 承担(第 7 篇)。L7 行为——按路径路由、可重试、超时、失败分类——走第三条链:ServiceProfiledestination.GetProfilelinkerd2-proxy 出站 HTTP 逻辑。读者常把「重试不生效」当成发现问题,或把 SP 校验失败当成策略拒绝;本篇分列机制与表象。

本篇在系列中的位置

篇目 核心内容
第 8 篇 · 策略模型 Server、AuthorizationPolicy
第 9 篇 · ServiceProfile L7 路由、sp-validator、GetProfile
第 10 篇 · linkerd2-proxy Rust 数据面、协议探测
系列目录 关键问题、阅读路径

版本锚定:Linkerd 2.20(tag version-2.20)。ServiceProfile API 组 linkerd.io,版本 v1alpha2(validator webhook 亦接受 v1alpha1)。GetProfile 语义见 destination.proto DestinationProfile @ linkerd2-proxy-api v0.20.0无真实集群则不粘贴伪造 profile 推送或 apply 输出。


一、ServiceProfile CRD

ServiceProfile 是 Linkerd 原生的 L7 流量描述:绑定到某个 Service(按 FQDN),定义 routesretryBudgetdstOverrides(流量拆分)等。数据面不直接读 CRD;destination 控制器 watch ServiceProfile,翻译成 DestinationProfile 消息经 GetProfile 流推送。

destination.protoDestinationProfile 关键字段:

与 Istio VirtualService 对照:Istio 翻译为 xDS RDS;Linkerd 把等价信息塞进 专用 GetProfileistio-xds/14)。排障 L7 应查 profile 流内容,不是 VirtualService 是否同步到 istiod。

ServiceProfile 命名 convention:通常与 Service 同名同 namespace,或通过 Service 注解 linkerd.io/profiles 指向外部 profile——以 2.20 官方 ServiceProfile 文档为准,本篇不展开注解全集。


二、sp-validator webhook

destination Pod 内的 sp-validator 容器注册 linkerd-sp-validator ValidatingWebhookConfiguration:

分工边界

组件 时机 职责
sp-validator CRD 写入 API server 前 语法/语义校验,拒绝非法 ServiceProfile
destination + ProfileWatcher 运行时 将合法 CRD 编入 GetProfile 响应
policy-validator CRD 写入前 校验 policy.linkerd.io 与 GAPI 路由(第 8 篇

校验失败时 kubectl apply 直接报错——此时数据面从未见过该 profile,谈不上「路由不命中」。与运行时 404/超时(profile 已加载但条件不匹配)证据包不同。

failurePolicy 跟随 chart 全局 webhookFailurePolicy:集群级运维门,决定 webhook 不可达时是否阻断写入。


三、与 destination 合流

server.goGetProfileGet 并列:解析 GetDestination.path 后,经 ProfileWatcher 订阅对应 ServiceProfile;IP 查询走 getProfileByIP 分支(用于按 Pod IP 反查 profile)。

合流路径:

flowchart TD
  spcrd["ServiceProfile CRD"] --> pw["ProfileWatcher"]
  pw --> gp["destination.GetProfile stream"]
  gp --> proxy["linkerd2-proxy outbound HTTP"]
  get["destination.Get stream"] --> proxy

出站一次 HTTP 请求同时依赖:

  1. Get:后端地址与 mTLS 身份(发现轴)。
  2. GetProfile:走哪条 route、是否可重试、超时多久(L7 轴)。

subscribeToServiceProfile 在 profile 缺失时发送 默认空 profiledefaultProfile),使行为回退到无自定义路由——表象是「SP 写了但不生效」,要先查 CRD 是否同名、watcher 是否收到、validator 是否曾拒绝。

dst_overrides 触发对多个 authority 的 Get 调用,把流量拆分与 per-target 流模型绑在一起;拆分配错会表现为部分后端永远无流量,而非单条 route 正则错误。


四、Gateway API 分工指针(详 11)

Linkerd 2.20 同时支持 Gateway API(公告门 1.5.1)与 ServiceProfile。分工原则(机制层,详 第 11 篇):

机制 ServiceProfile Gateway API HTTPRoute 等
主要场景 mesh 内 L7 路由/重试/超时 南北向与 GAPI 生态互操作
控制面入口 linkerd.io ServiceProfile gateway.networking.k8s.io + policy.linkerd.io HTTPRoute
校验 webhook sp-validator policy-validator(同 Pod 旁路)
数据面下发 GetProfile policy-controller 编译后仍汇入 proxy 策略/profile 链

双轨开放问题:同一 Service 上 SP 与 HTTPRoute 规则冲突时何者优先,须以 tag 文档与 第 11 篇 为准,本篇不写成已统一仲裁算法。选型读者应把 GAPI 当边界扩展,把 ServiceProfile 当 mesh 内经典 L7 配置路径。


五、校验失败表象

表象 落格 核对
apply ServiceProfile 被 webhook 拒绝 sp-validator kubectl 事件;validator Pod 日志
apply 成功但无自定义路由 ProfileWatcher / 命名 Service 与 Profile 名是否对齐;注解 profiles
重试不发生 L7 轴 is_retryableretry_budget 是否耗尽
超时与预期不符 L7 轴 route timeout;非 Service timeout 注解臆测
403 / 身份拒绝 策略轴(第 8 篇 不是 SP 问题
无端点 发现轴(第 7 篇 Get 流,不是 GetProfile

口诀:写入失败找 validator;行为失败先分 Get vs GetProfile;403 找 policy。 不要把三轴证据包混在一个「Linkerd 配置坏了」叙事里。


参考资料

规范 / 官方文档 / 源码(A)

站内对照(A/B)

学术谱系(A)


上一篇策略模型

下一篇linkerd2-proxy 数据面

读完这篇,下一步读什么

优先读同系列或同问题的下一篇,把单篇消费变成主题集群。


By .