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提供了一组预配置的仪表板,用于网格和控制平面的所有最重要的指标。
- Mesh Dashboard 提供网格中所有服务的概述。
- Service Dashboard 提供服务指标的详细分类。
- Workload Dashboard 提供工作负载指标的详细分类。
- Performance Dashboard 监视网格的资源使用情况。
- Control Plane Dashboard 监控控制平面的运行状况和性能。
比如控制层平面监控,具体效果如下:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。