LinuxXLVI · OpenTelemetryOTel collectors
OTel collectors and agents - the deployment model
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
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
Q1. What is the role of the OTel agent?
Q2. OTel agents and gateways are the same thing.
Q3. Which of the following are valid OTel Collector receivers? Select all that apply.
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.