在 Istio 中合并监控指标

2022-11-23 14:39:46 浏览数 (1)

前些天阅读 Istio 文档的时候发现个语焉不详的东西:Metrics Merging,原文如下:

This option is enabled by default but can be disabled by passing —set meshConfig.enablePrometheusMerge=false during installation. When enabled, appropriate prometheus.io annotations will be added to all data plane pods to set up scraping. If these annotations already exist, they will be overwritten. With this option, the Envoy sidecar will merge Istio’s metrics with the application metrics. The merged metrics will be scraped from /stats/prometheus:15020.

大致翻译一下:这是一个缺省开放的功能,可以在安装时用 --set meshConfig.enablePrometheusMerge=false 参数停用这个功能。这个功能启用后,相对应的 prometheus.io 注解就会被加入到所有数据面 Pod 上,以启用 Prometheus 的指标抓取能力。如果这些注解已经存在,那么就会被覆盖。有了这样的功能,Envoy Sidecar 就会把应用指标和 Istio 指标进行合并,Prometheus 可以从 :15020/stats/prometheus 拉取合并后的指标。

看完之后,一头雾水。翻翻代码看到另一番说辞:

applyPrometheusMerge configures prometheus scraping annotations for the “metrics merge” feature. This moves the current prometheus.io annotations into an environment variable and replaces them pointing to the agent.

这段代码实现了指标合并功能。它会把当前的 prometheus.io 注解保存到环境变量之中,并且将原有注解替换为指向 Agent 的内容。

再结合相关代码,大概可以推断其功能大致如下:

  1. 网格化微服务在网格化之前使用 prometheus.io 注解标注的抓取方法,会被保存到 Sidecar 的环境变量之中;
  2. 合并指标功能,能够将被网格劫持的微服务输出的 Promethues 指标和 Sidecar 自身指标进行合并,输出到 :15020/stats/prometheus 端点,供 Prometheus 拉取。

我们用 Python 的 Prometheus Exporter SDK 中的测试代码做一个示例应用,并使用如下 Dockerfile 进行打包:

代码语言:javascript复制
FROM python:3.9.13-slim-buster
RUN pip install prometheus-client && mkdir app
COPY server.py /app/server.py
WORKDIR /app
EXPOSE 8000
CMD [ "python3", "server.py" ]

使用 Docker 运行一下,可以看到他输出的简单指标:

代码语言:javascript复制
$ docker run -p 8000:8000 dustise/promclient:v0.1
Unable to find image 'dustise/promclient:v0.1' locally
v0.1: Pulling from dustise/promclient
...
Status: Downloaded newer image for dustise/promclient:v0.1
$ curl http://127.0.0.1:8000
...
# HELP request_processing_seconds_created Time spent processing request
# TYPE request_processing_seconds_created gauge
request_processing_seconds_created 1.6597804647800276e 09
...

会看到指标中是一些请求相关和 Python 特定的内容,这正像我们一个提供了监控指标的微服务,那么如何将这些“业务”指标和 Sidecar 合并输出呢?根据上文,需要加上 Prometheus 的注解,因此我们准备这样一个 YAML:

代码语言:javascript复制
apiVersion: apps/v1
kind: Deployment
...
  template:
    metadata:
...
      annotations:
        prometheus.io/path: /
        prometheus.io/port: 8000
        prometheus.io/scrape: true
    spec:
...
---
apiVersion: v1
kind: Service
...

注入 Sidecar 并提交到集群:istioctl kube-inject -f promclient.yaml | kubectl apply -f -

成功后,可以看看新 Pod 是不是发生了像文档所说的变化:

代码语言:javascript复制
$ kubectl describe po promclient-6c74596f4f-r5z29 | grep prometheus.io
              prometheus.io/path: /stats/prometheus
              prometheus.io/port: 15020
              prometheus.io/scrape: true

看到我们原有的注解的确被替换为缺省内容,那原有内容是不是出现在环境变量之中?

代码语言:javascript复制
$ kubectl exec -it [pod] -c istio-proxy -- env |  | grep ANNO
ISTIO_PROMETHEUS_ANNOTATIONS={"scrape":"true","path":"/","port":"8000"}

果然出现在这里了。那么指标是否完成合并了?采集一下 Pod 的 15020 端口:

代码语言:javascript复制
$ http 10.52.1.11:15020/stats/prometheus | grep python | more
# HELP python_gc_objects_collected_total Objects collected during gc
# TYPE python_gc_objects_collected_total counter
python_gc_objects_collected_total{generation="0"} 101.0
python_gc_objects_collected_total{generation="1"} 273.0
...

可以看到,指标已经被合并到了 Sidecar 指标中之中。

方法简单,但存在一些不适用的场景,例如:

  1. 用 mTLS 抓取指标
  2. 应用指标和 Sidecar 指标重名
  3. Prometheus 未配置按照标准注解进行抓取

遇到上述问题,可能就需要关掉合并功能,采用自定义抓取的方式了。

0 人点赞