Day 16 / 共 20 天 · 第 4 周 遥测/扩展/安装

遥测

服务网格"免费"给你的可观测性从哪来?Istio 的 Telemetry API 把"要采集什么指标/追踪"翻译成 Envoy 的 stats filter,注入每个 listener。今天看这个翻译。第 4 周开场:W3 我们让 sidecar 落地并加了安全,本周看它"顺手送"的三件生态大礼——遥测、扩展、安装。

📍 你在整门课的位置 · 第 4 周「遥测 / 扩展 / 安装」(W1-3 全部 ✓:控制面 · xDS · sidecar 与安全)
D16 遥测 D17 EnvoyFilter D18 istioctl D19 安装 D20 收官
L01

遥测三态

Istio 遥测三支柱(呼应 Envoy 课 Day 18):Metrics(指标)、Tracing(追踪)、AccessLogging(访问日志)。都由 Telemetry API 配置,istiod 翻译成 Envoy 配置。

🤔 痛点:以前想给微服务加监控有多烦? 传统做法:每个服务里手动埋点,接监控 SDK,统计"这次调用多久、成没成、调的谁"。几十个服务、还可能是不同语言写的,每个都埋一遍——重复、易漏、升级 SDK 要全改。更别提想统一"所有服务间调用"的视图有多难。
💡 本质:流量都过保安,让保安顺手记账 续用类比:Envoy 是每个门店的"保安",所有进出流量都从他手里过。那让保安顺手拿个记录仪,每笔进出都记一条账(谁来的、去哪、多久、成没成)——不就"免费"得到全套监控了吗?业务代码一行不改,因为记账的是保安不是店员。Istio 的活儿,就是给保安下一张"记账规则单"(Telemetry CRD → stats filter),告诉他记什么、报给谁。
⚠️ 常见误解:以为指标是 istiod 采集的。其实 istiod 只负责"配置",真正采集的是数据面的 Envoy。istiod 把 Telemetry CRD 翻译成 stats filter 下发,Envoy 在处理每个请求时累计指标——控制面出规则,数据面出数据。
为什么服务网格能"免费"给可观测性? 因为所有流量都经过 sidecar Envoy(Day 11)——Envoy 天然能统计每个请求的延迟、状态码、来源去向。Istio 只需配置 Envoy"采集这些指标、上报到哪",业务代码一行不改,就得到了全套的服务间调用指标、分布式追踪、访问日志。这是服务网格最受欢迎的能力之一——上了网格,可观测性自动到位。Istio 的活儿就是把"你想观测什么"(Telemetry CRD)翻译成"Envoy 怎么采集"(stats filter)。
L02

Telemetry API

// pilot/pkg/model/telemetry.go:45 type Telemetry(一个 CRD)
// telemetry.go:388 HTTPFilters / :396 TCPFilters → telemetryFilters(:493)生成 filter
// telemetry.go:297 Tracing(合并 mesh provider + CR overrides,采样率/tags)
// telemetry.go:242 AccessLogging
读法:Telemetry CRD 让你精细控制"哪些流量采集什么指标、追踪采样率多少、日志格式"。istiod 的 telemetry.go 负责把它翻译成 Envoy 的 metrics/tracing/logging 配置(stats filter、tracing provider 等)。
L03

昂贵所以缓存

// telemetry.go:56 Telemetries 带缓存:
//   computedMetricsFilters map[metricsKey]any  // :76
//   注释强调:这些 filter 极昂贵(merge 多份 spec + 两次 Any marshal + 插到每个 listener)
//   按 metricsKey(Class/Protocol/ProxyType/Service)缓存
为什么遥测配置生成要特别缓存? 注释直言这些 filter"极其昂贵"。因为:①要合并多份 Telemetry spec(mesh 级 + namespace 级 + workload 级);②要做两次 proto 序列化(Any marshal);③要插到每个 listener上(一个 proxy 可能有几十上百个 listener)。如果每个 proxy 每次都重算,开销巨大。所以按 metricsKey(一组决定 filter 内容的因素)缓存——很多 proxy 的遥测 filter 其实相同(同协议、同 proxy 类型),缓存命中就省了重算。这又是"带 Proxy 翻译成本高 → 用缓存补偿"(Day 07)。
L04

层级合并

telemetry.go:404 applicableTelemetries:按 root ns → workload ns → workload selector 层级合并——越具体越优先覆盖。

读法:和 PeerAuthentication(Day 15)一样的层级模型:mesh 级设默认,namespace 级细化,workload 级最精确。PolicyMatcherForProxy 判断某条 Telemetry 是否命中当前 proxy。合并后得到"这个 proxy 最终的遥测配置"。
L05

stats filter 生成

// telemetry.go:980 generateStatsConfig
//   构造 stats.PluginConfig(来自 istio.io/api)
//   metricToPrometheusMetric(:967):REQUEST_COUNT → requests_total 标准名映射
//   处理维度/tag 增删 → protoconv.MessageToAny
// telemetry.go:927 buildHTTPTelemetryFilter:生成名为 xds.StatsFilterName 的 filter
读法:最终生成一个 Envoy HTTP/TCP filter(StatsFilterName)——它是个 Wasm/native 插件,负责统计请求指标。REQUEST_COUNT → requests_total 是把 Istio 标准指标名映射成 Prometheus 约定名。目前 provider 主要支持 Prometheus。
📝 举个例子:一条指标名的翻译 Istio 内部标准名 REQUEST_COUNT → 经 metricToPrometheusMetric → Prometheus 约定名 istio_requests_total;再带上维度标签变成 istio_requests_total{source_app="frontend", destination_service="reviews", response_code="200"}这样 Grafana 里就能按"来源→目的、状态码"切片看调用量了——这些标签正是保安记账时填的字段。
L06

注入 listener

生成的 stats filter 在 listener_builder.go:520 被 append 进 HCM 的 filter 链(回想 Day 08 的 ListenerBuilder)。TCP 在 networkfilter.go:60

遥测就是"多插一个过滤器" 回想 Envoy 课 Day 08:请求处理是过滤器链。Istio 的遥测实现,本质就是在每个 listener 的过滤器链里插入一个 stats filter——这个 filter 在请求经过时记录指标(延迟、状态码、来源)。所以遥测和限流、认证一样,都是"往过滤器链里加一个过滤器"。这就把 Istio 课(生成 filter)和 Envoy 课(执行 filter)又一次精确对接——Istio 生成的 stats filter,正是 Envoy 在过滤器链里执行的。
L07

Prometheus 闭环

指标采集的完整闭环
① Telemetry CRD → istiod 生成 stats filter → 注入 Envoy listener(今天)
② Envoy 请求经过 stats filter,累积指标(Envoy 课 Day 18 的无锁 stats)
③ Envoy admin 的 /stats/prometheus 暴露指标;bootstrap 里的"必备 stats"(Day 13)保证关键指标被采集
④ pilot-agent 的 status server(15020,Day 12)反代到 15090
⑤ Prometheus 抓取 15090 → 存储 → Grafana 展示
Istio(生成配置)+ Envoy(采集指标)+ agent(暴露端口)+ Prometheus(抓取)——四方协作,你 kubectl apply 一个 Telemetry 就全通了。
Telemetry CRDistiod 生成 filter Envoy 累积stats filter 记账 /stats/prometheusEnvoy admin 暴露 agent 15090反代(Day12) Prometheus抓取→Grafana Istio 配 · Envoy 记 · agent 露 · Prometheus 抄 —— 四方协作
指标采集闭环:像"总部定期来抄表"——保安(Envoy)平时记账,agent 把账本挂到 15090,Prometheus 定时来抄,Grafana 出图。
L08

今日小结 + 动手

🧠 今天你应该能回答

  • 遥测三态是什么?为什么服务网格能"免费"给可观测性?
  • Telemetry API 控制什么?
  • 为什么遥测配置生成要特别缓存?
  • 层级合并怎么工作?
  • 遥测本质是"插一个什么"?Prometheus 采集闭环?

✋ 动手

cd /Users/bitmart/work/codes/github/higress-group/istio
grep -n 'type Telemetry struct\|func.*HTTPFilters\|generateStatsConfig' pilot/pkg/model/telemetry.go
grep -n 'HTTPFilters' pilot/pkg/networking/core/listener_builder.go
明天预告 · Day 17EnvoyFilter——直接给 Envoy 配置打补丁的"逃生舱"。Higress 重度依赖它实现 Wasm 插件、自定义 filter。理解它就理解了 Higress 怎么在 Istio 上做增强。
← Day 10 连接生命周期 Day 17 · EnvoyFilter →