apiVersion: v1 kind: Service metadata: { name: otel-collector, namespace: observability } spec: selector: { app: otel-collector } ports: - { name: otlp-http, port: 4318, targetPort: 4318 } - { name: otlp-grpc, port: 4317, targetPort: 4317 } --- apiVersion: apps/v1 kind: Deployment metadata: { name: otel-collector, namespace: observability } spec: replicas: 2 selector: { matchLabels: { app: otel-collector } } template: metadata: { labels: { app: otel-collector } } spec: nodeSelector: { node: hetzner-2 } containers: - name: otel-collector image: otel/opentelemetry-collector-contrib:0.102.0 args: ["--config=/etc/otel/config.yaml"] ports: - { containerPort: 4318 } - { containerPort: 4317 } volumeMounts: - { name: cfg, mountPath: /etc/otel } volumes: - { name: cfg, configMap: { name: otel-config } } --- apiVersion: v1 kind: ConfigMap metadata: { name: otel-config, namespace: observability } data: config.yaml: | receivers: otlp: protocols: { http: {}, grpc: {} } processors: { batch: {} } exporters: logging: {} elasticsearch: endpoints: ["http://elasticsearch.elastic.svc.cluster.local:9200"] logs_index: "k8s-logs" service: pipelines: logs: { receivers: [otlp], processors: [batch], exporters: [elasticsearch, logging] } traces: { receivers: [otlp], processors: [batch], exporters: [logging] } metrics: { receivers: [otlp], processors: [batch], exporters: [logging] } --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: otlp namespace: observability annotations: { cert-manager.io/cluster-issuer: letsencrypt-prod } spec: ingressClassName: nginx tls: [{ hosts: ["otlp.betelgeusebytes.io"], secretName: otlp-tls }] rules: - host: otlp.betelgeusebytes.io http: paths: - path: /v1/traces pathType: Prefix backend: { service: { name: otel-collector, port: { number: 4318 } } } - path: /v1/metrics pathType: Prefix backend: { service: { name: otel-collector, port: { number: 4318 } } } - path: /v1/logs pathType: Prefix backend: { service: { name: otel-collector, port: { number: 4318 } } }