Jaeger 2
Overview
Jaeger is the CNCF graduated distributed tracing platform. You instrument your services, ship spans over OTLP or Jaeger native protocols, and search and visualise the resulting trace graph in the browser.
Jaeger 2 is a major rebuild on the OpenTelemetry Collector codebase. It is a single Go binary named jaeger with an OTel-Collector-style YAML config and embedded Badger storage out of the box. One process runs every receiver, processor and exporter, together with the Web UI.
This SecureAnyCloud image installs Jaeger 2.17.0 from the official GitHub release and runs it as the dedicated jaeger system user. Trace data persists to /var/lib/jaeger/badger. nginx wraps the Web UI and the admin health endpoint in HTTP basic-auth on port 80, so the UI is never exposed without credentials. The trace ingest ports stay direct, because instrumented applications speak OTLP and Jaeger protocols, not HTTP basic-auth.
What you get:
- Jaeger 2.17.0 (Apache 2.0) from the official GitHub release tarball at
/opt/jaeger-2.17.0, with a/opt/jaegersymlink - SHA256-verified binary install, with the checksum compared against the upstream
sha256sum.txt - A dedicated
jaegersystem user, with the data directory at/var/lib/jaeger/badger(jaeger:jaeger 0750) - OTel-Collector-style YAML config at
/etc/jaeger/config.yaml - Embedded Badger key-value storage with a 48h TTL for live traces and a 720h TTL for the archive
- All receivers enabled: OTLP gRPC
:4317, OTLP HTTP:4318, Jaeger gRPC:14250, Jaeger Thrift HTTP:14268and Jaeger Thrift compact UDP:6831 - Web UI on
:16686and admin healthcheckv2 on:14269 - nginx 1.24 reverse proxy with HTTP basic-auth in front of the UI and admin endpoint on port 80
- A per-VM SecureAnyCloud user password, rotated at first boot with openssl rand -hex 12
- A per-VM credentials log at
/var/lib/sac/secrets/sac-credentials.txt(root:root 0600) - Three systemd units:
jaeger.service,jaeger-2-firstboot.serviceandnginx.service - 24/7 SecureAnyCloud support
For production scale-out, replace the Badger backend of the jaeger_storage extension with OpenSearch, Elasticsearch or Cassandra. Edit /etc/jaeger/config.yaml and restart jaeger.service.
Prerequisites
You need an active Azure subscription, an SSH key, and a VNet with a subnet. Standard_B2s (4 GB RAM) is a comfortable size for a single-node Jaeger handling tens of thousands of spans per minute.
Configure these NSG inbound rules:
22/tcpfrom your management CIDR, for SSH80/tcpfrom any client CIDR that needs the Jaeger Web UI. nginx fronts the UI with HTTP basic-auth, so the UI is never exposed without credentials4317/tcpand4318/tcpfrom your application subnet, for OTLP gRPC and HTTP trace ingest from instrumented apps14250/tcp,14268/tcpand6831/udp, for Jaeger native trace ingest. Open these only if you have apps that use the older Jaeger client libraries
Never expose 16686/tcp or 14269/tcp directly. They are the upstream UI and admin endpoints, and they have no authentication. The image runs them on 0.0.0.0 so nginx can proxy them locally. In production, bind them to loopback if you need stronger isolation.
Step 1-3 - Deploy and connect over SSH
Deploy the image from the Azure Marketplace or the Azure CLI, then connect to the VM over SSH as azureuser:
ssh azureuser@<vm-ip>Check service status and versions
sudo systemctl is-active jaeger nginx
sudo test -f /var/lib/sac/data/jaeger-2-firstboot.done && echo "firstboot: complete" || echo "firstboot: missing" /opt/jaeger/jaeger --version 2>&1 | head -1Both jaeger and nginx report active. The first-boot oneshot generates the per-VM nginx htpasswd password and the credentials log. It then writes a sentinel file and exits cleanly. The Jaeger binary reports its git version as v2.17.0.
Read the per-VM credentials
sudo cat /var/lib/sac/secrets/sac-credentials.txtNote JAEGER_PASSWORD, the SecureAnyCloud user's password. You enter it at the nginx HTTP basic-auth prompt when you browse to the Web UI.
The file also lists the trace-ingest endpoints: OTLP_GRPC, OTLP_HTTP, JAEGER_GRPC, JAEGER_THRIFT_HTTP and JAEGER_THRIFT_UDP. JAEGER_URL is the canonical browser entry point, and JAEGER_ADMIN_HEALTH_URL points at the healthcheckv2 endpoint behind basic-auth. The file is root:root 0600.
Run the admin health check
curl -s http://127.0.0.1:14269/status | head -c 400
PASS=$(sudo grep '^JAEGER_PASSWORD=' /var/lib/sac/secrets/sac-credentials.txt | cut -d= -f2-)
curl -s -u sac:$PASS http://127.0.0.1/admin/status | head -c 400The first request calls Jaeger's healthcheckv2 extension directly on the loopback admin port. It returns a JSON status document confirming that all components are healthy.
The second request goes through nginx with HTTP basic-auth and returns the same document. This confirms that the full reverse-proxy chain is wired correctly.
Send a trace over OTLP HTTP
curl -sf -X POST -H 'Content-Type: application/json' \
--data '{"resourceSpans":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"hello-sac"}}]},"scopeSpans":[{"scope":{"name":"manual"},"spans":[{"traceId":"5b8aa5a2d2c872e8321cf37308d69df2","spanId":"051581bf3cb55c13","name":"manual-span","startTimeUnixNano":"1746000000000000000","endTimeUnixNano":"1746000001000000000","kind":1}]}]}]}' \
http://127.0.0.1:4318/v1/traces && echo "trace ingested"This command sends a minimal valid OTLP JSON trace with service.name=hello-sac to the OTLP HTTP receiver. The receiver routes it through the batch processor and writes it to the Badger backend via the jaeger_storage_exporter. The trace is now searchable in the Web UI.
Open the Jaeger Web UI
Browse to http://<vm-ip>/ and authenticate as SecureAnyCloud with <JAEGER_PASSWORD> at the nginx HTTP basic-auth prompt.
The Search page opens by default. Pick a service from the dropdown and click Find Traces. The trace you posted in Step 7 appears in the results.
View the system architecture
Open the Search menu and choose System Architecture. Jaeger renders a force-directed graph of every service that has emitted spans. Edges show the parent-child call relationships derived from the trace context.
With a single hello-sac trace ingested, the graph shows one node. In production, with thousands of spans per minute, it shows your full service mesh.
Inspect a trace
Click a trace in the Search results to open the trace detail view. It shows a Gantt-style flame graph of every span in the trace, with timing data, tags, logs and process info.
Use this view to debug latency bottlenecks. Hover over the longest span to see its duration, then expand its tags to see HTTP status codes, database queries and custom attributes.
Component reference
Component and path:
jaeger binary /opt/jaeger/jaeger (symlink to /opt/jaeger-2.17.0/jaeger)
Config /etc/jaeger/config.yaml
Badger storage /var/lib/jaeger/badger/ (live), /var/lib/jaeger/badger-archive/ (archive)
systemd unit /etc/systemd/system/jaeger.service
Firstboot script /usr/local/sbin/jaeger-2-firstboot.sh
Firstboot service /etc/systemd/system/jaeger-2-firstboot.service
nginx site config /etc/nginx/sites-enabled/jaeger-sac
nginx htpasswd /etc/nginx/.htpasswd-jaeger (root:www-data 0640)
Credentials /var/lib/sac/secrets/sac-credentials.txt (root:root 0600)
Logs journalctl -u jaeger, /var/log/sac/sac-firstboot.log
Production hardening
- Switch Badger to OpenSearch, Elasticsearch or Cassandra. Edit
/etc/jaeger/config.yaml, replace thejaeger_storageBadger backend with the appropriate config block, and restartjaeger.service. Badger is single-node only. - Restrict the NSG. Keep
80/tcpopen only to your CDN, load balancer or VPN CIDR, and lock22/tcpto your management CIDR. - Add TLS. Terminate TLS at nginx by adding a
listen 443 ssl;block with your real certificate, and usereturn 301 https://$host$request_uri;on:80. - Sample traces. If your application throughput is high, edit
/etc/jaeger/config.yamlto add a probabilistic sampler underprocessors:, for example 1% sampling in production. - Monitor Jaeger metrics. The config exposes Prometheus metrics on
:8888. Scrape them from your Prometheus install to watch receiver throughput, exporter latency and dropped spans. - Patch monthly. Run
apt-get update && apt-get upgrade && reboot, and subscribe to https://github.com/jaegertracing/jaeger/releases for Jaeger releases.
Licensing
Jaeger is licensed under Apache 2.0 and is free to use commercially. SecureAnyCloud provides commercial support separately. Contact sales@secureanycloud.com.
Deploy on Azure
Launch Jaeger 2.17.0 Distributed Tracing on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com