无代理 gRPC 的可观测性

Cloud Service Mesh Observability,用于基于 现有的 gRPC OpenTelemetry 插件 记录所有 gRPC 通道和服务器的指标(延迟时间、消息大小等) 即已启用 Cloud Service Mesh,并提供 显示 Cloud Service Mesh 流量的拓扑网格信息。如果 gRPC 通道从 Cloud Service Mesh 控制平面获取配置,则会被视为启用了 Cloud Service Mesh;而所有 gRPC 服务器都被视为启用了 Cloud Service Mesh。

网格属性

指标提供以下网格属性。

本地环境标签:

  • csm.mesh_id
    • 网格 ID。
  • 其他本地环境属性从 OpenTelemetry 资源
    • 您可以将 Managed Service for Prometheus (GMP) 设置为使用 Google 基础架构存储指标。如果使用此参数 描述应用本地环境的资源属性包括 自动添加到 MonitoredResource
    • 如果使用非 Google 基础架构来导出和存储指标, 收集流水线应该在描述 运行应用的环境

远程环境标签:

  • csm.remote_workload_type
    • 远程对等方的类型。(GKE 中的“gcp_kubernetes_engine”)。
  • 根据对等方的类型,系统会显示其他属性。
    • 对于在 GKE 上运行的对等方:
    • csm.remote_workload_project_id
      • 与此资源关联的项目的标识符,例如“my-project”。
    • csm.remote_workload_location *包含容器的集群的实际位置。
    • csm.remote_workload_cluster_name
      • 容器运行所在的集群。
    • csm.remote_workload_namespace_name
      • The namespace where the container is running.
    • csm.remote_workload_name
      • 远程工作负载的名称。这应是包含 Pod 定义的对象的名称(例如 Deployment、ReplicaSet,或者仅为裸 Pod 的 Pod 名称)。

服务标签:有关 RPC 的后端服务(xDS 集群)的信息 正在被路由到的另一个 IP 地址。请注意,只有在通过 Gateway API 配置了后端服务的情况下,此方法才可用。

  • csm.service_name
    • 服务名称。
  • csm.service_namespace_name
    • 服务命名空间名称。

术语 remote_workload 是指对等方,也就是说,对于客户端,RPC 的目标服务器 Pod 是远程工作负载,而对于服务器,发起 RPC 的客户端 Pod 是远程工作负载。

请注意,grpc.client.attempt.startedgrpc.server.call.started 上不会提供这些属性,因为这些指标的收集点无法提供所有拓扑网格信息。

可观测性设置说明

本部分介绍如何为以下各项启用 Cloud Service Mesh 可观测性: 服务网格设置上的无代理 gRPC。

C++

可观测性支持只能通过 Bazel 构建系统获得。需要将目标 grpcpp_csm_observability 添加为依赖项

所需的代码更改

您需要将以下代码添加到 gRPC 客户端和服务器,才能使用 Cloud Service Mesh 可观测性功能。

#include <grpcpp/ext/csm_observability.h>

int main() {
  // …
  auto observability = grpc::CsmObservabilityBuilder()
                          .SetMeterProvider(std::move(meter_provider))
                          .BuildAndRegister();
  assert(observability.ok());
  // …
}

在执行任何 gRPC 操作(包括创建通道、服务器或凭据)之前,请使用 CsmObservabilityBuilder API 注册插件。以下示例 介绍了如何使用 Prometheus 设置 Cloud Service Mesh 可观测性 导出器。

  opentelemetry::exporter::metrics::PrometheusExporterOptions opts;
  opts.url = "0.0.0.0:9464";
  auto prometheus_exporter =
      opentelemetry::exporter::metrics::PrometheusExporterFactory::Create(opts);
  auto meter_provider =
      std::make_shared<opentelemetry::sdk::metrics::MeterProvider>();
  meter_provider->AddMetricReader(std::move(prometheus_exporter));
  auto observability = grpc:::CsmObservabilityBuilder()
                          .SetMeterProvider(std::move(meter_provider))
                          .BuildAndRegister();

CsmObservabilityBuilder() 上的 SetMeterProvider() API 允许用户设置可与导出程序配置的 MeterProvider 对象。

Java

如需为 Java gRPC 应用启用 Cloud Service Mesh 可观测性,请执行以下操作: 请执行以下步骤:

  1. 确保项目包含 grpc-gcp-csm-observability 工件。使用 gRPC 1.65.0 或更高版本。

  2. main() 方法中,通过提供 配置了包含 MeterProvider 的 OpenTelemetry SDK 实例 和导出指标。

    在执行任何 gRPC 操作(例如设置通道或服务器)之前,请务必使用 CsmObservability.Builder() API 注册 OpenTelemetry SDK。

    创建 CsmObservability 实例后,对该实例调用 registerGlobal() 即可为所有 Cloud Service Mesh 渠道和服务器启用 Cloud Service Mesh 可观测性。

    以下示例演示了如何使用 Prometheus 导出器设置 Cloud Service Mesh 可观测性。

import io.grpc.gcp.csm.observability.CsmObservability;
...

public static void main(String[] args) {
    ...

    int prometheusPort = 9464;

    SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
        .registerMetricReader(
            PrometheusHttpServer.builder().setPort(prometheusPort).build())
        .build();

    OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder()
        .setMeterProvider(sdkMeterProvider)
        .build();

    CsmObservability observability = new CsmObservability.Builder()
        .sdk(openTelemetrySdk)
        .build();
    observability.registerGlobal();

    // ... (continue with channel and server configuration)
}

Go

在执行任何 gRPC 操作(包括创建 ClientConn 或服务器)之前,或 使用 Cloud Storage 存储分区中的 MeterProvider。以下示例展示了如何设置 Cloud Service Mesh 可观测性。设置 Cloud Service Mesh Observability 后,任何 Cloud Service Mesh 渠道和所有服务器都会选择使用提供的选项和其他 Cloud Service Mesh 标签配置的 OpenTelemetry 统计插件。非 Cloud Service Mesh 渠道将获得不含 Cloud Service Mesh 标签的 OpenTelemetry 统计插件。

  import (
  "context"

  "google.golang.org/grpc/stats/opentelemetry"
  "google.golang.org/grpc/stats/opentelemetry/csm"

  "go.opentelemetry.io/otel/sdk/metric"
)

func main() {
  reader := metric.NewManualReader()
  provider := metric.NewMeterProvider(metric.WithReader(reader))
  opts := opentelemetry.Options{
    MetricsOptions: opentelemetry.MetricsOptions{
        MeterProvider: provider,
    },
  }
  cleanup := csm.EnableObservability(context.Background(), opts)
  defer cleanup()
  // Any created ClientConns and servers will be configured with an
  // OpenTelemetry stats plugin configured with provided options.

}

Python

Cloud Service Mesh Observability 需要以下 gRPC 依赖项:

grpcio>=1.65.0
grpcio-observability>=1.65.0
grpcio-csm-observability>=1.65.0

在执行任何 gRPC 操作(包括创建通道、服务器或凭据)之前,请使用 CsmOpenTelemetryPlugin API 创建和注册插件:

import grpc_csm_observability

# ...
csm_plugin = grpc_csm_observability.CsmOpenTelemetryPlugin(
    meter_provider=[your_meter_provider],
)
csm_plugin.register_global()

# Create server or client 

在执行完所有 gRPC 操作后,请使用以下代码取消注册并清理资源:

csm_plugin.deregister_global()

以下示例展示了如何使用 Prometheus 导出器设置 Cloud Service Mesh 可观测性:

import grpc_csm_observability
from opentelemetry.exporter.prometheus import PrometheusMetricReader
from prometheus_client import start_http_server

start_http_server(port=9464, addr="0.0.0.0")
reader = PrometheusMetricReader()
meter_provider = MeterProvider(metric_readers=[reader])
csm_plugin = CsmOpenTelemetryPlugin(
    meter_provider=meter_provider,
)
csm_plugin.register_global()

# Clean up after use

csm_plugin.deregister_global()

在前面的示例中,您可以抓取 localhost:9464/metrics 以获取 Cloud Service Mesh Observability 报告的指标。

请注意,为使添加到 gRPC 指标的网格属性有效, 客户端和服务器二进制文件需要使用 CsmObservability 进行设置。

如果使用非 Google 基础架构来导出和存储指标, 收集流水线应该在描述 运行应用的环境与网格一起显示 可用于获取当前流量的 在网格上运行

规范变更

Cloud Service Mesh 可观测性通过需要添加到容器环境中的环境变量(适用于客户端和服务器)来确定网格拓扑信息。此信息会提供给对等方以指标使用 通过 Cloud Service Mesh 可观测性报告。

spec:
  containers:
  - image: IMAGE_NAME
    name: CONTAINER_NAME
    env:
    - name: GRPC_XDS_BOOTSTRAP
      value: "/tmp/grpc-xds/td-grpc-bootstrap.json" #created by td-grpc-bootstrap
    - name: POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: NAMESPACE_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
     - name: CSM_WORKLOAD_NAME
       value: CSM_WORKLOAD_NAME
     - name: CONTAINER_NAME
       value: CONTAINER_NAME
     - name: OTEL_RESOURCE_ATTRIBUTES
       value: k8s.pod.name=$(POD_NAME),k8s.namespace.name=$(NAMESPACE_NAME),k8s.container.name=CONTAINER_NAME

替换以下内容:

  • IMAGE_NAME 替换为映像的名称。
  • CONTAINER_NAME 替换为容器名称。
  • CSM_WORKLOAD_NAME 替换为工作负载名称,例如部署名称。