1

Istio为网格内的所有服务通信生成详细的遥测。这种遥测功能提供了服务行为的可观察性,使运维同学可以对应用程序进行故障排除,维护和优化,而不会给服务开发人员带来任何额外负担。通过Istio,可以全面了解受监控的服务如何与其他服务以及与Istio组件本身进行交互。

Istio生成以下遥测类型,以提供整体服务网格可观察性:

  • Metrics. Istio根据监控的四个“黄金信号”(延迟,流量,错误和饱和度)生成一组服务指标。 Istio还提供了网格控制平面的详细指标。还提供了基于这些指标构建的一组默认的网格监控仪表板。
  • Distributed Traces. Istio为每种服务生成分布式跟踪范围,从而使我们可以详细了解网格中的调用流程和服务依赖性。
  • Access Logs. 当流量流入网格内的服务时,Istio可以生成每个请求的完整记录,包括源和目标元数据。该信息使我们能够审核服务行为,可以到单个工作负载实例级别。

本文我们主要讲述metrcis。

Metrcis简介

在大多数情况下,指标是可观察性的起点。它们的收集成本低,存储成本低,便于快速分析,并且是衡量整体健康状况的好方法。
为了监控服务行为,Istio会为Istio服务网格内,外所有服务流量生成指标。这些度量标准提供有关行为的信息,例如总流量,流量中的错误率以及请求的响应时间。
除了监控网格内服务的行为外,监控网格本身的行为也很重要。 Istio组件根据自己的内部行为导出度量标准,以提供有关网格控制平面的运行状况和功能的见解。

下面我们详细讲下以下:

  • 代理级别指标
  • 服务级别指标
  • 控制层指标

代理级别指标

Istio指标收集从Sidecar代理(Envoy)开始。每个代理都会生成一组丰富的指标,用于衡量通过代理的所有流量(入站和出站)。代理还提供有关代理本身的管理功能的详细统计信息,包括配置和运行状况信息。

Envoy生成的度量标准以Envoy资源(例如侦听器和集群)的粒度提供对网格的监视。因此,需要了解网状服务和Envoy资源之间的连接才能监视Envoy指标。

Istio使我们可以选择在每个工作负载实例中生成和收集哪些Envoy指标。默认情况下,Istio仅启用Envoy生成的统计信息的一小部分,以避免过多的度量标准后端并减少与度量标准收集相关的CPU开销。但是,我们可以在需要时轻松扩展收集的代理指标集。这样可以针对性地调试网络行为,同时降低mesh监控的总成本。

Envoy官方文档包括Envoy统计信息收集的详细概述。 Envoy Statistics上的操作指南提供了有关控制代理级度量标准生成的更多信息。

代理级别指标示例:

envoy_cluster_internal_upstream_rq{response_code_class="2xx",cluster_name="xds-grpc"} 7163

envoy_cluster_upstream_rq_completed{cluster_name="xds-grpc"} 7164

envoy_cluster_ssl_connection_error{cluster_name="xds-grpc"} 0

envoy_cluster_lb_subsets_removed{cluster_name="xds-grpc"} 0

envoy_cluster_internal_upstream_rq{response_code="503",cluster_name="xds-grpc"} 1

服务级别指标

除了代理级别的度量标准之外,Istio还提供了一组面向服务的度量标准,用于监控服务通信。这些指标涵盖了四个基本的服务监视需求:延迟,流量,错误和饱和度。 Istio附带了一组默认的仪表板,用于根据这些指标监视服务行为。
默认情况下,标准Istio指标会导出到Prometheus。
服务级别指标的使用完全是可选的。运维同学可以选择关闭这些指标的生成和收集,以满足他们的个性化需求。

服务级别指标示例:

istio_requests_total{
  connection_security_policy="mutual_tls",
  destination_app="details",
  destination_canonical_service="details",
  destination_canonical_revision="v1",
  destination_principal="cluster.local/ns/default/sa/default",
  destination_service="details.default.svc.cluster.local",
  destination_service_name="details",
  destination_service_namespace="default",
  destination_version="v1",
  destination_workload="details-v1",
  destination_workload_namespace="default",
  reporter="destination",
  request_protocol="http",
  response_code="200",
  response_flags="-",
  source_app="productpage",
  source_canonical_service="productpage",
  source_canonical_revision="v1",
  source_principal="cluster.local/ns/default/sa/default",
  source_version="v1",
  source_workload="productpage-v1",
  source_workload_namespace="default"
} 214

控制层指标

Istio控制平面还提供了一系列自我监控指标。这些度量标准允许监视Istio本身的行为(与网格内服务的行为不同)。

主要包括pilot,galley等组件指标。更多相关信息可以参阅官方文档

最佳实践

所谓最佳实践,只要包括以下两个方面:

  • 生产环境具备扩展性的Prometheus -- 单机Prometheus采集和存储能力有限,而istio保留出了丰富的指标,所以必须提供一个高可用的弹性Prometheus集群。关于这点,本文我们不会详细阐述,大家可以通过thanos,cortex等开源项目,对prometheus进行扩展。
  • 通过recording rules 对一些指标进行预聚合。

比如为了聚合实例和容器之间的度量,使用以下recording rules更新默认的Prometheus配置:

groups:
- name: "istio.recording-rules"
  interval: 5s
  rules:
  - record: "workload:istio_requests_total"
    expr: |
      sum without(instance, namespace, pod) (istio_requests_total)

  - record: "workload:istio_request_duration_milliseconds_count"
    expr: |
      sum without(instance, namespace, pod) (istio_request_duration_milliseconds_count)

  - record: "workload:istio_request_duration_milliseconds_sum"
    expr: |
      sum without(instance, namespace, pod) (istio_request_duration_milliseconds_sum)

  - record: "workload:istio_request_duration_milliseconds_bucket"
    expr: |
      sum without(instance, namespace, pod) (istio_request_duration_milliseconds_bucket)

  - record: "workload:istio_request_bytes_count"
    expr: |
      sum without(instance, namespace, pod) (istio_request_bytes_count)

  - record: "workload:istio_request_bytes_sum"
    expr: |
      sum without(instance, namespace, pod) (istio_request_bytes_sum)

  - record: "workload:istio_request_bytes_bucket"
    expr: |
      sum without(instance, namespace, pod) (istio_request_bytes_bucket)

  - record: "workload:istio_response_bytes_count"
    expr: |
      sum without(instance, namespace, pod) (istio_response_bytes_count)

  - record: "workload:istio_response_bytes_sum"
    expr: |
      sum without(instance, namespace, pod) (istio_response_bytes_sum)

  - record: "workload:istio_response_bytes_bucket"
    expr: |
      sum without(instance, namespace, pod) (istio_response_bytes_bucket)

  - record: "workload:istio_tcp_connections_opened_total"
    expr: |
      sum without(instance, namespace, pod) (istio_tcp_connections_opened_total)

  - record: "workload:istio_tcp_connections_closed_total"
    expr: |
      sum without(instance, namespace, pod) (istio_tcp_connections_opened_total)

  - record: "workload:istio_tcp_sent_bytes_total_count"
    expr: |
      sum without(instance, namespace, pod) (istio_tcp_sent_bytes_total_count)

  - record: "workload:istio_tcp_sent_bytes_total_sum"
    expr: |
      sum without(instance, namespace, pod) (istio_tcp_sent_bytes_total_sum)

  - record: "workload:istio_tcp_sent_bytes_total_bucket"
    expr: |
      sum without(instance, namespace, pod) (istio_tcp_sent_bytes_total_bucket)

  - record: "workload:istio_tcp_received_bytes_total_count"
    expr: |
      sum without(instance, namespace, pod) (istio_tcp_received_bytes_total_count)

  - record: "workload:istio_tcp_received_bytes_total_sum"
    expr: |
      sum without(instance, namespace, pod) (istio_tcp_received_bytes_total_sum)

  - record: "workload:istio_tcp_received_bytes_total_bucket"
    expr: |
      sum without(instance, namespace, pod) (istio_tcp_received_bytes_total_bucket)

原理

暴露指标

默认条件下,istio通过为控制平面和数据平面的Pod增加注解的方式,告诉Prometheus采集指标的端口和路径。

比如控制层istiod组件:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    prometheus.io/port: "15014"
    prometheus.io/scrape: "true"
    sidecar.istio.io/inject: "false"
  labels:
    app: istiod

istiod 在端口15014暴露metrcis。

对于istio-ingressgateway :

apiVersion: v1
kind: Pod
metadata:
  annotations:
    prometheus.io/path: /stats/prometheus
    prometheus.io/port: "15090"
    prometheus.io/scrape: "true"
    sidecar.istio.io/inject: "false"
  labels:
    app: istio-ingressgateway

istio-ingressgateway 在端口15090暴露metrcis。

对于数据平面的代理:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    prometheus.io/path: /stats/prometheus
    prometheus.io/port: "15020"
    prometheus.io/scrape: "true" 
  labels:
    app: helloworld

proxy 在端口15020暴露metrcis。

由于ingressgateway和代理均为基于envoy实现,所以其metrcis路径均为/stats/prometheus。

Prometheus配置

此时我们配置我们的prometheus收集这些数据即可。实际上,就是典型的prometheus k8s 服务发现功能,具体就是对于pod的自动发现。

如下:

 scrape_configs:
              - job_name: kubernetes-pods
                kubernetes_sd_configs:
                - role: pod
                relabel_configs:
                - action: keep
                  regex: true
                  source_labels:
                  - __meta_kubernetes_pod_annotation_prometheus_io_scrape
                - action: replace
                  regex: (.+)
                  source_labels:
                  - __meta_kubernetes_pod_annotation_prometheus_io_path
                  target_label: __metrics_path__
                - action: replace
                  regex: ([^:]+)(?::d+)?;(d+)
                  replacement: $1:$2
                  source_labels:
                  - __address__
                  - __meta_kubernetes_pod_annotation_prometheus_io_port
                  target_label: __address__
                - action: labelmap
                  regex: __meta_kubernetes_pod_label_(.+)
                - action: replace
                  source_labels:
                  - __meta_kubernetes_namespace
                  target_label: kubernetes_namespace
                - action: replace
                  source_labels:
                  - __meta_kubernetes_pod_name
                  target_label: kubernetes_pod_name

至此指标已经收集到我们的监控系统中了,接下来就是展示。

Grafana展示

Grafana是一个开源监视解决方案,可用于为Istio配置仪表板。您可以使用Grafana监视Istio以及服务网格中应用程序的运行状况。

虽然您可以构建自己的仪表板,但Istio提供了一组预配置的仪表板,用于网格和控制平面的所有最重要的指标。

比如控制层平面监控,具体效果如下:


iyacontrol
1.4k 声望2.7k 粉丝

专注kubernetes,devops,aiops,service mesh。