Open­Te­le­me­try (OTel) in Ku­ber­netes ist ein Cloud-Native-Framework zur her­stel­ler­neu­tra­len Erfassung von Traces, Metriken und Logs. Über K8s-Ope­ra­to­ren und den OTel Collector er­mög­licht es die au­to­ma­ti­sche In­stru­men­tie­rung sowie den Te­le­me­trie-Export via OTLP an verteilte Backends, ohne den An­wen­dungs­code an­zu­pas­sen.

Zu­sam­men­fas­sung

  • Open­Te­le­me­try erfasst in Ku­ber­netes Traces, Metriken und Logs her­stel­ler­neu­tral und ex­por­tiert sie per OTLP.
  • Zu­sam­men­hän­gen­de Traces entstehen nur, wenn alle be­tei­lig­ten Services den Trace Context korrekt wei­ter­ge­ben.
  • Der Collector läuft als DaemonSet, als zentrales Gateway oder als Kom­bi­na­ti­on aus beidem.
  • Der Open­Te­le­me­try Operator ergänzt neue Pods per An­no­ta­ti­on um die au­to­ma­ti­sche In­stru­men­tie­rung.
  • Der Ku­ber­netes At­tri­bu­tes Processor ordnet Spans Namespace, Pod und De­ploy­ment zu.
  • Head- und Tail-Sampling sowie Filter- und Redaction-Pro­zes­so­ren steuern Da­ten­men­ge und sensible Inhalte.

Was leistet Open­Te­le­me­try in Ku­ber­netes?

Die au­to­ma­ti­sche Erfassung ohne Quell­code­än­de­run­gen gilt für un­ter­stütz­te Lauf­zei­ten und Bi­blio­the­ken. Dafür müssen In­stru­men­tie­rung und De­ploy­ment ein­ge­rich­tet werden. Eigene Ge­schäfts­ope­ra­tio­nen benötigen ge­ge­be­nen­falls zu­sätz­li­che Spans im An­wen­dungs­code. Der Open­Te­le­me­try Operator ist außerdem eine mögliche Be­triebs­form, keine zwingende Vor­aus­set­zung für jede OTel-In­stal­la­ti­on. Auch ohne Operator lassen sich SDKs und Collector betreiben.

Reine Metriken zeigen bei­spiels­wei­se, dass die Ant­wort­zeit eines Services steigt. Sie re­kon­stru­ie­ren aber nicht au­to­ma­tisch den Weg einer konkreten Anfrage durch eine Mi­cro­ser­vice-Ar­chi­tek­tur. Ein Trace verbindet die Ope­ra­tio­nen dieser Anfrage. Jeder Span be­schreibt einen einzelnen Abschnitt mit Zeit­in­for­ma­tio­nen und At­tri­bu­ten. Der Trace wird erst voll­stän­dig, wenn die be­tei­lig­ten Services den Kontext korrekt wei­ter­ge­ben.

Context Pro­pa­ga­ti­on überträgt unter anderem Trace-ID und El­tern­be­zie­hung über Pro­zess­gren­zen. Für HTTP wird dafür häufig W3C Trace Context verwendet. OTLP erfüllt eine andere Aufgabe: Das Protokoll trans­por­tiert die erzeugte Te­le­me­trie zum Collector oder Backend. Ein er­reich­ba­rer OTLP-Endpunkt beweist daher noch nicht, dass ein zu­sam­men­hän­gen­der Trace entsteht. Prüfen Sie zunächst einen Request über min­des­tens zwei Services.

Wie wählen Sie das Collector-De­ploy­ment?

Ein Open­Te­le­me­try Collector lässt sich lokal oder zentral be­reit­stel­len. Die Auswahl richtet sich nach der Da­ten­quel­le und dem er­for­der­li­chen Ver­ar­bei­tungs­zu­stand. Node-Dateien erfordern einen lokalen Zugriff. Eine Tail-Sampling-Ent­schei­dung benötigt dagegen die zu­sam­men­ge­hö­ri­gen Spans mehrerer Services. Zu­sätz­li­che Collector-Ebenen sollten einen solchen konkreten Bedarf erfüllen, weil sie Res­sour­cen ver­brau­chen und einen weiteren Trans­port­ab­schnitt einführen.

  • DaemonSet auf Node-Ebene: Geeignet für Host-Metriken und Container-Logs mit lokalem Zugriff. Ein schlank kon­fi­gu­rier­ter Agent übernimmt zu­sätz­lich Me­ta­da­ten­an­rei­che­rung und Wei­ter­lei­tung. Der Res­sour­cen­be­darf wächst mit der Node-Zahl; ein Node-Ausfall betrifft auch den lokalen Agent.
  • De­ploy­ment als Gateway: Geeignet für zentrale Ex­port­re­geln und Backend-Zu­gangs­da­ten. Replikate skalieren un­ab­hän­gig von der Node-Zahl. Tail-Sampling benötigt zu­sätz­lich eine Ver­tei­lung nach Trace-ID. Ein De­ploy­ment allein erzeugt weder globales Load Balancing noch au­to­ma­ti­sche Aus­fall­si­cher­heit.
  • Agent-to-Gateway als Hybrid: Trennt lokale Erfassung von auf­wen­di­ger zentraler Ver­ar­bei­tung. Agents und Gateways benötigen jeweils passende Res­sour­cen­li­mits. Für un­ab­hän­gi­ge Aus­fall­do­mä­nen müssen die Gateway-Replikate auf ge­trenn­ten Nodes liegen und War­te­schlan­gen Störungen zwischen den Ebenen abfedern.

OTLP/gRPC nutzt üb­li­cher­wei­se Port 4317, OTLP/HTTP Port 4318. Beide eignen sich für den Te­le­me­trie­ex­port. Wählen Sie die Variante, die SDK, Ingress und Proxy durch­gän­gig un­ter­stüt­zen. Ein Ku­ber­netes-Service stellt den Gateway-Endpunkt bereit. Beachten Sie bei gRPC, dass lang­le­bi­ge Ver­bin­dun­gen die Last­ver­tei­lung be­ein­flus­sen. TLS und bei Bedarf mTLS sichern die Über­tra­gung, Net­work­Po­li­ci­es be­schrän­ken die erlaubten Kom­mu­ni­ka­ti­ons­we­ge.

IONOS CLOUD Managed Ku­ber­netes
Container Workloads in sicherer Hand

IONOS CLOUD Managed Ku­ber­netes ist die ideale Plattform für per­for­man­te und hoch­ska­lier­ba­re Container-An­wen­dun­gen – rund um die Uhr pro­fes­sio­nell betreut. Ab sofort pro­fi­tie­ren Sie von einer au­to­ma­ti­schen CPU-Zuweisung für Dedicated Cores und kos­ten­ef­fi­zi­en­ten vCPUs für weniger per­for­mance-intensive Workloads. So nutzen Sie Ihre Res­sour­cen optimal, senken Kosten und behalten jederzeit volle Kontrolle über Ihre An­wen­dungs­per­for­mance.

Wie in­stru­men­tiert der Operator Workloads?

Der Open­Te­le­me­try Operator verwaltet Collector-Res­sour­cen und die au­to­ma­ti­sche In­stru­men­tie­rung un­ter­stütz­ter Workloads.

Bei einer In­stal­la­ti­on über das Stan­dard­ma­ni­fest wird cert-manager für die Webhook-Zer­ti­fi­ka­te benötigt; das Helm-Chart un­ter­stützt al­ter­na­tiv unter anderem die au­to­ma­ti­sche Erzeugung eines selbst­si­gnier­ten Zer­ti­fi­kats. Für eine Java-Anwendung wird zunächst eine Instrumentation-Ressource ein­ge­rich­tet. Sie legt unter anderem Ex­port­end­punkt und Pro­pa­ga­to­ren fest. Setzen Sie spec.exporter.endpoint explizit auf einen er­reich­ba­ren Collector-Service. Ohne diese Angabe verwendet der Operator stan­dard­mä­ßig http://localhost:4317, wodurch die Te­le­me­trie in diesem Setup nicht beim zentralen Collector ankommt. Eine An­no­ta­ti­on im Pod-Template wählt an­schlie­ßend die ge­wünsch­te Instrumentation-Ressource aus. Der Admission-Webhook ergänzt neu erstellte Pods um die In­stru­men­tie­rung.

Das folgende Beispiel setzt einen in­stal­lier­ten Operator und einen er­reich­ba­ren Collector-Service otel-gateway im Namespace observability voraus. Der OTLP/HTTP-Receiver muss nicht nur aktiviert, sondern auch über das Pod-Netzwerk er­reich­bar sein, bei­spiels­wei­se mit einem Endpoint wie 0.0.0.0:4318 oder einer passenden Pod-IP. Eine Bindung aus­schließ­lich an localhost ist von anderen Pods nicht er­reich­bar.

apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: checkout-instrumentation
  namespace: apps
spec:
  exporter:
    endpoint: http://otel-gateway.observability.svc.cluster.local:4318
  propagators:
    - tracecontext
    - baggage
  sampler:
    type: parentbased_traceidratio
    argument: "1"
yaml

Die Java-Auto-In­stru­men­tie­rung verwendet stan­dard­mä­ßig OTLP über http/protobuf. Deshalb zeigt das Beispiel auf den OTLP/HTTP-Port 4318 und nicht auf den gRPC-Port 4317.

Der Wert "1" dient hier dazu, in einer Test­um­ge­bung alle neu be­gon­ne­nen Root-Traces aus­zu­wäh­len. Über­nom­me­ne Sampling-Ent­schei­dun­gen folgen dem Parent-Kontext. Für den Pro­duk­tiv­be­trieb ist die Rate bewusst fest­zu­le­gen. Das Beispiel nutzt internes HTTP zur Ver­an­schau­li­chung. Für ver­schlüs­sel­te Ver­bin­dun­gen müssen Endpunkt und Zer­ti­fi­kats­kon­fi­gu­ra­ti­on angepasst werden.

Ergänzen Sie im be­stehen­den De­ploy­ment unter spec.template.metadata.annotations folgende An­no­ta­ti­on. Der Aus­schnitt ist kein voll­stän­di­ges De­ploy­ment-Manifest:

instrumentation.opentelemetry.io/inject-java: "checkout-instrumentation"
yaml

Legen Sie die Instrumentation-Ressource vor dem neuen Pod an. Im Beispiel liegt sie im selben Namespace wie die Anwendung. Al­ter­na­tiv kann die An­no­ta­ti­on mit namespace/name auf eine Instrumentation-Ressource in einem anderen Namespace verweisen. Nach der Änderung des Pod-Templates erzeugt das De­ploy­ment neue Pods. Für andere Sprachen gelten eigene An­no­ta­tio­nen und Kom­pa­ti­bi­li­täts­an­for­de­run­gen. Prüfen Sie an­schlie­ßend die in­ji­zier­te Kon­fi­gu­ra­ti­on, den tat­säch­li­chen Service-Namen und die Er­reich­bar­keit des Receivers. Sind die be­tei­lig­ten Services in­stru­men­tiert und pro­pa­gie­ren sie den Trace Context korrekt, sollten au­to­ma­tisch erzeugte HTTP-Spans einen Test­re­quest ser­vice­über­grei­fend sichtbar machen.

Wie erhalten Spans Ku­ber­netes-Metadaten?

Der Ku­ber­netes At­tri­bu­tes Processor ordnet ein­ge­hen­de Te­le­me­trie einem Pod zu und ergänzt Resource At­tri­bu­tes. Dazu benötigt der Collector passende RBAC-Rechte zum Lesen der re­le­van­ten Ku­ber­netes-Res­sour­cen. Hinter einem Agent oder Proxy sieht ein Gateway mög­li­cher­wei­se nur dessen IP-Adresse. Eine explizit mit­ge­ge­be­ne Pod-UID und eine darauf ab­ge­stimm­te Zu­ord­nungs­re­gel vermeiden dann eine falsche Pod-Zuordnung.

  • k8s_attributes: Ergänzt etwa Namespace, Pod und De­ploy­ment als Resource At­tri­bu­tes. Die Ex­trak­ti­on eigener Labels und An­no­ta­tio­nen wird gezielt kon­fi­gu­riert. Ältere Collector-Versionen und Kon­fi­gu­ra­tio­nen können noch den Alias k8sattributes verwenden.
  • Node­be­zo­ge­ne Be­gren­zung: Im DaemonSet lässt sich die Pod-Erfassung auf den eigenen Node be­schrän­ken. Ein zentrales Gateway benötigt dagegen ge­ge­be­nen­falls einen Cache für Metadaten des gesamten Clusters. Das be­ein­flusst den Spei­cher­be­darf.

Wie steuern Sie Sampling und sensible Daten?

Head-Sampling ent­schei­det früh, häufig bereits im SDK. Es senkt den Da­ten­strom vor dem Collector, kennt aber spätere Fehler eines Requests noch nicht. Tail-Sampling be­rück­sich­tigt die ein­tref­fen­den Spans eines Traces und wählt bei­spiels­wei­se Feh­ler­fäl­le oder langsame Abläufe aus. Was das Head-Sampling bereits verworfen hat, kann das Tail-Sampling nicht nach­träg­lich wie­der­her­stel­len.

Für eine verteilte Tail-Sampling-Stufe müssen alle Spans einer Trace-ID beim selben zu­stän­di­gen Collector ein­tref­fen. Der load_balancing Exporter kann dieses Routing anhand der Trace-ID über­neh­men. Warten auf Spans benötigt Ar­beits­spei­cher. Ent­schei­dungs­war­te­zeit und Trace-Kapazität sind deshalb anhand der Trace-Dauer und Last zu di­men­sio­nie­ren. Än­de­run­gen an der Re­pli­ka­zahl können laufende Zu­ord­nun­gen be­ein­flus­sen.

Wichtige Pro­zes­so­ren über­neh­men dabei un­ter­schied­li­che Aufgaben:

  • tail_sampling: Trifft re­gel­ba­sier­te Ent­schei­dun­gen über Traces. Ku­ber­netes-An­rei­che­rung muss davor erfolgen, wenn sie den ur­sprüng­li­chen Emp­fangs­kon­text benötigt.
  • filter: Verwirft passende Spans oder andere Te­le­me­trie­ele­men­te anhand von Be­din­gun­gen. Der Processor entfernt nicht au­to­ma­tisch nur einzelne sensible Felder eines Spans.
  • redaction: Entfernt nicht zu­ge­las­se­ne Attribute und maskiert kon­fi­gu­rier­te Werte. Bleibt allowed_keys leer und ist allow_all_keys nicht aktiviert, entfernt der Processor alle be­tref­fen­den Attribute. Soll er alle Attribute behalten und nur bestimmte Werte maskieren, setzen Sie allow_all_keys: true. Die Kom­po­nen­te gilt derzeit für Traces als Beta sowie für Logs und Metriken als Alpha.

Erfassen Sie sensible Header und Request-Inhalte möglichst gar nicht erst. Prüfen Sie zu­sätz­lich Span-Namen und Events, damit per­so­nen­be­zo­ge­ne In­for­ma­tio­nen nicht über andere Felder ex­por­tiert werden. Die Pro­zes­so­ren un­ter­stüt­zen tech­ni­sche Da­ten­mi­ni­mie­rung. Eine voll­stän­di­ge An­ony­mi­sie­rung oder rechts­kon­for­me Ge­samt­ver­ar­bei­tung ergibt sich daraus nicht au­to­ma­tisch.

Wie binden Sie das Backend an?

Das Gateway ex­por­tiert an ein OTLP-kom­pa­ti­bles Backend. Das kann ein selbst be­trie­be­nes Open-Source-System oder ein her­stel­ler­neu­tral an­ge­bun­de­ner Managed Service sein. Ein Grafana-Tempo-Backend lässt sich bei­spiels­wei­se in eine be­stehen­de Ana­ly­se­ober­flä­che in­te­grie­ren. Zen­tra­li­sie­ren Sie Backend-Zu­gangs­da­ten im Gateway und kon­fi­gu­rie­ren Sie Export-Queues samt Retries. Prüfen Sie separat, welche Daten bei einem Pod-Neustart tat­säch­lich per­sis­tent bleiben.

Die Kor­re­la­ti­on mit Logs benötigt Trace-ID und ge­ge­be­nen­falls Span-ID im Log-Datensatz. Ge­mein­sa­me Service- und Ku­ber­netes-Attribute er­leich­tern den Wechsel zwischen Signalen. Metrik-Exemplare können auf zu­ge­hö­ri­ge Traces verweisen, wenn In­stru­men­tie­rung und Backend dies un­ter­stüt­zen. Ein Ab­nah­me­test sollte deshalb nicht nur den Trace zeigen, sondern auch den Sprung zum passenden Log-Eintrag und die korrekte Zuordnung nach einem Pod-Wechsel be­stä­ti­gen.

Zum Hauptmenü