使用 k8s 元数据改进故障排除
博客文章在发布后不会更新。这篇文章已经发布一年多了,其内容可能已过时,部分链接可能无效。在依赖任何信息之前,请务必核实。
有关如何使用 Kubernetes 元数据增强遥测数据的最新信息,请参阅文档。有关更多信息,请参阅 Kubernetes 入门。
将 Kubernetes 资源元数据附加到 OpenTelemetry Traces 非常有用,可以识别哪个资源(例如 pod)出现故障或存在性能问题。它对于跨其他信号进行关联也很有用,例如:您可以关联由同一个 pod 生成的日志和 Span。
在本文中,您将学习如何在不同场景下配置 OpenTelemetry Collector 以使用 k8sattributesprocessor。
本文将不涵盖 OpenTelemetry Collector pipeline 的详细信息。有关这些详细信息,请参阅 Collector 文档。
K8s 属性如何附加
总体而言,K8s 属性作为 资源 附加到 Traces。这有两个原因:
- K8s 属性符合资源定义:即记录遥测数据的实体。
- 它集中了这些元数据,这些元数据对于任何生成的 Span 都很重要。
让我们深入了解如何实现它!
使用 k8sattributes 处理器
这是一个 OpenTelemetry 处理器,它可以自动发现 pod 元数据并将其附加到与该 pod 生成的 Span 关联的资源上。如果 pod 属于 Deployment 或 ReplicaSet,它还会发现其属性。
我们可以附加到资源的某些属性包括:
- 节点名称
k8s.node.name - Pod 名称
k8s.pod.name - Pod UID
k8s.pod.uid - 命名空间
k8s.namespace.name - Deployment 名称,如果 pod 是由 deployment 创建的,则为
k8s.deployment.name
这些属性符合 OpenTelemetry 语义约定。有关详细信息,请参阅 Kubernetes 资源语义约定。
该处理器在内部维护一个 pod 列表及其关联属性,通常是 pod 的 IP 地址,并使用此属性来知道哪个 pod 生成了某个 Span。

在上图中,您可以看到数据流:Pod 表使用 Kubernetes API 获取,而 Pod IP 则从 Pod 与 Collector 之间的连接上下文中提取。
k8sattributesprocessor 可以根据 Collector 的配置方式在不同模式下工作。让我们探讨一种常见场景:当 Collector 作为 daemonset 部署时。
Daemonset 模式
让我们看看如何在 daemonset 模式下配置 Collector,在 k8sattributes 文档中也称为 agent 模式。
当我们以 daemonset 模式部署 Collector 时,每个节点都有一个 Collector pod。我们需要配置 Collector 服务帐户以拥有获取所有 Pod 信息的权限。为此,我们将创建一个具有必要权限的 ClusterRole。
以下是使 k8sattributesprocessor 工作所需的最低权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: otel-collector
rules:
- apiGroups: ['']
resources: ['pods', 'namespaces']
verbs: ['get', 'watch', 'list']
接下来,以 daemonset 模式部署 Collector。我们建议您设置一个过滤器,仅获取属于 Collector 所部署节点上的 Pod。这是因为如果您有一个大型集群,您不希望维护一个巨大的 Pod 列表。
这是本博客中用于演示处理器工作方式的清单:
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: otel-collector-daemonset
spec:
mode: daemonset
image: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib:0.47.0
serviceAccount: attributes-account
env:
- name: KUBE_NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
config: |
receivers:
jaeger:
protocols:
grpc:
thrift_binary:
thrift_compact:
thrift_http:
otlp:
protocols:
grpc:
http:
processors:
k8sattributes:
filter:
node_from_env_var: KUBE_NODE_NAME
exporters:
jaeger:
endpoint: jaeger-all-in-one-collector:14250
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp, jaeger]
processors: [k8sattributes]
exporters: [jaeger]
需要注意的主要部分是它使用了 contrib Collector 镜像。k8sattributesprocessor 不是 OpenTelemetry Collector 核心的一部分,但 contrib 发行版中包含了它。其他需要注意的点是前面提到的过滤器,以及使用预先创建的特定服务帐户,该帐户具有获取 Pod 列表的权限。
接下来,部署清单和 vert.x 示例应用程序 来生成一些 Traces。

正如您所见,Trace 的每个 Span 现在都已附加了相应的 Pod 属性。
如果您将上面的配置限制到特定命名空间,可以通过将命名空间添加到 k8sattributesprocessor 过滤器来实现,如下所示:
processors:
k8sattributes:
filter:
namespace: my_namespace
这样,您可以创建一个 Role 而无需创建 ClusterRole,从而将 Collector 服务帐户的范围缩小到单个命名空间。
使用 Resource detector processor
最近,OpenTelemetry operator 在 Collector 容器上设置了 OTEL_RESOURCE_ATTRIBUTES 环境变量,其中包含 K8s pod 属性。这允许您使用 resource detector processor,该处理器将环境变量值附加到 Spans。这仅在 Collector 以 sidecar 模式部署时有效。
例如,如果您部署以下清单:
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: sidecar-for-my-app
spec:
mode: sidecar
image: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib:0.47.0
config: |
receivers:
jaeger:
protocols:
grpc:
thrift_binary:
thrift_compact:
thrift_http:
otlp:
protocols:
grpc:
http:
processors:
resourcedetection:
detectors: [env]
timeout: 2s
override: false
exporters:
jaeger:
endpoint: jaeger-all-in-one-collector:14250
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp, jaeger]
processors: [resourcedetection]
exporters: [jaeger]
然后部署 vert.x 示例应用程序,您可以看到 OTEL_RESOURCE_ATTRIBUTES 环境变量被注入了一些值到 sidecar 容器中。其中一些使用了 Kubernetes downward API 来获取属性值。
以下是环境变量值的示例:
- name: OTEL_RESOURCE_ATTRIBUTES
value: k8s.deployment.name=dep-vert-x,k8s.deployment.uid=ef3fe26b-a690-4746-9119-d2dbd94b469f,k8s.namespace.name=default,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=(OTEL_RESOURCE_ATTRIBUTES_POD_NAME),k8s.pod.uid=$(OTEL_RESOURCE_ATTRIBUTES_POD_UID),k8s.replicasetname=dep-vert-x-59b6f76585,k8s.replicaset.uid=5127bc38-e298-40e1-95df-f4a777e3176c
了解更多
本文介绍了如何配置 OpenTelemetry Collector 以将 Kubernetes 资源元数据作为资源属性附加到 OpenTelemetry Traces。所涵盖的场景虽然基础,但说明了如何向 Traces 添加此类元数据,以便您可以将该技术应用于其他更复杂的场景。如果您想了解有关不同场景或配置处理器的选项的更多信息,可以查看 K8sattributes processor 文档,其中可以找到更多场景,例如 sidecar,或者一个 Collector 作为 agent 向另一个 Collector 报告。