Fast jedes erste Kubernetes-Dashboard auf Basis des OpenTelemetry Collectors stellt
innerhalb eines Tages dieselbe Frage: «Ich sehe die CPU pro Pod, aber wie sehe ich sie
pro Deployment?» Die Metrik weiss es nicht. Das Kubelet meldet die Nutzung pro Pod und
hat keine Ahnung, welches Deployment, welches StatefulSet oder welcher CronJob diesen
Pod erzeugt hat. Der Prozessor k8sattributes ergänzt diesen Kontext, und er steckt
auch hinter den meisten Diskussionen der Art «warum ist dieses Attribut leer».
Dieser Beitrag behandelt die drei Stellen, an denen es meistens schiefgeht: wie ein Datenpunkt einem Pod zugeordnet wird, welche RBAC-Rechte jedes Attribut braucht und was nach der Anreicherung mit den Attributen geschieht. Er gehört zu unserer Serie über Kubernetes-Monitoring. Die vollständige Referenz Schicht für Schicht finden Sie im Kubernetes-Monitoring-Leitfaden auf opensight.ch.
Das Wichtigste in Kürze
- Kubelet-Metriken brauchen eine explizite
pod_association-Regel aufk8s.pod.uid. Ohne Regeln ordnet der Prozessor nur über die IP der Verbindung zu, und eine abgefragte Kubelet-Metrik hat keine Pod-Verbindung, die passen könnte. - Der Standardwert von
k8s.deployment.namewird aus dem ReplicaSet-Namen abgeleitet und braucht nur Rechte aufpodsundnamespaces. Rechte aufreplicasetsbrauchen Sie nur fürk8s.deployment.uidoder für Deployment-Labels. - Fehlende RBAC-Rechte lassen die Pipeline nie scheitern. Das Attribut bleibt leer, und der einzige Hinweis ist eine «forbidden»-Zeile im Collector-Log.
- Ordnen Sie über die Pod-UID zu, behalten Sie die stabilen Namen, löschen Sie die UID vor dem Export, und machen Sie nur das zum Metrik-Label, wonach Sie filtern.
Warum Kubelet-Metriken keinen Deployment-Namen haben
Der Receiver kubeletstats liefert die Nutzung von Pods und Containern mit wenigen
Resource-Attributen: k8s.pod.uid, k8s.pod.name und k8s.namespace.name. Mehr weiss
das Kubelet nicht. Die Besitzverhältnisse stehen in der Kubernetes-API: Der Pod hat eine
Owner-Referenz auf ein ReplicaSet, und das ReplicaSet eine auf ein Deployment.
Der Prozessor k8sattributes schliesst diese Lücke. Er beobachtet Pods über die API,
hält sie in einem lokalen Cache und macht für jeden Datenpunkt, der ihn passiert, drei
Dinge: den Pod finden, zu dem der Datenpunkt gehört, dessen Metadaten und Owner lesen und
das Ergebnis als Resource-Attribute zurückschreiben.
Abbildung 1. Der Anreicherungsweg für einen Kubelet-Datenpunkt. Bei Schritt 2 beginnen die meisten leeren Attribute.
Pod-Zuordnung: Sagen Sie dem Prozessor, wie er den Pod findet
Die Zuordnung wird als geordnete Liste von pod_association-Regeln konfiguriert. Jede
Regel nennt eine oder mehrere Quellen, und alle Quellen einer Regel müssen passen. Es
gibt zwei Quelltypen: resource_attribute (ein benanntes Attribut der eingehenden
Resource nachschlagen) und connection (die IP-Adresse verwenden, von der die Daten
kommen).
Der Standard ist hier entscheidend. Wenn Sie gar keine Regeln konfigurieren, ordnet der Prozessor nur über die IP der Verbindung zu. Das funktioniert für einen Anwendungs-Pod, der OTLP direkt an einen Collector auf demselben Node schickt, weil die IP der Verbindung die Pod-IP ist. Für Kubelet-Metriken funktioniert es nicht, denn die fragt der Collector selbst ab. Die erste Regel ist also die Pod-UID, mit der IP der Verbindung als Rückfall für OTLP:
processors:
k8sattributes:
auth_type: serviceAccount
filter:
node_from_env_var: K8S_NODE_NAME # Agent: nur Pods auf diesem Node
extract:
metadata:
- k8s.namespace.name
- k8s.pod.name
- k8s.pod.uid
- k8s.deployment.name
- k8s.statefulset.name
- k8s.daemonset.name
- k8s.node.name
labels:
- tag_name: app
key: app.kubernetes.io/name
from: pod
pod_association:
- sources:
- from: resource_attribute
name: k8s.pod.uid # Kubelet-Metriken
- sources:
- from: connection # OTLP direkt von Anwendungs-Pods
Drei Details aus der Dokumentation des Prozessors sollten Sie kennen, bevor Sie etwas debuggen:
- Der Node-Filter ist in einem DaemonSet nicht optional. Ohne
node_from_env_varbeobachtet jeder Agent jeden Pod im Cluster. Übergeben Sie den Node-Namen über die Downward API (fieldPath: spec.nodeName), und lassen Sie den Filter auf diese Variable zeigen. - Eine
connection-Regel muss vor jedem Batching stehen. Der Batch-Prozessor verwirft den Verbindungskontext, also gehörtk8sattributesvorbatch. - Pods im Host-Netzwerk lassen sich nicht über die IP zuordnen. Sie teilen alle die Adresse des Nodes. Ordnen Sie diese über ein Resource-Attribut zu.
Wenn Sie Agents und ein Gateway betreiben, ist das dokumentierte Muster
passthrough: true auf den Agents. Diese setzen dann nur die Pod-IP auf die Daten,
machen keine API-Aufrufe und überlassen das Nachschlagen dem Gateway. So gibt es einen
Pod-Cache pro Gateway statt einen pro Node, um den Preis eines Gateways, das den ganzen
Cluster beobachtet.
RBAC: Welches Attribut welche Rechte braucht
Hier widersprechen sich die Anleitungen, die Sie finden, teilweise weil sich der
Prozessor verändert hat. Der Deployment-Name braucht standardmässig keinen Zugriff
mehr auf ReplicaSets. Steht k8s.deployment.name in extract.metadata, liest der
Prozessor den ReplicaSet-Namen aus der Owner-Referenz des Pods und schneidet den
Pod-Template-Hash ab. Aus checkout-7d9f8b6c5 wird checkout, ganz ohne Abfrage des
ReplicaSets.
Zugriff auf ReplicaSets braucht es wieder in zwei Fällen: wenn Sie k8s.deployment.uid
anfordern oder wenn Sie Labels oder Annotationen from: deployment oder
from: replicaset extrahieren. Dann startet der Prozessor einen ReplicaSet-Informer und
löst den Namen über die API auf. Für CronJobs gilt dasselbe Muster: Der Name allein wird
aus dem Job-Namen abgeleitet, und der Job-Informer startet nur für die UID oder für
Labels von Jobs und CronJobs.
Abbildung 2. Die Rechte, die jede Art von Attribut braucht, gemäss dem RBAC-Abschnitt
des Prozessors. Vergeben Sie, was Ihr extract-Block verlangt, nicht mehr.
Die Falle ist nicht das fehlende Recht an sich. Sie liegt darin, dass unvollständige RBAC-Rechte nichts kaputt machen, was Ihnen auffallen würde. Die Pipeline läuft weiter, Daten kommen an, und das Attribut fehlt einfach. Der einzige Hinweis ist ein «forbidden»-Fehler im Log des Collectors, das niemand liest, solange die Dashboards grün sind.
Zwei Gewohnheiten fangen das ab:
- Fragen Sie nach jeder Änderung an der Collector-Konfiguration oder an ihrem
ServiceAccount nach Pod-Metriken, denen
k8s.deployment.name,k8s.statefulset.nameundk8s.daemonset.namegleichzeitig fehlen. Abgesehen von alleinstehenden Pods sollte diese Menge leer sein. - Alarmieren Sie auf «forbidden» im Collector-Log, so wie Sie auf fehlgeschlagene Exporte alarmieren.
Zuordnen, behalten, löschen, als Label übernehmen
Sobald die Anreicherung funktioniert, ist das nächste Problem, dass es zu viel davon gibt. Ein Attribut kann drei verschiedene Aufgaben haben, und was für die eine perfekt ist, ist für die nächste oft falsch.
Abbildung 3. Die Pod-UID ist der beste Schlüssel für die Zuordnung und einer der schlechtesten zum Behalten.
Ordnen Sie über das zu, was eindeutig ist. k8s.pod.uid bezeichnet genau einen Pod,
deshalb nutzt die Zuordnung sie.
Exportieren Sie nicht, was sich bei jedem Rollout ändert. Dieselbe Eindeutigkeit macht die UID zu einem schlechten Wert zum Speichern: Jeder Neustart erzeugt einen neuen Wert, und jeder neue Wert ist eine neue Serie in einem Metrik-Backend. Löschen Sie sie einmal, nach der Anreicherung und vor dem letzten Export-Schritt, zusammen mit anderen schnell wechselnden Prozess-Attributen:
processors:
resource/drop_noisy:
attributes:
- { key: k8s.pod.uid, action: delete }
- { key: process.pid, action: delete }
- { key: process.command_line, action: delete }
- { key: container.image.id, action: delete }
service:
pipelines:
metrics:
receivers: [ kubeletstats, otlp ]
processors: [ memory_limiter, k8sattributes, resource/drop_noisy, batch ]
exporters: [ otlp ]
Behalten Sie die stabilen Namen. Namespace, Deployment, Node und ein oder zwei
Labels wie app überstehen Neustarts und beantworten die Fragen, die tatsächlich
gestellt werden.
Machen Sie nur das zum Label, wonach Sie filtern. Das ist die Label-Falle. Ein
Resource-Attribut ist nicht automatisch ein Metrik-Label. Mit den Exportern für
Prometheus und Prometheus Remote Write landen Resource-Attribute standardmässig in einer
separaten Metrik target_info, die Sie zur Abfragezeit verknüpfen. Sie können alle zu
Labels auf jeder Serie machen, was funktioniert und die Kardinalität vervielfacht. Oder
Sie übernehmen eine kurze Liste: Prometheus 3.x macht das für OTLP-Ingestion mit
promote_resource_attributes, und der Prozessor transform kann einzelne Attribute in
Datenpunkt-Attribute kopieren. Optionsnamen ändern sich zwischen Versionen, prüfen Sie
sie also gegen Ihre. Namespace, Deployment und Node sind meistens die Liste.
Checkliste vor dem Rollout
pod_associationhat eine Regel aufk8s.pod.uidfür Kubelet-Daten und eineconnection-Regel für OTLP von Pods.- Agents filtern mit
node_from_env_varauf ihren eigenen Node, gespeist über die Downward API. k8sattributessteht in jeder Pipeline mit einerconnection-Regel vorbatch.- RBAC vergibt genau, was der
extract-Block braucht (Abbildung 2). - Eine Abfrage nach Pod-Metriken ohne Workload-Owner liefert nichts, und «forbidden» im Collector-Log löst einen Alarm aus.
- Pod-UID und Prozess-Attribute werden vor dem Export gelöscht.
- Nur die Attribute, nach denen Sie filtern, werden zu Metrik-Labels.
Das meiste davon ist Collector-Konfiguration, die auf jedem Node und in jedem Cluster
identisch sein muss. Genau dort driftet eine Flotte auseinander: Ein Cluster bekommt die
neuen RBAC-Rechte, ein anderer behält den extract-Block vom letzten Quartal. LinkMesh
verwaltet die Konfiguration von OpenTelemetry Collectors über eine ganze Flotte, mit
gestaffeltem Rollout und Rollback und
Drift-Erkennung, damit eine Änderung wie die
obige überall ankommt oder nirgends. Wo Agent und Gateway überhaupt sitzen, lesen Sie in
Deployment-Muster für den Collector.
Quellen
- OpenTelemetry Collector Contrib: README des k8sattributes-Prozessors, Abschnitte zu Pod-Zuordnung, Ableitung des Deployment-Namens, RBAC und Einsatzszenarien. Gelesen am 22.10.2026.
- OpenTelemetry Collector Contrib: kubeletstats-Receiver.
- Prometheus: Using Prometheus as your OpenTelemetry backend, zur Übernahme von Resource-Attributen.
- OpenSight: Kubernetes-Monitoring, der vollständige Leitfaden Schicht für Schicht.