Istio服务网格最流行和最强大的功能之一就是其先进的可观察性。因为所有服务到服务的通信都是通过Envoy代理路由的,并且Istio的控制平面能够从这些代理收集日志和指标,所以服务网格可以为我们提供有关网络状态和服务行为的深刻见解。这为运营商提供了独特的故障排除,管理和优化服务方式,而不会给应用程序开发人员带来任何额外的负担。

因此,运营商可以深入了解受监控的服务如何在入站和出站方向上进行交互。这些指标提供了各种信息,包括总流量,错误率和请求响应时间。

快速回顾Istio遥测指标

PROXY-LEVEL METRICS

代理级指标是Envoy代理本身提供的有关所有直通流量的标准指标,以及有关代理管理功能的详细统计信息,包括配置和运行状况信息。

Envoy生成的度量标准存在于Envoy资源(例如侦听器和集群)的粒度级别上。

proxy-level Metrics 示例

# TYPE envoy_cluster_internal_upstream_rq_200 counter
envoy_cluster_internal_upstream_rq_200{cluster_name="xds-grpc"} 2

# TYPE envoy_cluster_upstream_rq_200 counter
envoy_cluster_upstream_rq_200{cluster_name="xds-grpc"} 2

# TYPE envoy_cluster_upstream_rq_completed counter
envoy_cluster_upstream_rq_completed{cluster_name="xds-grpc"} 3

# TYPE envoy_cluster_internal_upstream_rq_503 counter
envoy_cluster_internal_upstream_rq_503{cluster_name="xds-grpc"} 1

# TYPE envoy_cluster_upstream_cx_rx_bytes_total counter
envoy_cluster_upstream_cx_rx_bytes_total{cluster_name="xds-grpc"} 2056154

# TYPE envoy_server_memory_allocated gauge
envoy_server_memory_allocated{} 15853480

SERVICE-LEVEL METRICS

除了代理级别的度量标准之外,Istio还提供了一组面向服务的度量标准,用于监控服务通信。这些指标涵盖了四个基本的服务监视需求:延迟,流量,错误和饱和。

Istio附带了一组默认的仪表板,用于根据这些指标监视服务行为。

service-level metric 示例

# TYPE istio_requests_total counter
istio_requests_total{
    connection_security_policy="mutual_tls",
    destination_app="analytics",
    destination_principal="cluster.local/ns/backyards-demo/sa/default",
    destination_service="analytics.backyards-demo.svc.cluster.local",
    destination_service_name="analytics",
    destination_service_namespace="backyards-demo",
    destination_version="v1",
    destination_workload="analytics-v1",
    destination_workload_namespace="backyards-demo",
    permissive_response_code="none",
    permissive_response_policyid="none",
    reporter="destination",
    request_protocol="http",
    response_code="200",
    response_flags="-",
    source_app="bookings",
    source_principal="cluster.local/ns/backyards-demo/sa/default",
    source_version="v1",
    source_workload="bookings-v1",
    source_workload_namespace="backyards-demo"
} 1855

Istio telemetry with Mixer

直到Istio 1.4为止,Istio的服务级别指标都是由称为Mixer的中央组件提供的。

telemetry-with-mixer.png

在每次报告遥测请求后,Envoy Sidecar都会调用Mixer,而Mixer提供了Prometheus指标终结点以公开收集的指标,从而使它们可用于抓取。代理将有关请求的源端和目标端的数据发送到每个报告中的Mixer,最重要的是源和目标工作负载的唯一ID(在K8s环境中基本上是唯一的Pod ID),这是Mixer的责任从K8中获取其他元数据,并将指标显示在特定端点上以供Prometheus抓取。

尽管Envoy Sidecar可以缓冲传出的遥测请求,但该体系结构在较大的环境中会产生大量的资源消耗。每个代理和Mixer之间必须建立活动连接。显然,这会导致代理中更高的CPU和内存消耗,随后还会导致更高的延迟。

Istio telemetry V2

为了减少代理的资源消耗并(同样重要的是)降低增加的延迟,遥测功能从头开始重新构造。它以较小的CPU占用空间从主动收集转向被动收集。

较旧的Envoy版本不容易扩展,向Envoy添加扩展需要一个整体的构建过程,并且扩展必须使用C++编写。需要部署二进制文件,需要滚动更新等,并且整个过程难以管理。尽管如此,仍通过定制的Envoy支持基于Mixer的实现,该Envoy具有所有必需的功能。

由于Istio Telemetry V2缺少可访问K8s元数据的中央组件(Mixer),因此代理服务器本身需要提供丰富指标所需的元数据。此外,必须将Enmixer提供的功能添加到Mixer中,以替代基于Mixer的遥测技术。 Istio Telemetry V2使用两个自定义的Envoy插件来实现这一目标。

telemetry-v2.png

根据Istio文档,新的遥测系统将等待时间减少了一半-90%的等待时间已从7毫秒减少到3.3毫秒。不仅如此,消除Mixer还使总CPU消耗减少了50%,降至每秒每1,000个请求0.55个vCPU。

WASM

WebAssembly(通常缩写为WASM)是一个开放标准,为可执行程序定义了一种可移植的二进制代码格式,以及一种相应的文本汇编语言,以及有助于程序与其主机环境之间进行交互的接口。

WebAssembly的主要目标是在网页上启用高性能应用程序,但是该格式还旨在在其他环境中执行和集成。它提供了一个基于精益堆栈的虚拟机,它通过利用快速加载的二进制格式(可以将其转换为文本格式进行调试)来使Web应用程序以接近本机的速度运行。而且,尽管WebAssembly最初是作为客户端技术而诞生的,但在服务器端使用它具有许多优点。

Istio社区一直在领导Envoy的WebAssembly(WASM)运行时的实现。该实现使用基于Google高性能V8引擎构建的WebAssembly运行时。

使用Envoy的WebAssembly插件,开发人员可以编写其自定义代码,将其编译为WebAssembly插件,并配置Envoy来执行它。这些插件可以包含任意逻辑(这是简单的代码!),因此它们对于各种消息集成和变异很有用。

Telemetry V2中的代理内服务级别指标由两个自定义插件提供,即元数据交换统计信息

默认情况下,在Istio 1.5中,启用遥测V2是在Istio代理过滤器中编译的,主要是出于性能方面的考虑。相同的Filter也将编译为WebAssembly(WASM)模块,并随Istio代理一起提供。在即将发布的版本中,性能将不断提高。

元数据交互插件

必须解决的第一个问题是如何在代理中提供有关连接两侧的客户端/服务器元数据。

对于基于HTTP的流量,这是通过包含对方的元数据属性的请求/响应中的自定义HTTP标头(envoy.wasm.metadata_exchange.upstream,envoy.wasm.metadata_exchange.downstream)完成的。

对于一般的TCP通信,元数据交换使用基于ALPN的隧道和基于前缀的协议。定义了一个新的协议istio-peer-exchange,该协议由网状网络中的客户端和服务器Sidecar通告并确定优先级。对于启用Istio的代理之间的连接,但不是启用Istio的代理与任何客户端之间的连接,ALPN协商将协议解析为istio-peer-exchange。

统计信息插件

stats插件将传入和传出的流量指标记录到Envoy统计子系统中,并使它们可供Prometheus抓取。

以下是默认情况下导出的标准服务级别指标。

  • 对于HTTP,HTTP/2和GRPC流量,代理将生成以下指标:

    Name Description
    istio_requests_total This is a COUNTER incremented for every request handled by an Istio proxy.
    istio_request_duration_milliseconds This is a DISTRIBUTION which measures the duration of requests.
    istio_request_bytes This is a DISTRIBUTION which measures HTTP request body sizes.
    istio_response_bytes This is a DISTRIBUTION which measures HTTP response body sizes.
  • 对于TCP流量,代理会生成以下指标:

    Name Description
    istio_tcp_sent_bytes_total This is a COUNTER which measures the size of total bytes sent during response in case of a TCP connection.
    istio_tcp_received_bytes_total This is a COUNTER which measures the size of total bytes received during request in case of a TCP connection.
    istio_tcp_connections_opened_total This is a COUNTER incremented for every opened connection.
    istio_tcp_connections_closed_total This is a COUNTER incremented for every closed connection.
  • 以下是服务级别指标上的默认标签:

    reporter: conditional((context.reporter.kind | "inbound") == "outbound", "source", "destination")
    source_workload: source.workload.name | "unknown"
    source_workload_namespace: source.workload.namespace | "unknown"
    source_principal: source.principal | "unknown"
    source_app: source.labels["app"] | "unknown"
    source_version: source.labels["version"] | "unknown"
    destination_workload: destination.workload.name | "unknown"
    destination_workload_namespace: destination.workload.namespace | "unknown"
    destination_principal: destination.principal | "unknown"
    destination_app: destination.labels["app"] | "unknown"
    destination_version: destination.labels["version"] | "unknown"
    destination_service: destination.service.host | "unknown"
    destination_service_name: destination.service.name | "unknown"
    destination_service_namespace: destination.service.namespace | "unknown"
    request_protocol: api.protocol | context.protocol | "unknown"
    response_code: response.code | 200
    connection_security_policy: conditional((context.reporter.kind | "inbound") == "outbound", "unknown", conditional(connection.mtls | false, "mutual_tls", "none"))
    response_flags: context.proxy_error_code | "-"
    source_canonical_service
    source_canonical_revision
    destination_canonical_service
    destination_canonical_revision

Istio 1.5中的stats插件不仅包含标准指标,而且还提供了对它们进行修改的实验性支持。请注意,由于新的扩展API设计,在Istio 1.6中将更改用于配置指标的API。

基于mixer的遥测和Telemetry V2之间的功能区别

虽然1.5版不推荐使用Mixer;它是一个高度可配置的组件,并提供许多功能。 Mixer提供的遥测功能与V2提供的功能之间存在很大的功能差别。

  • 不完全支持出网格遥测:缺少某些度量标准(Sidecar未注入流量源或目的地)。
  • 不支持出口网关遥测。
  • 仅mTLS支持TCP遥测。
  • 不支持用于TCP和HTTP协议的黑洞遥测。
  • 直方图桶与基于Mixer的桶明显不同。
  • 自定义指标支持是实验性的,并且功能有限。

iyacontrol
1.4k 声望2.7k 粉丝

专注kubernetes,devops,aiops,service mesh。