Inhoudsopgave
- Wat je leert
- Vereisten
- Wat OpenTelemetry toevoegt aan je Kubernetes-stack
- Architectuur: signalen, Collector, Operator
- Wat OpenTelemetry niet is
- cert-manager en de OpenTelemetry Operator installeren
- Een DaemonSet Collector voor node-niveau signalen
- Een Deployment Collector voor clusterniveau signalen
- Workloads auto-instrumenteren met de Instrumentation CRD
- Signalen routeren naar backends
- De pipeline end-to-end verifieren
- Veelvoorkomende valkuilen
- Wat je hebt geleerd
- Verder lezen
Wat je leert
Aan het eind van deze tutorial draait de OpenTelemetry Operator op je cluster, verzamelen twee Collectors de juiste signalen op het juiste niveau, en produceert minstens een workload traces zonder dat er ook maar een regel applicatiecode veranderd is. Je begrijpt waarom er twee Collectors zijn in plaats van een, welke receivers bij welke mode horen, en hoe je de output routeert naar Prometheus, Grafana Tempo of Jaeger.
Vereisten
Zorg dat je het volgende bij de hand hebt:
- Een draaiend Kubernetes-cluster, versie 1.25 of nieuwer. Een managed cluster (GKE, EKS, AKS) of een lokaal kind/minikube-cluster werkt allebei. Deze tutorial is geschreven tegen OpenTelemetry Operator v0.148.0, uitgebracht in maart 2026.
- Helm 3.9 of nieuwer, geconfigureerd voor je cluster. De Operator-chart vereist Helm 3.9+.
kubectlmet cluster-admin-rechten. De Operator installeert CRDs en clusterwijde resources.- Een observability-backend om naartoe te sturen. In deze tutorial gebruik ik Prometheus en Grafana Tempo als voorbeeld; heb je al Prometheus draaien via kube-prometheus-stack, dan hergebruik je die en voeg je alleen Tempo toe voor traces.
- Basiskennis van Kubernetes Deployments, DaemonSets en pod-annotaties. Is TLS-automatisering nieuw voor je, dan legt de cert-manager tutorial die voorwaarde uit.
Wat OpenTelemetry toevoegt aan je Kubernetes-stack
Als je al Prometheus hebt die metrics scrapet en Fluent Bit die logs verstuurt, is de eerlijke vraag wat OpenTelemetry er dan nog aan toevoegt. Het antwoord heeft drie delen.
Een derde signaaltype dat je waarschijnlijk nog niet hebt: distributed traces. Metrics vertellen je dat de checkout-API traag is. Logs vertellen je wat de checkout-API printte terwijl hij traag was. Traces laten zien wat het volledige requestpad was over de vijf services die de checkout-API aanriep, waar de tijd in elke hop bleef hangen, en welke hop de tail-latency veroorzaakte. Prometheus produceert geen traces. Fluent Bit ook niet. Zonder traces is latency-analyse in een service mesh gewoon gokken.
Een enkel wire-formaat. OpenTelemetry definieert het OTLP-protocol, een gedeelde encoding voor traces, metrics en logs over gRPC (poort 4317) en HTTP (poort 4318). Elke grote backend spreekt OTLP inmiddels native: Prometheus via OTLP-ingest, Grafana Tempo, Jaeger, Elasticsearch APM, Datadog, Honeycomb, New Relic. Je kiest de backend. En je hoeft nooit opnieuw te instrumenteren als je later wisselt.
Auto-instrumentatie zonder codewijzigingen. De OpenTelemetry Operator injecteert een init-container in geannoteerde pods die de language runtime voorziet van een OpenTelemetry-agent nog voordat je applicatie start. Java, Python, Node.js, .NET, Go, Apache HTTPD en Nginx zijn ondersteund. Je voegt een annotatie toe. Traces verschijnen.
Dat is waarom OpenTelemetry de moeite waard is zelfs als je al een werkende Prometheus-setup hebt. Het vult een gat in plaats van te vervangen wat werkt.
Architectuur: signalen, Collector, Operator
De architectuur heeft drie lagen.
Signalen. Traces, metrics en logs. Dat zijn de drie telemetriesignalen die OpenTelemetry definieert. Je applicatie stuurt ze uit, Collectors ontvangen, transformeren en exporteren ze.
Collectors. Een Collector is een standalone proces dat telemetrie ontvangt, door een pipeline van processors stuurt, en naar een of meer backends exporteert. Collectors schalen horizontaal en zijn backend-onafhankelijk. Op Kubernetes is de officiele aanbeveling om twee Collectors te draaien:
- Een DaemonSet Collector op elke node voor node-lokale telemetrie (kubelet-stats, container-logs, host-metrics) en om OTLP te ontvangen van workloads op diezelfde node. "A daemonset is used to guarantee that this instance of the collector is installed on all nodes."
- Een Deployment Collector met precies een replica voor clusterwijde telemetrie (cluster-scoped metrics, Kubernetes-events). "A deployment with exactly one replica ensures that we don't produce duplicate data."
Operator. De OpenTelemetry Operator is een Kubernetes-operator die twee CRDs reconciles: OpenTelemetryCollector (die een Collector-deployment beschrijft) en Instrumentation (die beschrijft hoe pods geauto-instrumenteerd worden). De Operator injecteert ook auto-instrumentatie init-containers in pods met de juiste annotatie.
Je kunt de Collector ook zonder de Operator draaien, met ruwe manifests. Je verliest dan wel de CRD-gedreven workflow, de auto-instrumentatie-injector en de target allocator voor Prometheus-metrics. Voor een productiecluster is de Operator de extra component waard.
Wat OpenTelemetry niet is
Drie misverstanden komen consistent voorbij.
OpenTelemetry vervangt Prometheus niet. OpenTelemetry definieert signalen, SDKs en een wire-formaat. Het bevat geen time-series database, geen querytaal zoals PromQL, en geen alerting engine. Je hebt nog steeds een metrics-backend nodig. Prometheus blijft daar een prima keuze voor; de OTLP-receiver in Prometheus 3.x accepteert metrics direct vanuit Collectors. OpenTelemetry zit voor Prometheus, niet in plaats ervan.
Auto-instrumentatie vereist geen codewijzigingen. Dat is nou net het hele punt. De Operator's automatische instrumentatie injecteert een init-container met de naam opentelemetry-auto-instrumentation in elke pod met de juiste annotatie. Die init-container kopieert de language-agent naar een gedeeld volume; je app-container laadt 'm via environment variables die de Operator zet. Je Dockerfile, je broncode, je CI-pijplijn: alles blijft ongewijzigd.
Een Collector-deployment is niet genoeg voor productie. Een enkele Deployment Collector kan geen kubelet-stats van elke node verzamelen (draait maar op een node) en kan geen /var/log/pods/*/*/*.log tailen over het hele cluster. Een enkele DaemonSet Collector zou weer cluster-scoped data dupliceren (een kopie per node) bij het scrapen van de Kubernetes API. De DaemonSet + Deployment-splitsing is geen optimalisatie. Het is een correctheidsvereiste.
cert-manager en de OpenTelemetry Operator installeren
De Operator gebruikt validating en mutating admission webhooks, en die hebben TLS nodig. De Helm-chart biedt drie manieren om die TLS te leveren: cert-manager (aanbevolen), zelf-gegenereerde self-signed certs uit de chart, of certs die je zelf aanlevert. Deze tutorial gebruikt cert-manager omdat dat de route is die meeschaalt naar andere operators die je later toevoegt.
Stap 1: installeer cert-manager
# cert-manager v1.20.2 via OCI-registry (aanbevolen door jetstack)
helm install cert-manager oci://quay.io/jetstack/charts/cert-manager \
--version v1.20.2 \
--namespace cert-manager \
--create-namespace \
--set crds.enabled=true
De cert-manager installatiedocs beschrijven ook de legacy HTTP-repositorymethode als je omgeving OCI-registries blokkeert.
Verwachte output. helm list -n cert-manager toont cert-manager in deployed state, en kubectl get pods -n cert-manager toont drie pods running: de controller, de webhook en de cainjector.
Stap 2: voeg de OpenTelemetry Helm-repository toe
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
Stap 3: installeer de Operator
# Operator v0.148.0; overschrijft de default collector-image naar de
# Kubernetes-aware distributie (otelcol-k8s) die de k8sattributes-,
# k8scluster-, kubeletstats- en filelog-componenten bundelt.
helm install opentelemetry-operator open-telemetry/opentelemetry-operator \
--namespace opentelemetry \
--create-namespace \
--set "manager.collectorImage.repository=ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-k8s" \
--set admissionWebhooks.certManager.enabled=true
Die manager.collectorImage.repository-override is belangrijk: de default collector-image is de minimale otelcol-distributie en mist Kubernetes-specifieke receivers. De opentelemetry-collector-k8s-distributie bundelt de receivers die je hier wel nodig hebt.
Verwachte output. Binnen een minuut:
kubectl get pods -n opentelemetry
Toont een pod opentelemetry-operator-<hash> in Running state. kubectl get crd | grep opentelemetry toont opentelemetrycollectors.opentelemetry.io en instrumentations.opentelemetry.io als geinstalleerde CRDs.
Hangt de Operator-pod in ContainerCreating met een webhook-foutmelding, dan heeft cert-manager het certificaat nog niet uitgegeven. Wacht 30 seconden en check kubectl get certificate -n opentelemetry; zodra het certificaat op Ready=True staat, start de webhook.
Een DaemonSet Collector voor node-niveau signalen
De DaemonSet Collector draait op elke node en heeft vier taken:
- OTLP ontvangen van lokale workloads op poort 4317 (gRPC) en 4318 (HTTP). Door dit local-only te houden voorkom je onnodige netwerkhops.
- Kubelet-stats verzamelen (pod- en container-CPU/geheugen) via de
kubeletstats-receiver. - Container-logs tailen uit
/var/log/pods/*/*/*.logvia defilelog-receiver. - Elk signaal verrijken met Kubernetes-metadata (podnaam, namespace, labels) via de
k8sattributes-processor.
Pas het volgende manifest toe:
# otel-collector-daemonset.yaml
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
name: otel-agent
namespace: opentelemetry
spec:
mode: daemonset
# De k8s-distributie bevat de receivers die deze config nodig heeft.
image: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-k8s:0.120.0
# Host-mounts voor log-tailing en kubelet-stats.
volumeMounts:
- name: varlogpods
mountPath: /var/log/pods
readOnly: true
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlogpods
hostPath:
path: /var/log/pods
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
# Moet op elke node draaien, inclusief control plane.
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
# Nodig zodat kubeletstats tegen de lokale kubelet kan authenticeren.
env:
- name: K8S_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
config:
receivers:
# Applicaties sturen OTLP naar de lokale DaemonSet via localhost.
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
# Pod/container-metrics vanaf de lokale kubelet.
kubeletstats:
auth_type: serviceAccount
collection_interval: 30s
endpoint: https://${env:K8S_NODE_NAME}:10250
insecure_skip_verify: true # acceptabel voor kubelet on-node
# Container stdout/stderr-logs.
filelog:
include:
- /var/log/pods/*/*/*.log
exclude:
- /var/log/pods/opentelemetry_*/*/*.log # voorkomt log-loops
start_at: end
include_file_path: true
processors:
# Verrijkt signalen met pod/namespace/label-metadata.
k8sattributes:
auth_type: serviceAccount
passthrough: false
extract:
metadata:
- k8s.namespace.name
- k8s.pod.name
- k8s.pod.uid
- k8s.node.name
pod_association:
- sources:
- from: resource_attribute
name: k8s.pod.uid
- sources:
- from: connection
batch: {} # altijd batchen voor export
exporters:
# Stuur alles door naar de cluster-Collector (volgende sectie).
otlp:
endpoint: otel-gateway.opentelemetry.svc.cluster.local:4317
tls:
insecure: true # in-cluster verkeer
service:
pipelines:
traces:
receivers: [otlp]
processors: [k8sattributes, batch]
exporters: [otlp]
metrics:
receivers: [otlp, kubeletstats]
processors: [k8sattributes, batch]
exporters: [otlp]
logs:
receivers: [otlp, filelog]
processors: [k8sattributes, batch]
exporters: [otlp]
kubectl apply -f otel-collector-daemonset.yaml
Verwachte output. kubectl get daemonset -n opentelemetry toont otel-agent-collector met DESIRED gelijk aan het aantal nodes in je cluster, en dezelfde waarde bij READY. Op elke node luistert nu een Collector op het host-netwerk voor OTLP op 4317/4318 en scrapet de lokale kubelet.
Draait de DaemonSet maar laat kubeletstats TLS-fouten zien in de logs, dan is insecure_skip_verify: true de pragmatische fix. Voor een strakke productie-setup mount je liever de kubelet CA-bundle; de kubeletstats-receiver docs laten beide paden zien.
Een Deployment Collector voor clusterniveau signalen
De Deployment Collector draait met precies een replica en behandelt signalen die alleen op clusterniveau zinvol zijn:
- Clusterwijde metrics (nodecondities, podfases, deployment-replicacounts) via de
k8scluster-receiver. - Kubernetes-events via de
k8sobjects-receiver. - Telemetrie ontvangen en doorsturen vanaf de DaemonSet Collectors naar de backends.
# otel-collector-deployment.yaml
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
name: otel-gateway
namespace: opentelemetry
spec:
mode: deployment
replicas: 1 # cluster-scoped receivers vragen om exact een
image: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-k8s:0.120.0
config:
receivers:
# DaemonSets pushen OTLP hierheen.
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
# Clusterwijde metrics (podfases, nodecondities, deploymentstatus).
k8s_cluster:
auth_type: serviceAccount
collection_interval: 30s
node_conditions_to_report: [Ready, MemoryPressure, DiskPressure, PIDPressure]
# Kubernetes-events als logrecords.
k8sobjects:
auth_type: serviceAccount
objects:
- name: events
mode: watch
group: events.k8s.io
processors:
batch: {}
exporters:
# Traces -> Tempo.
otlp/tempo:
endpoint: tempo.observability.svc.cluster.local:4317
tls:
insecure: true
# Metrics -> Prometheus via OTLP-ingest (Prometheus 3.x).
otlphttp/prometheus:
endpoint: http://kube-prom-stack-kube-prom-prometheus.monitoring.svc.cluster.local:9090/api/v1/otlp
tls:
insecure: true
# Logs -> een Loki OTLP-endpoint, of ruil om voor je eigen log-backend.
otlphttp/loki:
endpoint: http://loki-gateway.logging.svc.cluster.local/otlp
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp/tempo]
metrics:
receivers: [otlp, k8s_cluster]
processors: [batch]
exporters: [otlphttp/prometheus]
logs:
receivers: [otlp, k8sobjects]
processors: [batch]
exporters: [otlphttp/loki]
kubectl apply -f otel-collector-deployment.yaml
Verwachte output. kubectl get deployment -n opentelemetry toont otel-gateway-collector met READY 1/1. De Operator heeft ook een Service aangemaakt met de naam otel-gateway-collector.opentelemetry.svc.cluster.local op poort 4317 en 4318, precies waar de DaemonSet's OTLP-exporter op target.
Workloads auto-instrumenteren met de Instrumentation CRD
De auto-instrumentatiefeature van de Operator injecteert een language-agent in pods met de juiste annotatie. Je configureert dat een keer per namespace met een Instrumentation-resource.
Stap 1: maak een Instrumentation-resource
# instrumentation.yaml
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: default
namespace: production
spec:
# Traces en metrics van geinstrumenteerde apps gaan hierheen.
# Wijst naar de lokale DaemonSet Collector op dezelfde node.
exporter:
endpoint: http://$(K8S_NODE_IP):4318
propagators:
- tracecontext
- baggage
- b3
sampler:
type: parentbased_traceidratio
argument: "0.25" # sample 25% van alle root traces
# Language-defaults; overschrijf per taal waar nodig.
java:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:latest
python:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-python:latest
nodejs:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-nodejs:latest
dotnet:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-dotnet:latest
kubectl apply -f instrumentation.yaml
De $(K8S_NODE_IP)-placeholder wordt door de Operator bij pod-start ingevuld met het node-IP, zodat elke pod OTLP naar de DaemonSet Collector op de eigen node stuurt. Dat scheelt cross-node verkeer voor high-throughput signalen.
Stap 2: annoteer je workloads
Voeg een language-specifieke annotatie toe aan de pod-template. Voor een Java-Deployment:
# order-api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-api
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: order-api
template:
metadata:
labels:
app: order-api
annotations:
# Een annotatie. Meer hoeft er niet aan je workload te veranderen.
instrumentation.opentelemetry.io/inject-java: "true"
spec:
containers:
- name: app
image: registry.example.nl/order-api:1.14.0
ports:
- containerPort: 8080
De annotatiewaarden voor andere runtimes:
- Python:
instrumentation.opentelemetry.io/inject-python: "true" - Node.js:
instrumentation.opentelemetry.io/inject-nodejs: "true" - .NET:
instrumentation.opentelemetry.io/inject-dotnet: "true" - Go:
instrumentation.opentelemetry.io/inject-go: "true"(eBPF-gebaseerd, nog werk in uitvoering vanaf Operator v0.148.0; vereist verhoogde rechten) - Apache HTTPD:
instrumentation.opentelemetry.io/inject-apache-httpd: "true" - Nginx:
instrumentation.opentelemetry.io/inject-nginx: "true"
Verwacht gedrag. Bij de volgende rollout van order-api toont kubectl describe pod op een nieuwe pod een init-container opentelemetry-auto-instrumentation-java en environment variables als OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME=order-api en JAVA_TOOL_OPTIONS=-javaagent:/otel-auto-instrumentation-java/javaagent.jar. De applicatiecontainer zelf blijft ongewijzigd.
Kanttekening over Go
Go auto-instrumentatie werkt fundamenteel anders. De Go-compiler produceert een statisch binary zonder runtime-agent-hook, dus injecteert de Operator een eBPF-gebaseerde sidecar die het binary vanaf kernelniveau volgt. Die sidecar heeft privileged: true en runAsUser: 0 nodig, en je moet instrumentation.opentelemetry.io/otel-go-auto-target-exe zetten op het absolute pad van je Go-binary binnen de container. Voor productie-Go-workloads is de OpenTelemetry SDK in de broncode opnemen meestal toch de schonere route.
Signalen routeren naar backends
Het Deployment Collector-voorbeeld hierboven laat al drie gangbare routes zien. Een korte naslag:
Traces naar Grafana Tempo. Installeer Tempo via z'n Helm-chart en wijs otlp/tempo op het OTLP-ingest-endpoint op poort 4317. Tempo slaat traces op in object storage en bevraagt ze via TraceQL in Grafana.
Traces naar Jaeger. Jaeger heeft sinds versie 1.35 native OTLP-ondersteuning. Vervang de Tempo-exporter door:
otlp/jaeger:
endpoint: jaeger-collector.observability.svc.cluster.local:4317
tls:
insecure: true
Metrics naar Prometheus. Prometheus 3.x accepteert OTLP-metrics direct op /api/v1/otlp/v1/metrics. Zet de feature aan via --web.enable-otlp-receiver op de Prometheus-pod; gebruik je kube-prometheus-stack, zet dan prometheus.prometheusSpec.enableFeatures: [otlp-write-receiver] in de chart-values.
Metrics naar een bestaande Prometheus-only backend. Gebruik dan de prometheusremotewrite-exporter in plaats van otlphttp. Die spreekt het legacy Prometheus remote-write-protocol.
Logs naar Loki. Loki 3.0+ accepteert OTLP op /otlp/v1/logs. Wijs de otlphttp/loki-exporter op de Loki-gateway.
Logs naar Elasticsearch. Gebruik de elasticsearch-exporter (zit in de otelcol-contrib-distributie, niet in otelcol-k8s). Heb je Elasticsearch al als log-backend via Fluent Bit en de EFK-stack, dan is Fluent Bit voor logs houden en OpenTelemetry alleen voor traces en metrics gebruiken een prima splitsing.
De pipeline end-to-end verifieren
Voordat je 'em uitroept als af, stuur je signalen door de volledige pipeline.
Controleer de Collector-logs
# DaemonSet-kant
kubectl logs -n opentelemetry -l app.kubernetes.io/name=otel-agent-collector --tail=50
# Deployment-kant
kubectl logs -n opentelemetry -l app.kubernetes.io/name=otel-gateway-collector --tail=50
Zoek naar regels met Everything is ready. Begin running and processing data. Een connection refused aan de DaemonSet-kant wijst meestal op de Service-naam van de Deployment Collector; een TLS-fout op de backend-exporter wijst op certificate trust.
Genereer een trace
Deploy een geannoteerde workload en raak een HTTP-endpoint aan. Voor een snelle smoketest bevat de OpenTelemetry demo-applicatie een microservices-stack die traces, metrics en logs in realistische patronen produceert.
Bevestig dat traces in Tempo landen
Kies in Grafana de Tempo-datasource en zoek op spans met service.name = order-api (of welke servicenaam de Operator ook gezet heeft). Traces verschijnen binnen 30 seconden.
Bevestig dat metrics in Prometheus landen
Draai in de Prometheus-UI de query {__name__=~".+", job="otel-collector"}. Je moet een resultaatset met meer dan nul rijen zien (Status > Targets is hier niet relevant, want dit is push, geen pull).
Bevestig dat logs in Loki landen
Draai in Grafana Explore met de Loki-datasource de query {k8s_namespace_name="production"}. Logs met verrijkte Kubernetes-metadata verschijnen.
Checkpoint. Landen alle drie de signalen in hun respectievelijke backends en dragen ze podnaam, namespace en node-labels als resource-attributen, dan werkt de pipeline. De k8sattributes-processor is de component die die verrijking doet; ontbreken labels, check dan of zijn ClusterRole toestemming heeft om pods te listen.
Veelvoorkomende valkuilen
De default collector-image is niet de k8s-distributie. De simpele otelcol-image mist k8sattributes, k8scluster, kubeletstats en filelog. Override manager.collectorImage.repository altijd naar de opentelemetry-collector-k8s-image bij het installeren van de Operator.
Twee Collectors die dubbele data produceren. Zie je elke cluster-scoped metric dubbel, dan draait de k8s_cluster-receiver in zowel de DaemonSet als de Deployment Collector. Verplaats 'em naar alleen de Deployment, en houd in de DaemonSet alleen node-lokale receivers.
Webhook-fouten na Operator-installatie. Mislukt OpenTelemetryCollector applyen met failed to call webhook: x509 certificate signed by unknown authority, dan heeft cert-manager het webhook-certificaat nog niet uitgegeven. Check kubectl get certificate -n opentelemetry -o wide en wacht tot Ready=True. De Operator installeren voordat cert-manager helemaal op is gekomen is de gangbare oorzaak.
Log-loops van de filelog-receiver. De DaemonSet Collector tailt /var/log/pods/*/*/*.log, en daar zitten de Collector's eigen logs tussen. Zonder de exclude-pattern in de filelog-config wordt elke Collector-logregel een logrecord die de Collector zelf weer verwerkt en exporteert, wat meer logregels oplevert. De opentelemetry-collector Helm-chart documentatie roept dit expliciet uit.
Auto-instrumentatie-annotatie op de Deployment-spec in plaats van op de pod-template. De injector kijkt naar pod-metadata, niet naar Deployment-metadata. Zet de annotatie onder spec.template.metadata.annotations, niet onder de metadata.annotations van de Deployment zelf.
otlp en otlphttp door elkaar halen. Dat zijn verschillende exporters met verschillende config-vormen. otlp is gRPC; otlphttp is HTTP/protobuf. Een HTTP-endpoint in otlp zetten (of andersom) levert verwarrende connection-errors op.
Wat je hebt geleerd
Je hebt nu de OpenTelemetry Operator Collectors reconcileren op je cluster. Een DaemonSet Collector op elke node verzorgt node-lokale signalen en ontvangt OTLP van workloads op dezelfde node. Een Deployment Collector met een replica verzamelt cluster-scoped metrics en events, en stuurt alles door naar de backends die je kiest. Auto-instrumentatie injecteert een language-agent in pods via een enkele annotatie, zonder codewijzigingen. Traces, metrics en logs landen in Tempo, Prometheus en Loki met volledige Kubernetes-metadata.
Je weet ook waar de scherpe randjes zitten: de collector-image-override, de DaemonSet-vs-Deployment-splitsing als correctheidsvereiste in plaats van optimalisatie, de cert-manager-afhankelijkheid, en de log-loop-valkuil in de filelog-receiver.
Verder lezen
- Voeg PrometheusRule-alerts toe op de metrics die je nu verzamelt. De Prometheus-tutorial behandelt rule-writing en Alertmanager-routing.
- Rechtvaardigt je log-volume het, houd dan Fluent Bit voor stdout-logs en gebruik OpenTelemetry alleen voor traces en metrics. De Fluent Bit-tutorial loopt die setup door.
- Hard de Operator-TLS uit met een echte cert-manager ClusterIssuer in plaats van de self-signed default; de cert-manager-tutorial bevat dat patroon.