TT Lab
开始
学习 学习路径 课程

Istio 实测实验室

指标会被数两次,标签要花钱

在 TT Lab 中继续学习

一句话总结

sidecar 会对每个请求上报标准指标(istio_requests_total、istio_request_duration_milliseconds 等)并留下访问日志。Telemetry API 是在命名空间、工作负载级别修改它们的机制——增加标签(tagOverrides)、删除标签(REMOVE)、关闭指标(disabled),以及按条件过滤日志(filter)。

为什么需要它

网格的承诺之一是“不修改代码,就能用同样的格式看到所有服务的请求数、错误率和延迟”。因为所有请求都要经过 sidecar,所以这是可行的。不过放着不管会出现两个问题。

第一是成本。标准指标带有来源、目的地、响应码、协议等多个标签,延迟直方图的每个桶都会产生一条时间序列。服务有几百个时,首先不堪重负的是 Prometheus。第二是不足。“这是哪个客户(tenant)的请求”这样业务所需的维度,在标准标签里是没有的。

Telemetry API 用一份配置就能处理这两点。可以按整个网格(istio-system)、命名空间、工作负载选择器的顺序逐步收窄地应用。

工作原理

指标会被计数两次。在 sidecar 模式下,一个请求会由发送方 sidecar(reporter="source")和接收方 sidecar(reporter="destination")各计一次。两者都在网格内时,同一个数量会累积两次,所以求和时必须把 reporter 固定为一个。以接收方(destination)为准,通常更接近“服务收到的请求”。

Prometheus 是抓取的。发行包的 Prometheus 插件会根据 Pod 注解,定期(这套配置是 15 秒)抓取 sidecar 合并后的指标端口。所以发送请求后要过大约一个周期,才会出现在查询结果中。sidecar 现在持有的值,可以用 pilot-agent request GET stats/prometheus 直接查看。

用 Telemetry 修改的内容

配置 作用
tagOverrides: {tenant: {value: "request.headers['x-tenant']"}} 用请求属性创建新标签
tagOverrides: {request_protocol: {operation: REMOVE}} 删除标准标签
match: {metric: REQUEST_DURATION}, disabled: true 不生成该指标
accessLogging: [{filter: {expression: "response.code >= 400"}}] 只对符合条件的请求留下日志

如果把取值无限增长的东西(用户 ID、请求 ID)做成标签,时间序列就会爆炸。增加标签时,先考虑取值的个数。而且计数器不会被清除,所以修改配置的效果只体现在新产生的时间序列上。

用 PromQL 算出比率。错误率是 sum(5xx) / sum(전체)(占位符为全部请求)。生产仪表板用 rate(…[5m]) 看最近一个窗口的比率,但在请求很少的实验中,直接用计数器相除也可以。两种情况下,分子和分母都必须指向同一个 reporter、同一个目的地。

在现场相遇的样子

“仪表板上的请求数是负载均衡器的两倍”——没有过滤 reporter 就直接相加了。

“加了 tenant 标签后,Prometheus 的内存飙升”——客户有几万个。这是应该用日志或跟踪而不是标签来查看的维度。

“缩减访问日志之后,故障分析变难了”——只留下错误的话,就看不到“原本正常的请求是从什么时候开始变慢的”。条件表达式里常常也会同时加入延迟(response.duration)。

官方文档:Telemetry API、Customizing Istio Metrics、Istio Standard Metrics、Envoy Access Logs、Prometheus addon

下一项实验要做什么

在随发行包的 Prometheus 插件一同部署的网格中,发送请求并用 HTTP API 查询 istio_requests_total,看到同一个请求被按 source、destination 计数两次。用 Telemetry API 添加 tenant 标签、删除不用的标签、关闭延迟指标、把访问日志过滤为只留下错误,最后用一行 PromQL 算出错误率。