Observabilidad de gRPC sin proxy

La observabilidad de Cloud Service Mesh para gRPC sin proxy se basa en el complemento gRPC OpenTelemetry, registra métricas (latencia, tamaños de los mensajes, etc.) de todos los canales y servidores gRPC que tienen habilitado Cloud Service Mesh y proporciona atributos adicionales que muestran información de la topología de la malla del tráfico de Cloud Service Mesh. Se considera que un canal gRPC tiene habilitado Cloud Service Mesh si obtiene la configuración del plano de control de Cloud Service Mesh, mientras que todos los servidores gRPC tienen habilitado Cloud Service Mesh.

Atributos de malla

Los siguientes atributos de malla están disponibles en las métricas.

Etiquetas de entorno local:

  • csm.mesh_id
    • El ID de la malla.
  • Otros atributos del entorno local se obtienen del recurso OpenTelemetry.
    • Managed Service para Prometheus (GMP) se puede configurar para usar la infraestructura de Google con el fin de almacenar métricas. Si usas este atributo, los atributos de recursos que describen el entorno local de la aplicación se añaden automáticamente como MonitoredResource.
    • Si utiliza una infraestructura que no es de Google para exportar y almacenar métricas, la pipeline de recogida debe añadir atributos a las métricas que describan el entorno en el que se ejecuta la aplicación.

Etiquetas de entorno remoto:

  • csm.remote_workload_type
    • Tipo del peer remoto. ("gcp_kubernetes_engine" para GKE).
  • En función del tipo de elemento del mismo nivel, se mostrarán atributos adicionales.
    • En el caso de un peer que se ejecute en GKE:
    • csm.remote_workload_project_id
      • Identificador del proyecto asociado a este recurso, como "my-project".
    • csm.remote_workload_location * La ubicación física del clúster que contiene el contenedor.
    • csm.remote_workload_cluster_name
      • El clúster en el que se ejecuta el contenedor.
    • csm.remote_workload_namespace_name
      • The namespace where the container is running.
    • csm.remote_workload_name
      • Nombre de la carga de trabajo remota. Debe ser el nombre del objeto que contiene la definición del pod (por ejemplo, un Deployment, un ReplicaSet o simplemente el nombre del pod si se trata de un pod sin envoltorio).

Etiquetas de servicio: información sobre el servicio backend (clúster xDS) al que se está dirigiendo la RPC. Ten en cuenta que esta opción solo está disponible si el servicio de backend se ha configurado a través de la API Gateway.

  • csm.service_name
    • El nombre del servicio.
  • csm.service_namespace_name
    • Nombre del espacio de nombres del servicio.

El término remote_workload hace referencia al peer. Es decir, en el caso de los clientes, el Pod del servidor que es el destino de una RPC es la carga de trabajo remota, mientras que, en el caso de los servidores, el Pod del cliente que ha iniciado la RPC es la carga de trabajo remota.

Tenga en cuenta que estos atributos no estarán disponibles en grpc.client.attempt.started y grpc.server.call.started, ya que no se puede acceder a toda la información de la malla topológica en el punto de recogida de estas métricas.

Instrucciones de configuración de la observabilidad

En esta sección se explica cómo habilitar la observabilidad de Cloud Service Mesh para gRPC sin proxy en una configuración de malla de servicios.

C++

La observabilidad solo está disponible a través del sistema de compilación de Bazel. El destino grpcpp_csm_observability debe añadirse como dependencia.

Cambios de código obligatorios

El siguiente código debe añadirse a tus clientes y servidores gRPC para poder usar la observabilidad de Cloud Service Mesh.

#include <grpcpp/ext/csm_observability.h>

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

Antes de realizar cualquier operación de gRPC, como crear un canal, un servidor o credenciales, usa la API CsmObservabilityBuilder para registrar un complemento. En el siguiente ejemplo se muestra cómo configurar la observabilidad de Cloud Service Mesh con un exportador de Prometheus.

  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();

La API SetMeterProvider() de CsmObservabilityBuilder() permite a los usuarios definir un objeto MeterProvider que se puede configurar con exportadores.

Java

Para habilitar la observabilidad de Cloud Service Mesh en aplicaciones Java gRPC, sigue estos pasos:

  1. Asegúrate de que el proyecto incluya el artefacto grpc-gcp-csm-observability. Usa la versión 1.65.0 de gRPC o una posterior.

  2. En el método main(), inicializa la observabilidad de Cloud Service Mesh proporcionando una instancia configurada del SDK de OpenTelemetry con un MeterProvider para recoger y exportar métricas.

    Antes de realizar cualquier operación de gRPC, como configurar un canal o un servidor, asegúrate de usar la API CsmObservability.Builder() para registrar el SDK de OpenTelemetry.

    Una vez creada la instancia de CsmObservability, al invocar registerGlobal() en la instancia se habilita la observabilidad de Cloud Service Mesh en todos los canales y servidores de Cloud Service Mesh.

    En el siguiente ejemplo se muestra cómo configurar la observabilidad de Cloud Service Mesh mediante un exportador de Prometheus.

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

Antes de realizar cualquier operación de gRPC, como crear un ClientConn o un servidor, o credenciales, configura la observabilidad de Cloud Service Mesh de forma global con un MeterProvider. En el siguiente ejemplo se muestra cómo configurar la observabilidad de Cloud Service Mesh. Después de configurar Cloud Service Mesh Observability, cualquier canal de Cloud Service Mesh y todos los servidores recogerán un complemento de estadísticas de OpenTelemetry configurado con las opciones proporcionadas y con etiquetas adicionales de Cloud Service Mesh. Los canales que no sean de Cloud Service Mesh recibirán un complemento de estadísticas de OpenTelemetry sin etiquetas de Cloud Service Mesh.

  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

Se necesitan las siguientes dependencias de gRPC para la observabilidad de Cloud Service Mesh:

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

Antes de realizar cualquier operación de gRPC, como crear un canal, un servidor o credenciales, usa la API CsmOpenTelemetryPlugin para crear y registrar un complemento:

import grpc_csm_observability

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

# Create server or client 

Después de todas las operaciones de gRPC, usa el siguiente código para anular el registro y limpiar los recursos:

csm_plugin.deregister_global()

En el siguiente ejemplo se muestra cómo configurar la observabilidad de Cloud Service Mesh con un exportador de 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()

En el ejemplo anterior, puedes raspar localhost:9464/metrics para obtener las métricas que registra Observabilidad de Cloud Service Mesh.

Ten en cuenta que, para que funcionen los atributos de malla añadidos a las métricas de gRPC, los archivos binarios del cliente y del servidor deben configurarse con CsmObservability.

Si utiliza una infraestructura que no es de Google para exportar y almacenar métricas, la canalización de recogida debe añadir atributos a las métricas que describan el entorno en el que se ejecuta la aplicación. Esto, junto con los atributos de malla descritos anteriormente, se puede utilizar para obtener una vista del tráfico que se ejecuta en la malla.

Cambios en las especificaciones

La observabilidad de Cloud Service Mesh determina la información topológica de la malla a través de variables de entorno que deben añadirse al entorno del contenedor, tanto para clientes como para servidores. Esta información se pone a disposición de los peers para generar informes de métricas a través de la observabilidad de 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

Sustituye lo siguiente:

  • IMAGE_NAME con el nombre de la imagen.
  • CONTAINER_NAME con el nombre del contenedor.
  • CSM_WORKLOAD_NAME con el nombre de la carga de trabajo, por ejemplo, el nombre de la implementación.