Skip to main content
RunBook Academy

LinuxXLVI · OpenTelemetryOTel collectors

OTel collectors and agents - the deployment model

Intermediate⏱ ~10 minotel-collector

What you'll learn

  • Deploy OTel agents and gateways
  • Use the agent/gateway pattern
  • Configure OTLP receivers
  • Bridge an existing rsyslog and node_exporter estate into an OTel pipeline
  • Ship to multiple backends

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

OTel has two deployment modes: agents (per host) and gateways (central). This lesson covers both, and the common agent/gateway pattern.

Agent / Gateway pattern

Hosts                                       Gateway
+--------+                                +----------+
| App    |---OTLP (gRPC or HTTP)--------->| OTel      |---Prometheus
| OTel   |                                | Gateway   |---Loki (OTLP)
| agent  |                                |          |---Tempo (OTLP)
+--------+                                +----------+
+--------+
| App    |---OTLP
| OTel   |
| agent  |
+--------+
  • Agent (per host): receives OTLP from applications, batches, ships to gateway. Reduces network calls and adds local buffering.
  • Gateway (central): receives from many agents, processes, exports to backends. Centralised configuration and routing.

OTel agent

The agent runs on every host:

# /etc/otel-collector/agent.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

# `storage: file_storage` below refers to this extension by name. Declare it
# AND list it under service.extensions, or the collector refuses to start with
# "extension \"file_storage\" is not configured".
extensions:
  file_storage:
    directory: /var/lib/otelcol/sending_queue

processors:
  batch:
    timeout: 5s
    send_batch_size: 1000

exporters:
  otlp:
    endpoint: gateway:4317
    tls:
      insecure: false
      # ca_file is what verifies the GATEWAY's certificate. Without it the
      # collector falls back to the system trust store, which does not
      # contain your internal CA - so every export fails with
      # "x509: certificate signed by unknown authority", and mTLS with a
      # public CA in the store would verify the wrong peer.
      ca_file: /etc/ssl/internal-ca.pem
      cert_file: /etc/ssl/agent.pem      # this agent's client certificate
      key_file: /etc/ssl/agent.key
    # Telemetry is not worth losing during the incident you need it for.
    retry_on_failure:
      enabled: true
      max_elapsed_time: 0                # 0 = retry indefinitely
    sending_queue:
      enabled: true
      storage: file_storage              # survives a collector restart

service:
  extensions: [file_storage]
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp]
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp]
    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp]

The agent:

  • Receives OTLP from local applications.
  • Batches for efficiency.
  • Ships to the central gateway.

OTel gateway

The gateway runs centrally:

# /etc/otel-collector/gateway.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317

processors:
  batch:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 80
    spike_limit_percentage: 20

exporters:
  prometheus:
    endpoint: 0.0.0.0:8889
  otlphttp/loki:
    logs_endpoint: http://loki:3100/otlp/v1/logs
  otlp/tempo:
    endpoint: tempo:4317
    tls:
      insecure: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/tempo]
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [prometheus]
    logs:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlphttp/loki]

The gateway:

  • Receives from agents.
  • Limits memory.
  • Routes to backends per pillar.

Host receiver

The host receiver scrapes host metrics (like node_exporter):

receivers:
  hostmetrics:
    collection_interval: 30s
    scrapers:
      cpu:
      memory:
      disk:
      network:
      filesystem:
      load:
      processes:

exporters:
  prometheus:
    endpoint: 0.0.0.0:8889

service:
  pipelines:
    metrics:
      receivers: [hostmetrics]
      exporters: [prometheus]

The receiver key is hostmetrics: and its only settings are collection_interval and scrapers. There is no type: key inside a receiver - the map key is the type. Adding one is an unknown-field error and the collector will not start.

This gives the same host metrics as node_exporter, in OTLP format, so it can replace node_exporter on a fleet already running the agent.

Bridging what you already run

Most estates do not start from zero. They already forward syslog and already scrape node_exporter. The Collector is built to terminate both, so adoption is additive rather than a migration.

receivers:
  # Terminate the rsyslog forwarding you already have.
  # Point rsyslog omfwd at this port; applications change nothing.
  syslog:
    tcp:
      listen_address: 0.0.0.0:5514
    protocol: rfc5424

  # Scrape the node_exporter fleet you already have.
  # This takes Prometheus scrape_config verbatim.
  prometheus:
    config:
      scrape_configs:
        - job_name: node
          scrape_interval: 30s
          static_configs:
            - targets: ['10.0.0.11:9100', '10.0.0.12:9100']

service:
  pipelines:
    logs:
      receivers: [otlp, syslog]
      processors: [batch]
      exporters: [otlp]
    metrics:
      receivers: [otlp, hostmetrics, prometheus]
      processors: [batch]
      exporters: [otlp]

Deployment patterns

  • Sidecar (Kubernetes pod): one OTel agent per pod.
  • DaemonSet (Kubernetes): one agent per node.
  • Host agent (VM/bare-metal): one agent per host.
  • Gateway (central): one or more per region/datacenter.

For most production, daemon-set on K8s or host agent on VMs, with one or more gateways per region.

Knowledge check

Knowledge check · 4 questions

  1. Q1. What is the role of the OTel agent?

  2. Q2. OTel agents and gateways are the same thing.

  3. Q3. Which of the following are valid OTel Collector receivers? Select all that apply.

  4. Q4. Your estate already forwards logs with rsyslog and scrapes metrics with node_exporter. You are asked to adopt OTel without a rip-and-replace. What does the Collector give you?

Passing score: 75%. Answers are checked in this browser.