注入自动检测
OpenTelemetry Operator 支持为 .NET、Java、Node.js、Python 和 Go 服务注入和配置自动检测库。
安装
首先,将 OpenTelemetry Operator 安装到您的集群中。
您可以使用 Operator 发布清单、Operator Helm chart 或 Operator Hub 来完成此操作。
在大多数情况下,您需要安装 cert-manager。如果您使用 Helm chart,则有一个选项可以生成自签名证书。
如果您想使用 Go 自动检测,则需要启用功能门。有关详细信息,请参阅 控制检测功能。
创建 OpenTelemetry Collector (可选)
将容器中的遥测数据发送到 OpenTelemetry Collector 而不是直接发送到后端,这是一项最佳实践。Collector 有助于简化秘密管理,将数据导出问题(例如重试需求)与您的应用程序解耦,并允许您添加其他数据到您的遥测数据中,例如使用 k8sattributesprocessor 组件。如果您选择不使用 Collector,则可以跳到下一节。
Operator 提供了一个用于 OpenTelemetry Collector 的自定义资源定义 (CRD),该资源用于创建 Operator 管理的 Collector 实例。以下示例将 Collector 部署为部署(默认),但还有其他 部署模式 可用。
使用 Deployment 模式时,Operator 还会创建一个可用于与 Collector 交互的服务。服务名称是 OpenTelemetryCollector 资源名称加上 -collector 前缀。在我们的示例中,它将是 demo-collector。
kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
name: demo
spec:
config:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 75
spike_limit_percentage: 15
exporters:
debug:
verbosity: basic
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter]
exporters: [debug]
metrics:
receivers: [otlp]
processors: [memory_limiter]
exporters: [debug]
logs:
receivers: [otlp]
processors: [memory_limiter]
exporters: [debug]
EOF
上述命令将部署一个 Collector,您可以使用它作为 Pod 中自动检测的端点。
配置自动检测
为了管理自动检测,Operator 需要被配置为知道要检测哪些 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 资源使用 otlp 和 http/protobuf 协议。这意味着配置的端点必须能够接收 OTLP over http/protobuf。因此,示例使用了 http://demo-collector:4318,它将连接到上一步创建的 Collector 的 otlpreceiver 的 http 端口。
排除自动检测
默认情况下,.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 自动检测文档。
Deno
以下命令创建一个基本的 Instrumentation 资源,该资源配置用于检测 Deno 服务。
kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: demo-instrumentation
spec:
env:
- name: OTEL_DENO
value: 'true'
exporter:
endpoint: http://demo-collector:4318
propagators:
- tracecontext
- baggage
sampler:
type: parentbased_traceidratio
argument: '1'
EOF
当 Deno 进程以 OTEL_DENO=true 环境变量启动时,它们会自动将遥测数据导出到配置的端点。因此,示例在 Instrumentation 资源的 env 字段中指定了此环境变量,以便为使用此 Instrumentation 资源注入环境变量的所有服务设置此变量。
默认情况下,自动检测 Deno 服务的 Instrumentation 资源使用 otlp 和 http/proto 协议。这意味着配置的端点必须能够接收 OTLP over http/proto。因此,示例使用了 http://demo-collector:4318,它连接到上一步创建的 Collector 的 otlpreceiver 的 http/proto 端口。
Deno 的 OpenTelemetry 集成 尚不稳定。因此,所有想要使用 Deno 进行检测的工作负载在启动 Deno 进程时都必须设置 --unstable-otel 标志。
配置选项
默认情况下,Deno OpenTelemetry 集成将 console.log() 输出导出为
日志,同时仍然将日志打印到 stdout/stderr。您可以配置以下备用行为:
OTEL_DENO_CONSOLE=replace:仅将console.log()输出导出为日志;不打印到 stdout/stderr。OTEL_DENO_CONSOLE=ignore:不将console.log()输出导出为日志;但会打印到 stdout/stderr。
了解更多
有关更多详细信息,请参阅 Deno 的 OpenTelemetry 集成 文档。
Go
以下命令将创建一个基本的 Instrumentation 资源,该资源专门配置用于检测 Go 服务。
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
默认情况下,自动检测 Go 服务的 Instrumentation 资源使用 otlp 和 http/protobuf 协议。这意味着配置的端点必须能够接收 OTLP over http/protobuf。因此,示例使用了 http://demo-collector:4318,它连接到上一步创建的 Collector 的 otlpreceiver 的 http/protobuf 端口。
Go 自动检测不支持禁用任何检测。 有关更多详细信息,请参阅 Go 自动检测存储库。
Java
以下命令将创建一个基本的 Instrumentation 资源,该资源配置用于检测 Java 服务。
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
默认情况下,自动检测 Java 服务的 Instrumentation 资源使用 otlp 和 http/protobuf 协议。这意味着配置的端点必须能够通过 protobuf 有效负载接收 OTLP over http。因此,示例使用了 http://demo-collector:4318,它连接到上一步创建的 Collector 的 otlpreceiver 的 http 端口。
排除自动检测
默认情况下,Java 自动检测附带 许多检测库。这使得检测变得容易,但也可能导致过多的或不需要的数据。如果您不想使用某些库,可以设置 OTEL_INSTRUMENTATION_[NAME]_ENABLED=false,其中 [NAME] 是库的名称。如果您确切知道要使用的库,可以通过设置 OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED=false 来禁用默认库,然后使用 OTEL_INSTRUMENTATION_[NAME]_ENABLED=true,其中 [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'
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 资源使用 otlp 和 grpc 协议。这意味着配置的端点必须能够接收 OTLP over grpc。因此,示例使用了 http://demo-collector:4317,它连接到上一步创建的 Collector 的 otlpreceiver 的 grpc 端口。
排除检测库
默认情况下,Node.js 的零代码检测启用了所有检测库。
要仅启用特定的检测库,您可以使用 OTEL_NODE_ENABLED_INSTRUMENTATIONS 环境变量,如 Node.js 零代码检测文档 中所述。
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
# ... other fields skipped from this example
spec:
# ... other fields skipped from this example
nodejs:
env:
- name: OTEL_NODE_ENABLED_INSTRUMENTATIONS
value: http,nestjs-core # comma-separated list of the instrumentation package names without the `@opentelemetry/instrumentation-` prefix.
要保留所有默认库并仅禁用特定的检测库,您可以使用 OTEL_NODE_DISABLED_INSTRUMENTATIONS 环境变量。有关详细信息,请参阅 排除检测库。
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
# ... other fields skipped from this example
spec:
# ... other fields skipped from this example
nodejs:
env:
- name: OTEL_NODE_DISABLED_INSTRUMENTATIONS
value: fs,grpc # comma-separated list of the instrumentation package names without the `@opentelemetry/instrumentation-` prefix.
如果同时设置了这两个环境变量,则首先应用 OTEL_NODE_ENABLED_INSTRUMENTATIONS,然后将 OTEL_NODE_DISABLED_INSTRUMENTATIONS 应用于该列表。因此,如果同一检测包含在两个列表中,则该检测将被禁用。
了解更多
有关更多详细信息,请参阅 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 资源使用 otlp 和 http/protobuf 协议(目前不支持 gRPC)。这意味着配置的端点必须能够接收 OTLP over http/protobuf。因此,示例使用了 http://demo-collector:4318,它将连接到上一步创建的 Collector 的 otlpreceiver 的 http 端口。
从 operator v0.108.0 开始,Instrumentation 资源会自动为 Python 服务设置
OTEL_EXPORTER_OTLP_PROTOCOL为http/protobuf。如果您使用的是旧版本的 Operator,则 **必须** 将此环境变量设置为http/protobuf,否则 Python 自动检测将不起作用。
自动检测 Python 日志
默认情况下,Python 日志自动检测是禁用的。如果您想启用此功能,则必须按如下方式设置 OTEL_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_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED
value: 'true'
从 operator v0.111.0 开始,设置
OTEL_LOGS_EXPORTER为otlp不再是必需的。
排除自动检测
默认情况下,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:
<comma-separated list of package names to exclude from
instrumentation>
有关更多详细信息,请参阅 Python 代理配置文档。
了解更多
对于 Python 特有的注意事项,请参阅 Python OpenTelemetry Operator 文档 和 Python 代理配置文档。
现在您的 Instrumentation 对象已创建,您的集群就具备了自动检测服务并向端点发送数据的能力。然而,OpenTelemetry Operator 的自动检测遵循选择加入模型。要激活自动检测,您需要向您的部署添加一个注解。
向现有部署添加注解
最后一步是选择加入您的服务以进行自动检测。这是通过更新您服务的 spec.template.metadata.annotations 来实现的,其中包含一个特定于语言的注解:
- .NET:
instrumentation.opentelemetry.io/inject-dotnet: "true" - Deno:
instrumentation.opentelemetry.io/inject-sdk: "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"的InstrumentationCR 实例。"my-other-namespace/my-instrumentation"- 从另一个命名空间"my-other-namespace"注入名称为"my-instrumentation"的InstrumentationCR 实例。"false"- 不注入
或者,可以将注解添加到命名空间,这将导致该命名空间中的所有服务选择加入自动检测。有关更多详细信息,请参阅 Operator 的自动检测文档。
选择加入 Go 服务
与其他语言的自动检测不同,Go 通过 sidecar 运行的 eBPF 代理进行工作。选择加入后,Operator 会将此 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,因此还需要提升的权限。当您选择加入时,Operator 注入的 sidecar 将需要以下权限:
securityContext:
privileged: true
runAsUser: 0
自动检测基于 musl 的 Python 容器
从 operator v0.113.0 开始,Python 自动检测还支持一个注解,该注解允许它在具有不同 C 库(而非 glibc)的镜像上运行。
# for Linux glibc based images, this is the default value and can be omitted
instrumentation.opentelemetry.io/otel-python-platform: "glibc"
# for Linux musl based images
instrumentation.opentelemetry.io/otel-python-platform: "musl"
故障排除
如果您在自动检测代码时遇到问题,可以尝试以下一些方法。
检测资源是否已安装?
安装 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://demo-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'
当 Pod 启动时,上面的注解会告诉 OTel Operator 在 Pod 的命名空间中查找 Instrumentation 对象。它还会告诉 Operator 将 Python 自动检测注入到 Pod 中。
它会向应用程序的 Pod 添加一个名为 opentelemetry-auto-instrumentation 的 init-container,然后该 init-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
如果输出中缺少 opentelemetry-auto-instrumentation 的 Created 和/或 Started 条目,则表示您的自动检测存在问题。这可能是以下任何原因造成的:
Instrumentation资源未安装(或未正确安装)。Instrumentation资源在应用程序部署之后安装。- 自动检测注解中存在错误,或注解位置错误 — 请参阅下面的 #4。
请务必检查 kubectl get events 的输出,其中可能包含错误信息,这些信息有助于指出问题所在。
自动检测注解是否正确?
有时自动检测会因自动检测注解中的错误而失败。
以下是一些需要检查的事项:
- 自动检测是否适用于正确的语言?
- 例如,在检测 Python 应用程序时,请确保注解没有错误地写成
instrumentation.opentelemetry.io/inject-java: "true"。 - 对于 **Deno**,请确保您使用的是
instrumentation.opentelemetry.io/inject-sdk: "true"注解,而不是包含字符串deno的注解。
- 例如,在检测 Python 应用程序时,请确保注解没有错误地写成
- **自动检测注解是否在正确的位置?** 在定义
Deployment时,注解可以添加到两个位置之一:spec.metadata.annotations和spec.template.metadata.annotations。自动检测注解需要添加到spec.template.metadata.annotations,否则将不起作用。
自动检测端点是否配置正确?
Instrumentation 资源 的 spec.exporter.endpoint 属性定义了要发送数据的位置。这可以是 OTel Collector,也可以是任何 OTLP 端点。如果省略此属性,则默认为 https://:4317,这很可能不会将遥测数据发送到任何地方。
当将遥测数据发送到位于同一 Kubernetes 集群中的 OTel Collector 时,spec.exporter.endpoint 应引用 OTel Collector Service 的名称。
例如
spec:
exporter:
endpoint: http://demo-collector.opentelemetry.svc.cluster.local:4317
此处,Collector 端点设置为 http://demo-collector.opentelemetry.svc.cluster.local:4317,其中 demo-collector 是 OTel Collector Kubernetes Service 的名称。在上面的示例中,Collector 运行在与应用程序不同的命名空间中,这意味着 opentelemetry.svc.cluster.local 必须附加到 Collector 的服务名称之后,其中 opentelemetry 是 Collector 所在的命名空间。