Istio服务级指标
服务级指标
-
Istio暴露的服务级指标用于监控服务间通信
-
这类指标涵盖了服务监控的四个基本需求:延迟、流量、错误和饱和度
-
Istio默认配置了一组服务指标(通常也可称为标准指标),并将这些指标导出至Prometheus监控系统
-
舍弃Mixer之后,Istio的这些服务指标则由Envoy代理通过Proxy-wasm插件直接导出
-
服务级指标的旧时代(Telemetry V1)
在Istio 1.4及之前的版本中,服务级别的指标由Mixer提供
服务级指标的新实现(Telemetry V2)
-
实现路径:将服务级指标的实现借助于特定“extension”移入Envoy
-
目标:以被动收集方式实现,从而减少资源消耗,并降低延迟;
-
实现方式
-
静态预编译:需要使用C++编写相关的Filter,并集成到Envoy的源码中,因而需要重新编译和滚动更新
-
动态运行时加载:支持基于WASM(WebAssembly)来动态加载Filter,完成Envoy扩展
-
-
-
Istio Telemetry V2使用两个自定义的Envoy插件实现服务级指标
-
metadata-exchange
-
用于提供有关连接双方(Client/Server)的元数据
-
HTTP流量:使用自定义标头envoy.wasm.metadata_exchange.upstream和envoy.wasm.metadata_exchange.downstream
-
TCP流量:使用基于ALPN的隧道和基于前缀的协议,istio-peer-exchange
-
-
stats
-
负责将传入和传出的流量指标记录到Envoy统计子系统中,并使其可供Prometheus抓取
-
stats源码:https://github.com/istio/proxy/tree/master/extensions/stats
-
相关指标定义在plugin.cc文件的MetricFactory中
-
-
其暴露的指标称为标准服务指标或默认服务指标
-
-
Istio的服务级指标
-
针对HTTP、HTTP/2和GRPC流量的指标
-
Request Count (istio_requests_total):处理的总请求数,COUNTER类型;
-
Request Duration (istio_request_duration_milliseconds):请求的持续时长,HISTOGRAM类型;
-
Request Size (istio_request_bytes):请求体大小,HISTOGRAM类型;
-
Response Size (istio_response_bytes):响应体大小,HISTOGRAM类型;
-
gRPC Request Message Count (istio_request_messages_total):gRPC连接,请求消息总数;
-
gRPC Response Message Count (istio_response_messages_total):gRPC连接,响应消息总数;
-
-
针对TCP流量的指标
-
Tcp Bytes Sent (istio_tcp_sent_bytes_total):在TCP连接中总共发送的字节数,COUNTER类型;
-
Tcp Bytes Received (istio_tcp_received_bytes_total):在TCP连接中总共接收的字节数,COUNTER类型;
-
Tcp Connections Opened (istio_tcp_connections_opened_total):总共打开的TCP连接数量,COUNTER类型;
-
Tcp Connections Closed (istio_tcp_connections_closed_total):总共关闭的TCP连接数量, COUNTER类型;
-
在Istio网格中启动stats扩展中定义的指标
- Istio默认启用的服务级指标,是在首次部署Istio时由通过自动创建的EnvoyFilter资源定义的
- 这些EnvoyFilter资源定义在网格名称空间(例如istio-system)下
-
获取命令:~$ kubectl get envoyfilters -n istio-system
-
-
以envoyfiler/stats-filter-1.15资源为例
-
该EnvoyFilter用于配置名为envoy.wasm.stats的过滤器
-
各指标为自动添加一个istio前缀
-
-
三种类型的Envoy实例需要经context匹配后分别进行配置
-
SIDECAR_OUTBOUND
-
SIDECAR_INBOUND
-
GATEWAY
-
- 这些EnvoyFilter资源定义在网格名称空间(例如istio-system)下
-
注意
- 出于性能的考虑,该Wasm插件是直接编译进Envoy的,而非运行于Wasm VM中
- 但Istio也提供独立的stats Wasm插件,或要Istio将之运行为独立插件,可在部署istio时使用如下选项进行启用
-
--set values.telemetry.v2.prometheus.wasmEnabled=true
-
获取Envoy上的服务级指标
-
验证服务级指标
-
获取该Pod上的prometheus指标(由Envoy直接导出的prometheus格式的指标)
-
kubectl exec $POD_NAME -n default -- curl -sS localhost:15000/stats/prometheus | grep -o “^istio_[a-zA-Z_]*” | sort -u
-
kubectl exec $POD_NAME -c istio-proxy -- pilot-agent request GET /stats/prometheus | grep -o "^istio_[a-zA-Z_]*" | sort -u
- curl -sS `kubectl get pod -l app=proxy -o jsonpath='{.items[0].status.podIP}'`:15020/stats/prometheus
-
提示:对于不同的工作负载来说,服务使用的协议,以及获取指标的时间点不同,可获得的指标可能有所不同
-
-
- 这些默认的服务级指标,可在部署Istio时,于IstioOperator资源配置中的values.telemetry.v2.prometheus配置段中进行修改
服务级指标相关的时间序列
- Istio基于stats和metadata-exchange扩展,以及几个EnvoyFilter资源来控制指标的创建、配置及显示,这其中有三个重要概念
-
metric:指标名称
-
dimension:维度,标签
-
attribute:通信连接相关的属性,用作标签值
-
-
服务级指标的标识方式
-
通信双方
-
Server Workload:请求流量中的入站方(Inbound)
-
Client Workload:请求流量中的出站方(Outbound)
-
-
在同一个metric上使用不同的dimension,即代表着不同的时间序列
-
dimension中的各标签值来自于通信双方相关报文或连接的attribute
-
服务级指标上默认使用的标签
-
Reporter:该指标reporter的身份标识
-
reporter是服务端Sidecar Envoy时,其值为destination;
-
reporter是客户端Sidecar Envoy或Ingress Gateway时,其值为source;
-
-
Source Workload:源工作负载的标识,缺少相关信息时,则标识为unknown;
-
Source Workload Namespace:源工作负载所在名称空间,缺少相关信息时,则标识为unknown;
-
Source Principal:源工作负载的身份标识,通常为相关工作负载的SPIFFIE ID;
-
Source App:源应用程序名称,其值为相应工作负载上app标签的值,缺少相关信息时标识为unknown;
-
Source Version:源应用程序版本,其值为相应工作负载上version标签的值,缺少相关信息时标识为unknown;
-
Destination Workload:目标工作负载的标识,缺少相关信息时,则标识为unknown;
-
Destination Workload Namespace:目标工作负载所在名称空间,缺少相关信息时,则标识为unknown;
-
Destination Principal:目标工作负载的身份标识,通常为相关工作负载的SPIFFIE ID;
-
Destination App:目标应用程序名称,其值为相应工作负载上app标签的值;
-
Destination Version:源应用程序版本,其值为相应工作负载上version标签的值,缺少相关信息时标识为unknown;
-
Destination Service:请求报文中的目标服务(即目标主机),例如demoapp.default.svc.cluster.local;
-
Destination Service Name:目标服务的名称,例如demoapp;
-
Destination Service Namespace:目标服务所在的名称空间;
-
Request Protocol:请求时使用的协议,通常为请求协议或连接协议;
-
Response Code:请求对应的响应码,但仅对HTTP协议相关的指标有效;
-
Connection Security Policy:请求中使用的认证策略;
-
由Istio负责实施安全策略,且reporter为destination时,标识为mutual_tls;
-
若reporter为source,则会因无法正确识别安全策略而标识为unknown;
-
-
Response Flags:响应标志,其值通常为Envoy访问日志中“%RESPONSE_FLAGS% ”对应的内容;
- Canonical Service:尽管其可以从属于多个服务,但一个workload却仅能隶属于一个规范(canonical)服务,于是,指标上还会基于服务的名称和版本附带生成如下标签
-
source_canonical_service 和 source_canonical_revision
-
destination_canonical_service 和 destination_canonical_revision
-
-
Destination Cluster:目标workload所在的集群;
-
Source Cluster:源workload所在的集群;
配置服务级指标
-
配置服务级指标时,各指标的标签值通常要引用自连接的属性(attribute)信息,开箱可用的有
-
由metadata-exchange扩展提供的tcp连接的有关属性
-
HTTP请求属性
-
Envoy在连接上支持使用的各类属性
-
TCP连接相关属性
HTTP请求相关属性
Stats Config
-
MetricConfig(指标配置)支持使用的字段
-
dimensions:数据类型map<string, string>,在指标上要操作的标签名称及相关的表达式
-
name:string,指标的名称,省略时表示所有指标
-
tags_to_remove:string[],要移除的标签列表
-
match:条件式override,目前(Istio v1.12.1)尚未实现该功能
-
-
MetricDefinition(指标定义)支持使用的字段
-
name:string,指标名称
-
value:string,指标值表达式
-
type:MetricType,指标类型,目前(Istio v1.12.1)尚未实现该功能
-
-
MetricType
-
COUNTER
-
GAUGE
-
HISTOGRAM
-
控制平面指标
-
控制平面指标
-
由istiod负责暴露,使用的端口为15014/tcp
-
用于监控istiod自身的状况
-
-
指标组
-
citadel
-
galley
-
pilot
-
istiod
-
process
-
webhook
-
sidecar_injection
-
-
各指标介绍
-
文档:https://istio.io/latest/docs/reference/commands/pilot-discovery/#metrics
-
stats-filter-1.15
~# kubectl get envoyfilters stats-filter-1.15 -o yaml -n istio-system
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.istio.io/v1alpha3","kind":"EnvoyFilter","metadata":{"annotations":{},"labels":{"install.operator.istio.io/owning-resource-naespace":"istio-system"},"spec":{"configPatches":[{"applyTo":"HTTP_FILTER","match":{"context":"SIDECAR_OUTBOUND","listener":{"filterChain":{"filter":{"name":o.stats","typed_config":{"@type":"type.googleapis.com/udpa.type.v1.TypedStruct","type_url":"type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm",m_config":{"code":{"local":{"inline_string":"envoy.wasm.stats"}},"runtime":"envoy.wasm.runtime.null","vm_id":"stats_outbound"}}}}}}},{"applyTo":"HTTP_FILTERxyVersion":"^1\\.15.*"}},"patch":{"operation":"INSERT_BEFORE","value":{"name":"istio.stats","typed_config":{"@type":"type.googleapis.com/udpa.type.v1.TypedSug\": \"false\",\n \"stat_prefix\": \"istio\",\n \"disable_host_header_fallback\": true\n}\n"},"root_id":"stats_inbound","vm_config":{"code":{"local":{"ine":"envoy.filters.network.http_connection_manager","subFilter":{"name":"envoy.filters.http.router"}}}},"proxy":{"proxyVersion":"^1\\.15.*"}},"patch":{"operam","value":{"config":{"configuration":{"@type":"type.googleapis.com/google.protobuf.StringValue","value":"{\n \"debug\": \"false\",\n \"stat_prefix\": \"istats_outbound"}}}}}}}],"priority":-1}}
creationTimestamp: "2022-10-20T10:34:44Z"
generation: 1
labels:
install.operator.istio.io/owning-resource-namespace: istio-system
istio.io/rev: default
operator.istio.io/component: Pilot
operator.istio.io/managed: Reconcile
operator.istio.io/version: 1.15.2
name: stats-filter-1.15
namespace: istio-system
resourceVersion: "93367"
uid: 11acfeea-cabb-4927-91bb-bd89242249b8
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_OUTBOUND
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
proxy:
proxyVersion: ^1\.15.*
patch:
operation: INSERT_BEFORE
value:
name: istio.stats
typed_config:
'@type': type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
configuration:
'@type': type.googleapis.com/google.protobuf.StringValue
value: |
{
"debug": "false",
"stat_prefix": "istio"
}
root_id: stats_outbound
vm_config:
code:
local:
inline_string: envoy.wasm.stats
runtime: envoy.wasm.runtime.null
vm_id: stats_outbound
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
proxy:
proxyVersion: ^1\.15.*
patch:
operation: INSERT_BEFORE
value:
name: istio.stats
typed_config:
'@type': type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
configuration:
'@type': type.googleapis.com/google.protobuf.StringValue
value: |
{
"debug": "false",
"stat_prefix": "istio",
"disable_host_header_fallback": true
}
root_id: stats_inbound
vm_config:
code:
local:
inline_string: envoy.wasm.stats
runtime: envoy.wasm.runtime.null
vm_id: stats_inbound
- applyTo: HTTP_FILTER
match:
context: GATEWAY
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
proxy:
proxyVersion: ^1\.15.*
patch:
operation: INSERT_BEFORE
value:
name: istio.stats
typed_config:
'@type': type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
configuration:
'@type': type.googleapis.com/google.protobuf.StringValue
value: |
{
"debug": "false",
"stat_prefix": "istio",
"disable_host_header_fallback": true
}
root_id: stats_outbound
vm_config:
code:
local:
inline_string: envoy.wasm.stats
runtime: envoy.wasm.runtime.null
vm_id: stats_outbound
priority: -1
参考文档
https://istio.io/latest/zh/docs/tasks/observability/metrics/customize-metrics/