使用Kubernetes元数据改进故障排除
注意
关于如何使用Kubernetes元数据增强遥测的最新信息,可以在文档中找到。更多信息请参阅开始使用Kubernetes。将Kubernetes资源元数据附加到OpenTelemetry跟踪中有助于确定哪个资源(例如Pod)发生故障或存在性能问题。这对于跨其他信号进行关联也非常有用,例如:您可以关联由同一Pod生成的日志和跨度。
在本文中,您将学习如何配置OpenTelemetry Collector以在不同场景中使用k8sattributesprocessor。
本文不涵盖OpenTelemetry Collector管道的详细信息。有关此详细信息,请参阅收集器文档。
如何添加K8s属性
在高层次上,K8s属性作为资源附加到跟踪中。这有两个原因:
- K8s属性符合资源的定义:记录遥测的实体
- 它集中了该元数据,对于任何生成的跨度都是相关的。
让我们深入了解如何做到这一点!
使用k8sattributes处理器
这是一个OpenTelemetry处理器,它会自动发现Pod元数据并将其附加到与该Pod生成的跨度关联的资源。如果Pod属于Deployment
或ReplicaSet
,它还会发现其属性。
我们可以附加到资源上的一些属性包括:
- 节点名称
k8s.node.name
- Pod名称
k8s.pod.name
- Pod UID
k8s.pod.uid
- 命名空间
k8s.namespace.name
- 如果Pod是由Deployment创建的,则有部署名称
k8s.deployment.name
此类属性符合OpenTelemetry语义约定。详细信息请参阅[Kubernetes资源语义约定][]。
处理器内部维护着一个Pod列表以及相关的属性,通常是Pod的IP地址,并使用此属性来了解哪个Pod生成了某个跨度。
在上图中,您可以看到数据的流动方式:使用Kubernetes API获取Pod列表,同时从Pod和收集器之间的连接上提取Pod IP。
k8sattributesprocessor
可以在不同模式下工作,具体取决于如何配置收集器。让我们探索一个常见的场景,即以守护程序集方式部署收集器。
守护程序集模式
我们来看看如何以守护程序集模式(也称为k8sattributes文档中的代理模式)配置收集器。
在守护程序集模式下部署收集器时,每个节点有一个收集器Pod。我们需要配置收集器服务帐户以具有获取所有Pod信息的权限。为此,我们将创建一个具有必要权限的ClusterRole
。
以下是使k8sattributesprocessor
工作所需的最低权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: otel-collector
rules:
- apiGroups: ['']
resources: ['pods', 'namespaces']
verbs: ['get', 'watch', 'list']
接下来,部署守护程序集模式的收集器。我们建议您设置一个过滤器,只获取属于部署收集器所在节点的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收集器镜像。k8sattributesprocessor
不是OpenTelemetry Collector核心的一部分,而是contrib发行版中的一部分。还有其他值得注意的事项,如上面提到的过滤器以及使用先前创建的特定服务帐户,该服务帐户包含获取Pod列表的权限。
接下来,部署清单和[vert.x示例应用程序][]以生成一些跟踪。
正如您所看到的,每个跟踪的跨度现在都附带了相应的Pod属性。
如果要将上述配置限制为特定命名空间,可以在k8sattributesprocessor
过滤器中添加命名空间,如以下示例所示:
processors:
k8sattributes:
filter:
namespace: my_namespace
这样,您可以创建一个Role
而不需要创建一个ClusterRole
,将收集器服务帐户的范围限制为单个命名空间。
使用资源检测器处理器
根据最近的更改,OpenTelemetry operator将K8s Pod属性的值设置为收集器容器上的OTEL_RESOURCE_ATTRIBUTES
环境变量。这使您可以使用资源检测器处理器,它将环境变量的值附加到跨度中。这仅在将收集器部署为旁车模式时才起作用。
例如,如果您部署以下清单:
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
环境变量在旁车容器中的值被注入了一些值。其中一些使用Kubernetes下行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跟踪中。虽然所涵盖的场景很基本,但说明了如何向跟踪添加此类元数据,以便您可以将该技术融入到更复杂的场景中。如果您想了解更多不同场景或配置处理器的选项,可以参考K8s属性处理器文档,其中提供了更多的场景,例如旁车模式或一个收集器作为代理向另一个收集器报告。