Docker Swarm Monitoring: Prometheus & Grafana
Prometheus, birçok farklı sistemde performans ve durum izleme aracı olarak kullanılabilir ve konteyner ortamları da bunlardan biridir. Konteynerler, dağıtık ve dinamik bir yapıya sahip olduğundan, monitörleme ve izleme gereksinimleri değişebilir ve bu nedenle Prometheus’un özellikleri, konteyner ortamlarının izlenmesine uygun bir şekilde tasarlanmıştır.
Bu döküman da docker swarm ortamımızı nasıl prometheus kullanarak izleyebileceğimizden bahsedeceğim.
/etc/docker/daemon.json
Öncelikle bir editör ile yukarıdaki belirttiğimiz dosyayı açıyoruz. Ardından aşağıdaki parametreleri dosyamıza yazıyoruz. Eğer dosya mevcut değilse oluşturabiliriz. Bu işlemi tüm docker yüklü sunucularımızda yapıyoruz.
Böylelikle, docker daemon’unun kullanabileceği bir API adresini belirtiriz. Bu API, Docker daemon’unun istatistiklerini toplayan ve sunan bir API’dir. Bu API’yi kullanarak, Docker daemon’unun işlemci kullanımı, bellek kullanımı, ağ trafiği vb. gibi istatistikleri toplayabilirsiniz.
{
"metrics-addr" : "0.0.0.0:9323",
"experimental" : true
}
Bu örneğimizde 3 adet docker yüklü sunucumuz mevcut. Bunlardan 1 tanesi manager diğer 2 sunucu ise worker rolünde çalışmaktadır.
192.168.0.13 > Master
192.168.0.11 > Worker 1
192.168.0.12 > Worker 2
Ardından, Prometheus container’ın okuyacağı bir yapılandırma dosyası oluşturmalıyız.
/tmp/prometheus.yml
Yukarıdaki dosyayı bir editör yardımıyla oluşturuyoruz. Ardından aşağıdaki parametreleri bu dosyaya yazıyoruz.
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: 'codelab-monitor'
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first.rules"
# - "second.rules"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['192.168.0.13:9090']
- job_name: 'docker'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['192.168.0.13:9323','192.168.0.11:9323','192.168.0.12:9323']
Böylelikle prometheus uygulamamız, bu ayarlara göre çalışacak. Prometheus uygulamamızı ayağa kaldırmak için, aşağıdaki komutu manager node ‘da çalıştırıyoruz.
docker service create --replicas 1 --name my-prometheus \
--mount type=bind,source=/tmp/prometheus.yml,destination=/etc/prometheus/prometheus.yml \
--publish published=9090,target=9090,protocol=tcp \
prom/prometheus
Yukarıdaki komut bize 1 replika’ya sahip prometheus containerı oluşturacak.
http://nodeip:9090/targets/. adresinden prometheus’a bağlı olan tüm nodeları görebileceğiz.

Prometheus tarafında tüm işlemler tamamlandı. Sıra geldi buraya çektiğimiz metricleri görselleştirmeye. Bunun için grafana uygulamasını kullanacağız. Manager sunucu içerisinden aşağıdaki komutu çalıştırarak, bir grafana uygulaması deploy ediyoruz;
docker service create --name grafana --network monitoring --publish 3000:3000 \
grafana/grafana
http://nodeip:3000 adresinden grafana uygulamamıza web üzerinden bağlanabiliriz.
Default kullanıcı bilgileri; admin:admin ‘dir. Arayüze girdikten sonra, prometheus uygulamamızı source olarak eklememiz gerekiyor;


Test ettiğimizde data source ‘ın çalıştığını görüyoruz. Artık grafana üzerinden, docker swarm ortamımıza ait bilgileri sorgulayabiliriz;

Sorguları daha mantıklı ve anlaşılabilir hale getirmek için, network katmanında bir hareket olması adına “ping” paketi göndermek için “alpine” tabanlı bir linux container oluşturdum.

Sonuçlar yukarıdaki sekildedir. Böylelikle swarm ortamımızda gerçekleşen aksiyonları görüntüleyebiliriz.
Bonus — Node exporter
Ek olarak dilersek, nodelara node-exporter agentını kurarak, nodelar hakkında daha fazla bilgi edinebiliriz. Bunun için,
( Öncesinde 192.168.0.10 sunucunda node exporter servisi kurdum ve çalışır hale getirdim) Kurulum için kaynak;
/tmp/prometheus.yml
Yukarıdaki dosyanın en alt satırına aşağıdaki parametreleri ekliyoruz.
- job_name: 'node exporter'
static_configs:
- targets: ['192.168.0.10:9100']
Configin tamamı aşağıdaki gibi gözükmeli;
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: 'codelab-monitor'
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first.rules"
# - "second.rules"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['192.168.0.13:9090']
- job_name: 'docker'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['192.168.0.13:9323','192.168.0.11:9323','192.168.0.12:9323']
- job_name: 'node exporter'
static_configs:
- targets: ['192.168.0.10:9100']
Aşağıdaki komut ile servisimizi update ediyoruz;
docker service update --force my-prometheus --mount-add type=bind,source=/tmp/prometheus.yml,destination=/etc/prometheus/prometheus.yml
Prometheus arayüzünü kontrol ediyoruz;

Gördüğünüz gibi “node exporter” target up durumda gözüküyor. Şimdi ise, node exporter agentını kullanarak grafana üzerinde örnek bir sorgu çalıştıralım;

Yukarıdaki sorguda da test ettiğimiz üzere cevap dönüyor.
Kaynak: