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 的
④ pilot-agent 的 status server(15020,Day 12)反代到 15090
⑤ Prometheus 抓取 15090 → 存储 → Grafana 展示
Istio(生成配置)+ Envoy(采集指标)+ agent(暴露端口)+ 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 就全通了。指标采集闭环:像"总部定期来抄表"——保安(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 17:EnvoyFilter——直接给 Envoy 配置打补丁的"逃生舱"。Higress 重度依赖它实现 Wasm 插件、自定义 filter。理解它就理解了 Higress 怎么在 Istio 上做增强。