Mendeploy OpenTelemetry di Kubernetes: install collector via Helm chart, memilih mode daemonset (agent) vs deployment (gateway), enrichment atribut K8s dengan k8sattributes processor, dan auto-instrumentasi otomatis memakai OpenTelemetry Operator

Semakin banyak tim mendeploy aplikasi di Kubernetes — dan di situlah observability paling dibutuhkan sekaligus paling sulit. Pod datang dan pergi, nama berubah tiap deploy, dan attribut seperti k8s.pod.name tidak pernah stabil. Episode 18 menjawab pertanyaan deployment: bagaimana menjalankan collector di K8s dengan benar, dan bagaimana memberi atribut K8s pada setiap telemetry.
Mengapa penting? Di K8s, observability tanpa atribut Kubernetes hampir tidak berguna — kalian tidak bisa membedakan pod yang sama namanya dari deploy yang berbeda. Dan deployment collector yang salah (misal gateway dipasang sebagai daemonset) adalah kesalahan arsitektur yang mahal.
Cara resmi menginstall collector di K8s adalah Helm chart open-telemetry/opentelemetry-collector:
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
helm install otel-agent open-telemetry/opentelemetry-collector \
--namespace observability --create-namespace \
--set mode=daemonset \
--set image.repository=otel/opentelemetry-collector-contrib \
--set image.tag=0.156.0 \
--set config.exporters.otlp.endpoint=otel-gateway.observability:4317 \
--set config.exporters.otlp.tls.insecure=true \
--set config.service.pipelines.traces.exporters[0]=otlp \
--set config.service.pipelines.metrics.exporters[0]=otlp \
--set config.service.pipelines.logs.exporters[0]=otlpParameter paling penting: mode — daemonset untuk agent per-node, deployment untuk gateway terpusat.
Satu collector per node — persis pola agent episode 9. Ia membaca log pod setempat (filelog), mengumpulkan metrics node (hostmetrics), dan menerima OTLP dari aplikasi di node yang sama.
Satu atau beberapa collector terpusat (biasanya dengan HPA) — menerima dari semua agent, melakukan tail sampling, routing, dan ekspor ke backend.
| Aspek | DaemonSet (agent) | Deployment (gateway) |
|---|---|---|
| Lokasi | Per node | Terpusat |
| Tugas | Batch, redaksi awal, log node | Sampling, routing, ekspor |
| Resource per instance | Kecil | Bisa besar (HPA) |
| Tail sampling | Tidak cocok | Ya |
Note
Sebagian tim mencoba menghemat dengan memakai satu Deployment saja (tanpa agent). Untuk cluster kecil itu wajar — tetapi begitu cluster bertumbuh, filelog dan hostmetrics yang butuh akses lokal node akan memaksa kalian kembali ke daemonset. Mulailah dengan pola dua tingkat sejak awal bila scale sudah jelas.
Atribut K8s tidak otomatis menempel — collector perlu menghubungkan ip:port sumber telemetry dengan metadata pod. Processor k8sattributes melakukan itu:
processors:
k8sattributes:
auth_type: serviceAccount
passthrough: false
extract:
metadata:
- k8s.namespace.name
- k8s.pod.name
- k8s.node.name
- k8s.deployment.name
pod_association:
- sources:
- from: resource_attribute
name: k8s.pod.ip
- sources:
- from: connectionauth_type: serviceAccount — collector memakai ServiceAccount dengan RBAC untuk membaca API K8s.extract.metadata — atribut apa yang diambil.pod_association — bagaimana mencocokkan telemetry dengan pod (via IP resource attribute atau koneksi masuk).Tambahkan ke pipeline traces dan logs. Hasilnya: setiap span/log tahu namespace, pod, dan deployment-nya — syarat pemfilteran dan grouping di dashboard K8s.
OpenTelemetry Operator adalah K8s operator yang mengelola collector (sebagai CustomResource OpenTelemetryCollector) dan melakukan auto-instrumentasi otomatis lewat injection:
Instrumentation yang menentukan image agent per bahasa.instrumentation.opentelemetry.io/inject-python: "true" — operator menyuntikkan init-container + env var secara otomatis.helm install otel-operator open-telemetry/opentelemetry-operator \
--namespace observability \
--set manager.collectorImage.repository=otel/opentelemetry-collector-contrib \
--set manager.collectorImage.tag=0.156.0apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: py-instrumentation
namespace: observability
spec:
exporter:
endpoint: http://otel-agent.observability:4317
propagators:
- tracecontext
- baggage
python:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-python:0.49b0Kemudian anotasi satu pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: catalog
spec:
template:
metadata:
annotations:
instrumentation.opentelemetry.io/inject-python: "observability/py-instrumentation"Saat pod dibuat, operator menyuntikkan init-container yang mengunduh agent + env var OTEL_* — aplikasi ter-instrumentasi tanpa mengubah Docker image atau kode sama sekali.
Tip
Anotasi inject bisa diset default per-namespace dengan menganotasi namespace itu sendiri (instrumentation.opentelemetry.io/inject-python: "true"), sehingga semua deployment baru di namespace tersebut otomatis ter-instrumentasi. Sangat efisien untuk adopsi bertahap.
--set mode=deployment --set autoscaling.enabled=true.pods, namespaces); Helm chart menyediakan aturan default.k8sattributes — telemetry tidak tahu nama deployment; dashboard K8s pecah.pod_association salah — collector tidak bisa mencocokkan telemetry dengan pod; pastikan IP diteruskan.Pada episode 18 ini, kalian telah mendeploy OTel di Kubernetes.
Inti yang harus dibawa pulang:
open-telemetry/opentelemetry-collector; pilih mode: daemonset untuk agent dan mode: deployment untuk gateway.k8sattributes processor menghubungkan telemetry dengan metadata pod — wajib untuk dashboard K8s.Di episode 19 selanjutnya, kita akan membahas tuning & performance optimization — mengatur memory/CPU collector, tuning memory_limiter, concurrency, kontrol cardinality metrics, load test pipeline, dan profiling collector dengan pprof. Sampai jumpa di episode 19!