cAdvisor collects container-level metrics (CPU, memory, network per container).
Deploy it in global mode so it runs on all nodes automatically.
Execute the below on the Manager Node:
docker service create \
--name cadvisor \
--mode global \
--network monitoring \
--mount type=bind,source=/,target=/rootfs,readonly \
--mount type=bind,source=/var/run,target=/var/run \
--mount type=bind,source=/sys,target=/sys,readonly \
--mount type=bind,source=/var/lib/docker/,target=/var/lib/docker,readonly \
--constraint 'node.platform.os == linux' \
--cap-add SYS_ADMIN \
gcr.io/cadvisor/cadvisor:latest
Verify:
docker service ls
Should show:
cadvisor global 2/2
STEP 4 — Deploy Docker Swarm Exporter
Docker Swarm Exporter collects Swarm-level metrics (services, tasks, nodes, replicas).
It must run on a Manager Node as it needs access to the Docker socket.
Execute the below on the Manager Node:
docker service create \
--name docker-swarm-exporter \
--network monitoring \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock,readonly \
--constraint 'node.role == manager' \
--publish 9000:9000 \
nicholasjackson/swarm-exporter:latest
Verify:
docker service ls
Should show:
docker-swarm-exporter replicated 1/1
Verify metrics endpoint:
> Note: Look for metrics like `swarm_services_running`, `swarm_nodes_total` in the output.
STEP 5 — Enable Docker Engine Metrics (On ALL Nodes)
Perform the following steps on every node (Manager + Workers):
Edit Docker daemon config:
sudo vi /etc/docker/daemon.json
Add the following:
{
"metrics-addr": "127.0.0.1:9323",
"experimental": true
}
> Note: Use `"metrics-addr": "0.0.0.0:9323"` only if you need to access metrics
> from a remote host. For security, restrict to internal IP in production.
Restart Docker:
sudo systemctl restart docker
Verify the metrics endpoint:
> Verify: Look for `engine_daemon_engine_info` in the output to confirm it is working.
STEP 6 — Create Prometheus Configuration
On the Manager Node:
mkdir -p ~/prometheus
cd ~/prometheus
vi prometheus.yml
add the below configuration:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'dockerswarm'
dns_sd_configs:
- names:
- 'tasks.cadvisor'
type: 'A'
port: 8080
- names:
- 'tasks.node-exporter'
type: 'A'
port: 9100
- names:
- 'tasks.docker-swarm-exporter'
type: 'A'
port: 9000
static_configs:
- targets:
- '<manager-ip>:9323' # Replace with actual Manager Node IP
- '<worker-ip>:9323' # Replace with actual Worker Node IP
labels:
exporter: docker-engine
relabel_configs:
# Tag each target by exporter type
- source_labels: [__address__]
regex: '.*:8080'
target_label: exporter
replacement: cadvisor
- source_labels: [__address__]
regex: '.*:9100'
target_label: exporter
replacement: node-exporter
- source_labels: [__address__]
regex: '.*:9000'
target_label: exporter
replacement: docker-swarm-exporter
# Force instance = "crc" for ALL targets
- source_labels: [__address__]
regex: '.+'
target_label: instance
replacement: 'crc'
metric_relabel_configs:
# Ensure instance stays "crc" after scrape
- target_label: instance
replacement: 'crc'
> Note: Replace `<manager-ip>` and `<worker-ip>` with your actual node IPs.
STEP 7 — Deploy Prometheus
Execute the below on the Manager Node:
docker service create \
--name prometheus \
--network monitoring \
--publish 9090:9090 \
--constraint 'node.role == manager' \
--mount type=bind,source=$HOME/prometheus/prometheus.yml,target=/etc/prometheus/prometheus.yml \
prom/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--web.enable-lifecycle
Verify:
docker service ls
Should show:
Example Numbers:
prometheus replicated 1/1
cadvisor global n/n
node-exporter global n/n
docker-swarm-exporter replicated 1/1
STEP 8 — Verify in Browser
Open: `http://<manager-ip>:9090`
Go to: Status → Targets
You should see all targets as UP:
cadvisor n/n UP
node-exporter n/n UP
docker-swarm-exporter n/n UP
docker-engine n/n UP
All targets will carry the unified labels:
instance="crc" job="dockerswarm" exporter="<exporter-type>"