无代理 gRPC 的可观测性

适用于无代理 gRPC 的 Cloud Service Mesh 可观测性功能基于现有的 gRPC OpenTelemetry 插件构建,可为启用了 Cloud Service Mesh 的所有 gRPC 通道和服务器记录指标(延迟时间、消息大小等),并提供其他属性,以显示 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 上不会提供这些属性,因为这些指标的收集点无法提供所有拓扑网格信息。

可观测性设置说明

本部分介绍了如何在服务网格设置中为无代理 gRPC 启用 Cloud Service Mesh 可观测性。

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() 方法中,通过向配置好的 OpenTelemetry SDK 实例提供 MeterProvider 来收集和导出指标,从而初始化 Cloud Service Mesh Observability。

    在执行任何 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 或 Server 或凭据)之前,请先使用 MeterProvider 全局配置 Cloud Service Mesh 可观测性。以下示例展示了如何设置 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()

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

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 可观测性功能报告的指标。

请注意,为了让添加到 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 替换为工作负载名称,例如部署 名称。