无代理 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 集群) 的信息。请注意,只有在通过 Gateway API 配置了后端服务的情况下,此方法才可用。
csm.service_name
- 服务名称。
csm.service_namespace_name
- 服务命名空间名称。
术语 remote_workload 是指对等方,也就是说,对于客户端,RPC 的目标服务器 Pod 是远程工作负载,而对于服务器,发起 RPC 的客户端 Pod 是远程工作负载。
请注意,grpc.client.attempt.started
和 grpc.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 可观测性,请执行以下步骤:
确保项目包含
grpc-gcp-csm-observability
工件。使用 gRPC 1.65.0 或更高版本。在
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()
以下示例展示了如何使用 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 可观测性功能报告的指标。
请注意,为了让添加到 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 替换为工作负载名称,例如部署名称。