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

Istio 实测实验室

数两次,按标签付费

在 TT Lab 中继续学习

目标

在部署了 Prometheus 插件的真实网格中,用 PromQL 查询标准指标,并通过 Telemetry API 增加标签、删除标签、关闭指标、过滤访问日志,然后从 sidecar 的指标和日志中确认其效果。

为什么重要

网格的可观测性看似免费,但每多一个标签、每多一个直方图,时间序列的数量就会成倍增长。反过来,业务所需的维度在标准标签中并没有。决定增加什么、舍弃什么的机制就是 Telemetry API,而它的效果不能看配置,必须看实际累积起来的指标和日志。

步骤

  1. 用 kubectl apply -f /opt/fixtures/istlab/telemetry-app.yaml 部署材料,等待就绪。在 client 中访问 http://web/ 10 次、http://web/broken 3 次之后,向 Prometheus(服务 istio-system/prometheus,端口 9090)查询 sum by (response_code) (istio_requests_total{reporter="destination",destination_workload="web",destination_workload_namespace="shop"}),把响应 JSON 原样保存到 /root/istlab-telemetry/01-prom.json。抓取周期是 15 秒,所以要等到两个状态码都能看到之后再保存。
  2. 在 Prometheus 中,把 destination_workload="web" 且 response_code="503" 的 istio_requests_total 按 reporter 分别求和,以 source_503=、destination_503= 两行写入 /root/istlab-telemetry/02-reporters.txt。
  3. 在 /root/istlab-telemetry/telemetry.yaml 中写入并应用命名空间 shop 的 Telemetry shop-telemetry——metrics 的 provider 为 prometheus,override 针对 REQUEST_COUNT、CLIENT_AND_SERVER,通过 tagOverrides 把 tenant 设为 request.headers['x-tenant'] 来添加。应用后,带上 x-tenant: acme 访问三次,并把向 Prometheus 查询 sum by (tenant) (istio_requests_total{tenant="acme"}) 得到的响应保存到 /root/istlab-telemetry/03-tenant.json。
  4. 在 /root/istlab-telemetry/telemetry.yaml 中,往同一个 override 的 tagOverrides 里加入 request_protocol: {operation: REMOVE} 并重新应用。应用后,带 x-tenant: beta 发出的请求所产生的新时间序列中不应再有 request_protocol 标签。
  5. 在 /root/istlab-telemetry/telemetry.yaml 中再加一个 override,把 REQUEST_DURATION(CLIENT_AND_SERVER)用 disabled: true 关闭,并重新应用。应用后,即使发送请求,client sidecar 的 istio_request_duration_milliseconds_count 的总和也不应再增加(istio_requests_total 则应继续增加)。
  6. 在 /root/istlab-telemetry/telemetry.yaml 中加入 accessLogging 并重新应用——provider 为 envoy,filter.expression: "response.code >= 400"。应用后,client 的 200 请求不应出现在 client sidecar 的访问日志中,只应留下 /broken(503)请求。
  7. 在 /root/istlab-telemetry/07-error-ratio.promql 中写入一条 PromQL,返回 web 所接收的(reporter 为 destination)请求中 5xx 所占的比率,并把向 Prometheus 查询该语句得到的值以 ratio= 写入 /root/istlab-telemetry/07-ratio.txt。
  8. 在 /root/istlab-telemetry/08-report.md 中写入五行——requests_503_destination=(第 2 步的 destination_503)、counted_twice=(第 2 步中 source 与 destination 计数相同则为 yes)、tenant_label=(第 3 步中附加的 tenant 值)、duration_counting=(现在 duration 指标仍在增长则为 yes)、logged_only_errors=(第 6 步的结果成立则为 yes)——并在其下写出学到的内容,至少四行。

参考

发送请求并向 Prometheus 查询

用 kubectl apply -f /opt/fixtures/istlab/telemetry-app.yaml 部署材料,等待就绪。在 client 中访问 http://web/ 10 次、http://web/broken 3 次之后,向 Prometheus(服务 istio-system/prometheus,端口 9090)查询 sum by (response_code) (istio_requests_total{reporter="destination",destination_workload="web",destination_workload_namespace="shop"}),把响应 JSON 原样保存到 /root/istlab-telemetry/01-prom.json。抓取周期是 15 秒,所以要等到两个状态码都能看到之后再保存。

sidecar 会对每个请求累加 istio_requests_total 之类的标准指标,Prometheus 则根据 Pod 的注解抓取 sidecar 的 15020 端口。所以请求发出后不会立即看到,而是晚大约一个周期才会出现。查询要像 curl -s http://<ClusterIP>:9090/api/v1/query --data-urlencode 'query=…' 那样通过 HTTP API 进行。

一个请求由谁来计数——reporter

在 Prometheus 中,把 destination_workload="web" 且 response_code="503" 的 istio_requests_total 按 reporter 分别求和,以 source_503=、destination_503= 两行写入 /root/istlab-telemetry/02-reporters.txt。

在 sidecar 模式下,一个请求由发送方(source)的 sidecar 和接收方(destination)的 sidecar 分别计数。两个值相同才是正常的,在仪表板上不过滤 reporter 就直接相加,请求数会看起来翻倍。也请记住:接收方在网格之外时只剩 source 一侧,发送方在网格之外时只剩 destination 一侧。

给指标加上我们自己的标签——tagOverrides

在 /root/istlab-telemetry/telemetry.yaml 中写入并应用命名空间 shop 的 Telemetry shop-telemetry——metrics 的 provider 为 prometheus,override 针对 REQUEST_COUNT、CLIENT_AND_SERVER,通过 tagOverrides 把 tenant 设为 request.headers['x-tenant'] 来添加。应用后,带上 x-tenant: acme 访问三次,并把向 Prometheus 查询 sum by (tenant) (istio_requests_total{tenant="acme"}) 得到的响应保存到 /root/istlab-telemetry/03-tenant.json。

Telemetry API 在命名空间(或工作负载)级别修改 sidecar 的指标配置。tagOverrides 的值是请求属性表达式,所以可以把请求头、路径之类的请求信息变成标签。不过,如果把取值无限增长的东西(比如用户 ID)做成标签,时间序列会爆炸,要小心。sidecar 附加的内容可以用 kubectl -n shop exec client -c istio-proxy -- pilot-agent request GET stats/prometheus 直接查看,在 Prometheus 中则要晚大约一个周期才会出现。

删除不用的标签

在 /root/istlab-telemetry/telemetry.yaml 中,往同一个 override 的 tagOverrides 里加入 request_protocol: {operation: REMOVE} 并重新应用。应用后,带 x-tenant: beta 发出的请求所产生的新时间序列中不应再有 request_protocol 标签。

即使一个标签总是同一个值(http),它也会附加到所有时间序列上占用存储空间。把不用的标准标签删掉,是降低基数(cardinality)最便宜的方法。已经生成的时间序列是计数器,不会被删除而是保留,所以请用新产生的时间序列(新的 tenant 值)来确认。

关闭不用的指标

在 /root/istlab-telemetry/telemetry.yaml 中再加一个 override,把 REQUEST_DURATION(CLIENT_AND_SERVER)用 disabled: true 关闭,并重新应用。应用后,即使发送请求,client sidecar 的 istio_request_duration_milliseconds_count 的总和也不应再增加(istio_requests_total 则应继续增加)。

延迟直方图的每个桶都会产生时间序列,是标准指标中最重的。可以通过 Telemetry API 做出这样的选择:只在网关处查看,在 sidecar 上关闭。关闭并不会让旧的值消失,所以要以“不再增长”来确认——请在请求前后各测一次总和并比较。

只把错误留在访问日志中

在 /root/istlab-telemetry/telemetry.yaml 中加入 accessLogging 并重新应用——provider 为 envoy,filter.expression: "response.code >= 400"。应用后,client 的 200 请求不应出现在 client sidecar 的访问日志中,只应留下 /broken(503)请求。

这个网格在安装时通过 meshConfig 打开了所有访问日志。Telemetry 的 accessLogging 可以在命名空间级别覆盖它,只留下符合条件表达式(CEL)的请求。把成功的请求也全部留下的话,日志成本会随请求数成比例增长,所以在生产中往往只留下错误和慢请求。请带上请求 ID 发送,并在 kubectl -n shop logs client -c istio-proxy 中查找。

用一行 PromQL 算出错误率

在 /root/istlab-telemetry/07-error-ratio.promql 中写入一条 PromQL,返回 web 所接收的(reporter 为 destination)请求中 5xx 所占的比率,并把向 Prometheus 查询该语句得到的值以 ratio= 写入 /root/istlab-telemetry/07-ratio.txt。

比率是 sum(5xx 카운터) / sum(전체 카운터)(占位符依次为 5xx 计数器、全部计数器)。如果不把 reporter 固定为一个,就会拿被计数两次的请求互相相除;如果有来自网格之外的请求,分母和分子数的就是不同的东西。生产仪表板会用 rate(…[5m]) 看最近的比率,但本实验的请求只有几次,所以直接用计数器本身相除。查询文件中的换行,用 --data-urlencode "query=$(cat 파일)"(占位符为查询文件)发送就可以原样保留。

写下统计了什么、舍弃了什么

在 /root/istlab-telemetry/08-report.md 中写入五行——requests_503_destination=(第 2 步的 destination_503)、counted_twice=(第 2 步中 source 与 destination 计数相同则为 yes)、tenant_label=(第 3 步中附加的 tenant 值)、duration_counting=(现在 duration 指标仍在增长则为 yes)、logged_only_errors=(第 6 步的结果成立则为 yes)——并在其下写出学到的内容,至少四行。

说明行中请用自己的话写下“增加标签时的成本(基数)”以及“不过滤 reporter 就求和为什么是错的”。