注入自动仪表化
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资源使用otlp
和http/protobuf
协议。这意味着配置的端点必须能够接收http/protobuf
的OTLP。因此,示例中使用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自动仪表化文档。
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资源使用otlp
和grpc
协议。这意味着配置的端点必须能够接收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资源使用otlp
和grpc
协议。这意味着配置的端点必须能够接收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
资源使用otlp
和http/protobuf
协议(目前不支持gRPC)。这意味着配置的端点必须能够接收http/protobuf
的OTLP。因此,示例中使用http://demo-collector:4318
,它将连接到先前步骤中创建的Collector的otlpreceiver
的http
端口。
从operator v0.67.0开始,Instrumentation资源会自动将
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL
和OTEL_EXPORTER_OTLP_METRICS_PROTOCOL
设置为http/protobuf
。如果您使用的是较旧版本的Operator,必须将这些环境变量设置为http/protobuf
,否则python自动仪表化将无法工作。
自动仪表化Python日志
默认情况下,禁用了Python日志自动仪表化。如果要启用此功能,必须将OTEL_LOGS_EXPORTER
和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_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:
<逗号分隔的要从仪表化中排除的软件包名称列表>
了解更多
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资源使用otlp
和grpc
协议。这意味着配置的端点必须能够接收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-instrumentation
的 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
如果输出中缺少 Created
和/或 Started
条目以及 opentelemetry-auto-instrumentation
,则意味着您的自动仪表化存在问题。这可能是以下任何原因导致的:
Instrumentation
资源未安装(或未正确安装)。Instrumentation
资源在应用程序部署之后才安装。- 自动仪表化注释存在错误,或者注释位置错误 - 请参阅下面的 #4。
请务必检查 kubectl get events
的输出,查看是否有任何错误,因为这些可能有助于指出问题。
自动仪表化注释是否正确?
有时,自动仪表化可能会由于自动仪表化注释中的错误而失败。
以下是要检查的几个事项:
- 自动仪表化是否针对正确的语言? 例如,当为 Python 应用程序添加仪表化时,请确保注释不会错误地设置为
instrumentation.opentelemetry.io/inject-java: "true"
。 - 自动仪表化注释是否在正确的位置? 在定义
Deployment
时,注释可以添加在两个位置:spec.metadata.annotations
和spec.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
是收集器所在的命名空间。