注入自动仪表化

使用OpenTelemetry Operator实现自动仪表化。

OpenTelemetry Operator支持注入和配置用于.NET、Java、Node.js和Python服务的自动仪表化库。

安装

首先,将OpenTelemetry Operator安装到您的集群中。

您可以使用Operator发布清单Operator Helm图表Operator Hub来完成此操作。

在大多数情况下,您需要安装cert-manager。如果您使用helm图表,可以选择生成自签名证书。

如果您想使用Go自动仪表化,请启用功能通道。有关详细信息,请参阅控制仪表化功能

创建OpenTelemetry Collector(可选)

向容器发送遥测数据最佳实践是将数据发送到OpenTelemetry Collector而不是直接发送到后端。Collector可以帮助简化密钥管理,将数据导出问题(如需要重试)与应用程序解耦,并允许您在遥测数据中添加其他数据,例如k8sattributesprocessor组件。如果您选择不使用Collector,可以跳过下一节。

Operator提供了一个自定义资源定义(CRD)用于OpenTelemetry Collector,用于创建Operator管理的Collector实例。以下示例将Collector部署为部署(默认方式),但也可以使用其他部署模式

在使用“Deployment”模式时,运算符还将创建一个服务,可用于与Collector进行交互。服务的名称是OpenTelemetryCollector资源的名称前面加上-collector。对于我们的示例,名称将是demo-collector

kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
  name: demo
spec:
  config: |
    receivers:
      otlp:
        protocols:
          grpc:
          http:
    processors:
      memory_limiter:
        check_interval: 1s
        limit_percentage: 75
        spike_limit_percentage: 15
      batch:
        send_batch_size: 10000
        timeout: 10s

    exporters:
      # 注意:在v0.86.0之前,请使用`logging`而不是`debug`。
      debug:

    service:
      pipelines:
        traces:
          receivers: [otlp]
          processors: [memory_limiter, batch]
          exporters: [debug]
        metrics:
          receivers: [otlp]
          processors: [memory_limiter, batch]
          exporters: [debug]
        logs:
          receivers: [otlp]
          processors: [memory_limiter, batch]
          exporters: [debug]
EOF

上述命令将部署Collector,然后您可以将其用作自动仪表化中的端点。

配置自动仪表化

为了能够管理自动仪表化,操作员需要配置知道要仪表化哪些pod以及为这些pod使用何种自动仪表化。这是通过Instrumentation CRD完成的。

正确创建Instrumentation资源对于使自动仪表化正常工作至关重要。确保所有端点和环境变量正确无误是必需的。

.NET

以下命令将创建一个基本的Instrumentation资源,该资源专门用于配置.NET服务的仪表化。

kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: demo-instrumentation
spec:
  exporter:
    endpoint: http://demo-collector:4318
  propagators:
    - tracecontext
    - baggage
  sampler:
    type: parentbased_traceidratio
    argument: "1"
EOF

默认情况下,自动仪表化.NET服务的Instrumentation资源使用otlphttp/protobuf协议。这意味着配置的端点必须能够接收http/protobuf的OTLP。因此,示例中使用http://demo-collector:4318,它将连接到前一步中创建的Collector的otlpreceiverhttp端口。

排除自动仪表化

默认情况下,.NET自动仪表化使用许多仪表化库。这使得仪表化变得简单,但可能导致过多或不需要的数据。如果有任何您不想使用的库,您可以将OTEL_DOTNET_AUTO_[SIGNAL]_[NAME]_INSTRUMENTATION_ENABLED=false设置为[SIGNAL]是信号类型,[NAME]是区分大小写的库名称。

apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: demo-instrumentation
spec:
  exporter:
    endpoint: http://demo-collector:4318
  propagators:
    - tracecontext
    - baggage
  sampler:
    type: parentbased_traceidratio
    argument: '1'
  dotnet:
    env:
      - name: OTEL_DOTNET_AUTO_TRACES_GRPCNETCLIENT_INSTRUMENTATION_ENABLED
        value: false
      - name: OTEL_DOTNET_AUTO_METRICS_PROCESS_INSTRUMENTATION_ENABLED
        value: false

了解更多

欲了解详细信息,请参阅.NET自动仪表化文档

Java

以下命令创建一个基本的Instrumentation资源,该资源配置用于仪表化Java服务。

kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: demo-instrumentation
spec:
  exporter:
    endpoint: http://demo-collector:4317
  propagators:
    - tracecontext
    - baggage
  sampler:
    type: parentbased_traceidratio
    argument: "1"
EOF

默认情况下,自动仪表化Java服务的Instrumentation资源使用otlpgrpc协议。这意味着配置的端点必须能够接收OTLP over grpc。因此,示例中使用http://demo-collector:4317,它连接到先前步骤中创建的Collector的grpc端口。

排除自动仪表化

默认情况下,Java自动仪表化使用许多仪表化库。这使得仪表化变得简单,但可能导致过多或不需要的数据。如果有任何您不想使用的库,可以将OTEL_INSTRUMENTATION_[NAME]_ENABLED=false设置为[NAME]是库的名称。如果您确切地知道要使用哪些库,则可以将默认库禁用,将OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED=false设置为true,然后使用OTEL_INSTRUMENTATION_[NAME]_ENABLED=true,其中[NAME]是库的名称。有关详细信息,请参阅抑制特定自动仪表化

apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: demo-instrumentation
spec:
  exporter:
    endpoint: http://demo-collector:4317
  propagators:
    - tracecontext
    - baggage
  sampler:
    type: parentbased_traceidratio
    argument: '1'
  java:
    env:
      - name: OTEL_INSTRUMENTATION_KAFKA_ENABLED
        value: false
      - name: OTEL_INSTRUMENTATION_REDISCALA_ENABLED
        value: false

了解更多

欲了解详细信息,请参阅Java代理配置

Node.js

以下命令创建一个基本的Instrumentation资源,该资源配置用于仪表化Node.js服务。

kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: demo-instrumentation
spec:
  exporter:
    endpoint: http://demo-collector:4317
  propagators:
    - tracecontext
    - baggage
  sampler:
    type: parentbased_traceidratio
    argument: "1"
EOF

默认情况下,自动仪表化Node.js服务的Instrumentation资源使用otlpgrpc协议。这意味着配置的端点必须能够接收OTLP over grpc。因此,示例中使用http://demo-collector:4317,它连接到先前步骤中创建的Collector的grpc端口。

排除自动仪表化

默认情况下,Node.js自动仪表化使用许多仪表化库。目前还没有方法仅选择特定的包或禁用特定的包。如果不想使用默认图像中包含的包,您必须提供自己的图像,其中只包含您想要的包,或者使用手动仪表化。

了解更多

欲了解详细信息,请参阅Node.js自动仪表化

Python

以下命令将创建一个基本的Instrumentation资源,该资源专门用于配置Python服务的仪表化。

kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: demo-instrumentation
spec:
  exporter:
    endpoint: http://demo-collector:4318
  propagators:
    - tracecontext
    - baggage
  sampler:
    type: parentbased_traceidratio
    argument: "1"
EOF

默认情况下,自动仪表化Python服务的Instrumentation资源使用otlphttp/protobuf协议(目前不支持gRPC)。这意味着配置的端点必须能够接收http/protobuf的OTLP。因此,示例中使用http://demo-collector:4318,它将连接到先前步骤中创建的Collector的otlpreceiverhttp端口。

从operator v0.67.0开始,Instrumentation资源会自动将OTEL_EXPORTER_OTLP_TRACES_PROTOCOLOTEL_EXPORTER_OTLP_METRICS_PROTOCOL设置为http/protobuf。如果您使用的是较旧版本的Operator,必须将这些环境变量设置为http/protobuf,否则python自动仪表化将无法工作。

自动仪表化Python日志

默认情况下,禁用了Python日志自动仪表化。如果要启用此功能,必须将OTEL_LOGS_EXPORTEROTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED环境变量设置如下:

apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: python-instrumentation
  namespace: application
spec:
  exporter:
    endpoint: http://demo-collector:4318
  env:
  propagators:
    - tracecontext
    - baggage
  python:
    env:
      - name: OTEL_LOGS_EXPORTER
        value: otlp_proto_http
      - name: OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED
        value: 'true'

注意,OTEL_LOGS_EXPORTER必须显式设置为otlp_proto_http,否则它默认为gRPC。

排除自动仪表化

默认情况下,Python自动仪表化将检测Python服务中的软件包并对其进行仪表化。这使得仪表化变得简单,但可能导致过多或不需要的数据。如果有任何包不想进行仪表化,可以设置OTEL_PYTHON_DISABLED_INSTRUMENTATIONS环境变量

apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: demo-instrumentation
spec:
  exporter:
    endpoint: http://demo-collector:4318
  propagators:
    - tracecontext
    - baggage
  sampler:
    type: parentbased_traceidratio
    argument: '1'
  python:
    env:
      - name: OTEL_PYTHON_DISABLED_INSTRUMENTATIONS
        value:
          <逗号分隔的要从仪表化中排除的软件包名称列表>

了解更多

有关更多详细信息,请参阅Python代理配置文档。

Go

以下命令创建一个基本的Instrumentation资源,该资源专门用于配置Go服务的仪表化。

kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: demo-instrumentation
spec:
  exporter:
    endpoint: http://demo-collector:4317
  propagators:
    - tracecontext
    - baggage
  sampler:
    type: parentbased_traceidratio
    argument: "1"
EOF

默认情况下,自动仪表化Go服务的Instrumentation资源使用otlpgrpc协议。这意味着配置的端点必须能够接收OTLP over grpc。因此,示例中使用http://demo-collector:4317,它连接到先前步骤中创建的Collector的grpc端口。

Go自动仪表化仅支持通过gRPC导出。通过环境变量将协议或导出器设置为其他值将导致静默失败。

Go自动仪表化不支持禁用任何仪表化。有关更多详细信息,请参阅Go自动仪表化存储库。


现在,您的Instrumentation对象已创建,您的集群具备了自动仪表化服务并将数据发送到端点的能力。但是,使用OpenTelemetry Operator进行的自动仪表化遵循选择加入模型。为了激活自动仪表化,您需要向部署中添加一个注释。

添加注释到现有部署

最后一步是将您的服务自动添加到仪表化中。这是通过更新您的服务的 spec.template.metadata.annotations 来完成的,包括一个特定于语言的注释:

  • .NET: instrumentation.opentelemetry.io/inject-dotnet: "true"
  • Go: instrumentation.opentelemetry.io/inject-go: "true"
  • Java: instrumentation.opentelemetry.io/inject-java: "true"
  • Node.js: instrumentation.opentelemetry.io/inject-nodejs: "true"
  • Python: instrumentation.opentelemetry.io/inject-python: "true"

注释的可能值可以是:

  • "true" - 注入带有当前命名空间中默认名称的 Instrumentation 资源。
  • "my-instrumentation" - 在当前命名空间中注入名称为 "my-instrumentation"Instrumentation CR 实例。
  • "my-other-namespace/my-instrumentation" - 从另一个命名空间 "my-other-namespace" 注入名称为 "my-instrumentation"Instrumentation CR 实例。
  • "false" - 不进行注入。

或者,可以将注释添加到命名空间中,这将导致该命名空间中的所有服务都自动选择自动仪表化。了解更多详细信息,请参阅运营商自动仪表化文档

选择一个 Go 服务

与其他语言的自动仪表化不同,Go 通过运行一个 eBPF 代理来工作。当选择后,运营商将会将此 sidecar 注入到您的 Pod。除了上面提到的 instrumentation.opentelemetry.io/inject-go 注释之外,您还必须为 OTEL_GO_AUTO_TARGET_EXE 环境变量 提供一个值。您可以通过 instrumentation.opentelemetry.io/otel-go-auto-target-exe 注释设置此环境变量。

instrumentation.opentelemetry.io/inject-go: 'true'
instrumentation.opentelemetry.io/otel-go-auto-target-exe: '/path/to/container/executable'

该环境变量也可以通过 Instrumentation 资源进行设置,注释优先。由于 Go 自动仪表化要求设置 OTEL_GO_AUTO_TARGET_EXE,因此您必须通过注释或 Instrumentation 资源提供有效的可执行文件路径。如果未设置此值,仪表化注入将中止,保留原始 Pod。

由于 Go 自动仪表化使用 eBPF,所以它还需要提升的权限。当您选择参与时,运营商注入的 sidecar 将需要以下权限:

securityContext:
  capabilities:
    add:
      - SYS_PTRACE
  privileged: true
  runAsUser: 0

故障排除

如果您尝试自动添加仪表化到您的代码时遇到问题,可以尝试以下几个方法。

仪表化资源是否已经安装?

在安装 Instrumentation 资源后,通过运行以下命令验证它是否已正确安装,其中 <namespace> 是部署 Instrumentation 资源的命名空间:

kubectl describe otelinst -n <namespace>

示例输出:

Name:         python-instrumentation
Namespace:    application
Labels:       app.kubernetes.io/managed-by=opentelemetry-operator
Annotations:  instrumentation.opentelemetry.io/default-auto-instrumentation-apache-httpd-image:
               ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-apache-httpd:1.0.3
             instrumentation.opentelemetry.io/default-auto-instrumentation-dotnet-image:
               ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-dotnet:0.7.0
             instrumentation.opentelemetry.io/default-auto-instrumentation-go-image:
               ghcr.io/open-telemetry/opentelemetry-go-instrumentation/autoinstrumentation-go:v0.2.1-alpha
             instrumentation.opentelemetry.io/default-auto-instrumentation-java-image:
               ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:1.26.0
             instrumentation.opentelemetry.io/default-auto-instrumentation-nodejs-image:
               ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-nodejs:0.40.0
             instrumentation.opentelemetry.io/default-auto-instrumentation-python-image:
               ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-python:0.39b0
API Version:  opentelemetry.io/v1alpha1
Kind:         Instrumentation
Metadata:
 Creation Timestamp:  2023-07-28T03:42:12Z
 Generation:          1
 Resource Version:    3385
 UID:                 646661d5-a8fc-4b64-80b7-8587c9865f53
Spec:
...
 Exporter:
   Endpoint:  http://otel-collector-collector.opentelemetry.svc.cluster.local:4318
...
 Propagators:
   tracecontext
   baggage
 Python:
   Image:  ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-python:0.39b0
   Resource Requirements:
     Limits:
       Cpu:     500m
       Memory:  32Mi
     Requests:
       Cpu:     50m
       Memory:  32Mi
 Resource:
 Sampler:
Events:  <none>

OTel Operator 日志是否显示任何自动仪表化错误?

通过运行以下命令,检查 OTel Operator 日志中是否存在与自动仪表化相关的错误:

kubectl logs -l app.kubernetes.io/name=opentelemetry-operator --container manager -n opentelemetry-operator-system --follow

资源是否按正确顺序部署?

顺序很重要!在部署应用程序之前,Instrumentation 资源需要先部署,否则自动仪表化将无法工作。

回想一下自动仪表化的注释:

annotations:
  instrumentation.opentelemetry.io/inject-python: 'true'

上面的注释告诉 OTel Operator 在 Pod 的命名空间中查找一个 Instrumentation 对象。它还告诉 Operator 将 Python 自动仪表化注入到 Pod 中。

当 Pod 启动时,注释告诉 Operator 在 Pod 的命名空间中查找 Instrumentation 对象,并将自动仪表化注入到 Pod 中。它会向应用程序的 Pod 添加一个名为 opentelemetry-auto-instrumentationinit-container,然后用它来将自动仪表化注入到应用程序容器中。

然而,如果在应用程序部署之前没有部署 Instrumentation 资源,那么 init-container 将无法创建。因此,如果在部署 Instrumentation 资源之前部署应用程序,自动仪表化将失败。

为确保 opentelemetry-auto-instrumentation init-container 已正确启动(或是否已经启动),运行以下命令:

kubectl get events -n <your_app_namespace>

输出应该类似于以下内容:

53s         Normal   Created             pod/py-otel-server-7f54bf4cbc-p8wmj    Created container opentelemetry-auto-instrumentation
53s         Normal   Started             pod/py-otel-server-7f54bf4cbc-p8wmj    Started container opentelemetry-auto-instrumentation

如果输出中缺少 Created 和/或 Started 条目以及 opentelemetry-auto-instrumentation,则意味着您的自动仪表化存在问题。这可能是以下任何原因导致的:

  • Instrumentation 资源未安装(或未正确安装)。
  • Instrumentation 资源在应用程序部署之后才安装。
  • 自动仪表化注释存在错误,或者注释位置错误 - 请参阅下面的 #4。

请务必检查 kubectl get events 的输出,查看是否有任何错误,因为这些可能有助于指出问题。

自动仪表化注释是否正确?

有时,自动仪表化可能会由于自动仪表化注释中的错误而失败。

以下是要检查的几个事项:

  • 自动仪表化是否针对正确的语言? 例如,当为 Python 应用程序添加仪表化时,请确保注释不会错误地设置为 instrumentation.opentelemetry.io/inject-java: "true"
  • 自动仪表化注释是否在正确的位置? 在定义 Deployment 时,注释可以添加在两个位置:spec.metadata.annotationsspec.template.metadata.annotations。自动仪表化注释必须添加到 spec.template.metadata.annotations 中,否则它将无法工作。

是否正确配置了自动仪表化端点?

Instrumentation 资源的 spec.exporter.endpoint 属性定义了数据发送的目标。这可以是 OTel Collector 或任何 OTLP 端点。如果省略此属性,则默认为 http://localhost:4317,这很可能不会将遥测数据发送到任何地方。

当将遥测数据发送到位于同一 Kubernetes 集群中的 OTel Collector 时,spec.exporter.endpoint 应引用 OTel Collector 的名称 Service

例如:

spec:
  exporter:
    endpoint: http://otel-collector-collector.opentelemetry.svc.cluster.local:4317

这里,收集器的端点设置为 http://otel-collector.opentelemetry.svc.cluster.local:4317,其中 otel-collector 是 OTel Collector Kubernetes Service 的名称。在上面的示例中,收集器在与应用程序不同的命名空间中运行,这意味着必须将 opentelemetry.svc.cluster.local 附加到收集器的服务名称中,其中 open-telemetry 是收集器所在的命名空间。

最后修改 December 13, 2023: improve glossary translation (46f8201b)