Observabilidade para gRPC sem proxy

A observabilidade do Cloud Service Mesh para gRPC sem proxy se baseia no plug-in gRPC OpenTelemetry atual, registra métricas (latência, tamanhos de mensagens etc.) para todos os canais e servidores gRPC ativados para o Cloud Service Mesh e fornece atributos adicionais que mostram informações topológicas da malha para o tráfego do Cloud Service Mesh. Um canal gRPC é considerado ativado para o Cloud Service Mesh se receber configuração do plano de controle do Cloud Service Mesh, enquanto todos os servidores gRPC são considerados ativados para o Cloud Service Mesh.

Atributos de malha

Os seguintes atributos de malha estão disponíveis nas métricas.

Identificadores de ambiente local:

  • csm.mesh_id
    • O ID da malha.
  • Outros atributos do ambiente local são obtidos do recurso do OpenTelemetry.
    • O Managed Service para Prometheus (GMP) pode ser configurado para usar a infraestrutura do Google para armazenar métricas. Se você usar isso, os atributos de recurso que descrevem o ambiente local do aplicativo serão adicionados automaticamente como um MonitoredResource.
    • Se você estiver usando uma infraestrutura que não é do Google para exportar e armazenar métricas, o pipeline de coleta precisará adicionar atributos às métricas que descrevem o ambiente em que o aplicativo está sendo executado.

Identificadores de ambiente remoto:

  • csm.remote_workload_type
    • O tipo do peer remoto. ("gcp_kubernetes_engine" para GKE).
  • Dependendo do tipo de peer, outros atributos podem estar presentes.
    • Para um peer em execução no GKE:
    • csm.remote_workload_project_id
      • O identificador do projeto associado a esse recurso, como "my-project".
    • csm.remote_workload_location *O local físico do cluster que contém o contêiner.
    • csm.remote_workload_cluster_name
      • O cluster em que o contêiner está sendo executado.
    • csm.remote_workload_namespace_name
      • The namespace where the container is running.
    • csm.remote_workload_name
      • O nome da carga de trabalho remota. Esse deve ser o nome do objeto que contém a definição do pod (por exemplo, uma implantação, um ReplicaSet ou apenas o nome do pod para um pod simples).

Rótulos de serviço: informações sobre o serviço de back-end (cluster xDS) para o qual a RPC está sendo encaminhada. Isso só estará disponível se o serviço de back-end tiver sido configurado pela API Gateway.

  • csm.service_name
    • O nome do serviço.
  • csm.service_namespace_name
    • O nome do namespace do serviço.

O termo "remote_workload" se refere ao peer. Ou seja, para clientes, o pod do servidor que é o destino de uma RPC é a carga de trabalho remota. Já para servidores, o pod do cliente que iniciou a RPC é a carga de trabalho remota.

Esses atributos não estarão disponíveis em grpc.client.attempt.started e grpc.server.call.started porque todas as informações de malha topológica não estão disponíveis no ponto de coleta dessas métricas.

Instruções de configuração da observabilidade

Nesta seção, explicamos como ativar a observabilidade do Cloud Service Mesh para gRPC sem proxy em uma configuração de malha de serviço.

C++

O suporte à observabilidade só está disponível no sistema de compilação do Bazel. O destino grpcpp_csm_observability precisa ser adicionado como uma dependência.

Alterações de código necessárias

O código a seguir precisa ser adicionado aos clientes e servidores gRPC para usar a observabilidade do 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 qualquer operação gRPC, incluindo a criação de um canal, servidor ou credenciais, use a API CsmObservabilityBuilder para registrar um plug-in. O exemplo a seguir mostra como configurar a observabilidade do Cloud Service Mesh com um exportador do 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();

A API SetMeterProvider() em CsmObservabilityBuilder() permite que os usuários definam um objeto MeterProvider que pode ser configurado com exportadores.

Java

Para ativar a observabilidade do Cloud Service Mesh em aplicativos Java gRPC, siga estas etapas:

  1. Verifique se o projeto inclui o artefato grpc-gcp-csm-observability. Use a versão 1.65.0 ou posterior do gRPC.

  2. No método main(), inicialize a observabilidade do Cloud Service Mesh fornecendo uma instância configurada do SDK do OpenTelemetry com um MeterProvider para coletar e exportar métricas.

    Antes de realizar qualquer operação gRPC, como configurar um canal ou servidor, use a API CsmObservability.Builder() para registrar o SDK do OpenTelemetry.

    Depois que a instância CsmObservability é criada, invocar registerGlobal() nela ativa a observabilidade do Cloud Service Mesh para todos os canais e servidores do Cloud Service Mesh.

    O exemplo a seguir demonstra como configurar a observabilidade do Cloud Service Mesh usando um exportador do 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 qualquer operação gRPC, incluindo a criação de um ClientConn ou Server, ou credenciais, configure a capacidade de observação da malha de serviços do Cloud globalmente com um MeterProvider. A amostra a seguir mostra como configurar a observabilidade do Cloud Service Mesh. Depois de configurar a observabilidade do Cloud Service Mesh, todos os canais e servidores do Cloud Service Mesh vão usar um plug-in de estatísticas do OpenTelemetry configurado com as opções fornecidas e com rótulos adicionais do Cloud Service Mesh. Os canais que não são do Cloud Service Mesh vão receber um plug-in de estatísticas do OpenTelemetry sem rótulos do 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

As seguintes dependências do gRPC são necessárias para a observabilidade do Cloud Service Mesh:

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

Antes de qualquer operação gRPC, incluindo a criação de um canal, servidor ou credenciais, use a API CsmOpenTelemetryPlugin para criar e registrar um plug-in:

import grpc_csm_observability

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

# Create server or client 

Depois de todas as operações gRPC, use o código a seguir para cancelar o registro e limpar os recursos:

csm_plugin.deregister_global()

O exemplo a seguir mostra como configurar a observabilidade do Cloud Service Mesh com um exportador do 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()

No exemplo anterior, é possível extrair localhost:9464/metrics para receber as métricas informadas pela observabilidade do Cloud Service Mesh.

Para que os atributos da malha adicionados às métricas do gRPC funcionem, os binários do cliente e do servidor precisam ser configurados com CsmObservability.

Se você usar uma infraestrutura que não é do Google para exportar e armazenar métricas, o pipeline de coleta vai adicionar atributos às métricas que descrevem o ambiente em que o aplicativo está sendo executado. Isso, junto com os atributos da malha descritos anteriormente, pode ser usado para ter uma visão do tráfego em execução na malha.

Mudanças na especificação

A capacidade de observação do Cloud Service Mesh determina as informações topológicas da malha usando variáveis de ambiente que precisam ser adicionadas ao ambiente do contêiner, tanto para clientes quanto para servidores. Essas informações são disponibilizadas aos colegas para relatórios de métricas pela observabilidade do 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

Substitua o seguinte:

  • IMAGE_NAME com o nome da imagem.
  • CONTAINER_NAME pelo nome do contêiner.
  • CSM_WORKLOAD_NAME com o nome da carga de trabalho, por exemplo, o nome da implantação.