Prometheus'u kurup ilk sorgunu çalıştırdıysan muhtemelen şu tuhaf durumla karşılaşmışsındır: elinde metrik var ama hiçbiri sunucunla ilgili değil. up, prometheus_tsdb_head_samples_appended_total gibi şeyler dönüyor, çünkü Prometheus varsayılan olarak yalnızca kendini izler. Sunucunun CPU'sunu, boş belleğini, disk doluluğunu ya da ağ trafiğini görmek istiyorsan araya bir aracı koyman gerekir; bu aracının adı Node Exporter. Node Exporter kurulumu tek bir binary indirip bir systemd servisi yazmaktan ibarettir ama doğru yapılandırılmadığında ya yarım metrik toplar ya da 9100 portunu tüm internete açarak sunucunun iç yapısını hediye eder.
Bu rehberde Node Exporter'ın çekirdekten neyi okuduğunu, ikili dosyayla ve Docker ile nasıl kurulacağını, Prometheus'a hedef olarak nasıl ekleneceğini, günlük hayatta gerçekten işine yarayacak PromQL ifadelerini, collector'ları açıp kapatmanın ne anlama geldiğini ve kendi özel metriklerini textfile collector ile nasıl ekleyeceğini anlatacağım. Sonunda da ilk kurulumda neredeyse herkesin düştüğü tuzakları toplayacağım.
Node Exporter Tam Olarak Ne Yapar#
Node Exporter, Linux çekirdeğinin /proc ve /sys sanal dosya sistemlerinde zaten yayımladığı sayaçları okuyup Prometheus'un anlayacağı metin biçimine çeviren küçük bir HTTP sunucusudur. Yeni bir veri üretmez, mevcut veriyi tercüme eder. cat /proc/stat çıktısındaki CPU tick sayaçları node_cpu_seconds_total olur, /proc/meminfo içindeki MemAvailable satırı node_memory_MemAvailable_bytes olur, statfs() çağrısından dönen blok bilgisi node_filesystem_avail_bytes olur. Yani Node Exporter'ın yaptığı iş bir çeviri katmanıdır ve bu yüzden kaynak tüketimi son derece düşüktür; tipik bir sunucuda birkaç on megabayt bellek ve ihmal edilebilir CPU kullanır.
Yapmadığı şeyleri bilmek de en az bunun kadar önemli. Node Exporter veri saklamaz; sorgu geldiği anda anlık değerleri üretir, geçmişi tutan taraf Prometheus'tur. Uyarı üretmez; eşik değerlendirmesi Prometheus kural motorunda yapılır. Uygulama içi metrikleri de bilmez; onlar uygulamanın kendi /metrics uç noktasından gelir. Konteyner başına kaynak kullanımını göstermez — o iş için bkz. cAdvisor ile konteyner izleme. Alanı yalın ve nettir: işletim sistemi ve donanım seviyesi.
Çalışma prensibini görmek için kurduktan sonra tarayıcı yerine curl kullan; çıktı düz metindir ve okunabilir:
# Ham metrik çıktısını gör (binlerce satır döner, ilk 20'sine bak)
curl -s http://localhost:9100/metrics | head -20
# Sadece bellek metriklerini süz
curl -s http://localhost:9100/metrics | grep '^node_memory_MemAvailable'
# node_memory_MemAvailable_bytes 3.221225472e+09
İkili Dosya ile Kurulum ve systemd Servisi#
Paket depolarındaki prometheus-node-exporter paketi iş görür ama genelde birkaç sürüm geridedir. Resmi ikili dosya hem günceldir hem dağıtımdan bağımsız. Üretimde şu sırayla kurarım:
- İkili dosyayı indir, doğrula ve
/usr/local/binaltına koy. - Servisi çalıştırmak için oturum açamayan (nologin) ayrı bir sistem kullanıcısı oluştur.
- systemd unit dosyasını yaz ve sertleştirme direktiflerini ekle.
- Servisi etkinleştirip başlat,
curlile doğrula.
# 1) İndir ve yerleştir (sürüm numarasını resmi sayfadan güncel al)
cd /tmp
curl -LO https://github.com/prometheus/node_exporter/releases/latest/download/node_exporter-linux-amd64.tar.gz
tar xzf node_exporter-linux-amd64.tar.gz
sudo cp node_exporter-*/node_exporter /usr/local/bin/
sudo chmod 755 /usr/local/bin/node_exporter
# 2) Servis kullanıcısı — kabuk erişimi olmayan bir sistem hesabı
sudo useradd --system --no-create-home --shell /usr/sbin/nologin node_exporter
systemd unit dosyası /etc/systemd/system/node_exporter.service yoluna yazılır:
[Unit]
Description=Prometheus Node Exporter
After=network-online.target
Wants=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
# Sadece localhost'a bağlan; dışarı açmak için ters vekil ya da firewall kullan
ExecStart=/usr/local/bin/node_exporter \
--web.listen-address=127.0.0.1:9100 \
--collector.systemd \
--collector.textfile.directory=/var/lib/node_exporter/textfile
Restart=on-failure
RestartSec=5
# Sertleştirme: servis yalnızca okuma yapar, yazacak yeri yoktur
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Ardından servisi devreye al ve gerçekten cevap verdiğini doğrula:
sudo mkdir -p /var/lib/node_exporter/textfile
sudo chown node_exporter:node_exporter /var/lib/node_exporter/textfile
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
sudo systemctl status node_exporter --no-pager
# Metrik geliyor mu?
curl -s http://127.0.0.1:9100/metrics | wc -l
# Örnek çıktı: 1147
ProtectSystem=strict varken textfile dizinine yazacaksan ReadWritePaths=/var/lib/node_exporter/textfile satırını da ekle; aksi halde dizin salt okunur kalır. Zamanlanmış işlerle metrik üretme kısmına cron görevleri yazısı iyi bir tamamlayıcıdır.
Docker ile Node Exporter Çalıştırmak#
Sunucunda zaten Docker varsa exporter'ı konteyner olarak çalıştırmak cazip gelir, ama burada kritik bir ayrıntı var: konteyner kendi izole /proc ve /sys görünümünü görür, dolayısıyla varsayılan kurulumda host'un değil konteynerin metriklerini toplar. Doğru sonucu almak için host dosya sistemlerini salt okunur bağlamak ve --path.rootfs parametresini vermek zorundasın.
# docker-compose.yml
services:
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
restart: unless-stopped
# Host'un ağ ad alanını kullan ki ağ metrikleri gerçek arayüzleri göstersin
network_mode: host
pid: host
volumes:
- /:/host:ro,rslave
command:
- '--path.rootfs=/host'
- '--web.listen-address=127.0.0.1:9100'
# Konteyner katmanlarının sahte dosya sistemi olarak sayılmasını engelle
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc|var/lib/docker/.+)($$|/)'
Buradaki pid: host satırı süreç sayısı metriklerinin host'u yansıtması için gereklidir; rslave ise sonradan bağlanan disklerin konteyner içinde görünmesini sağlar, onsuz yeni takılan bir diskin doluluk metriği hiç oluşmaz. Compose yapısını tazelemek istersen Docker Compose kullanımı rehberi işine yarar.
Prometheus'a Hedef Olarak Eklemek#
Exporter çalışıyor olması tek başına bir şey ifade etmez; Prometheus'un onu düzenli olarak kazıması (scrape) gerekir. prometheus.yml dosyasına yeni bir job ekliyorsun:
scrape_configs:
- job_name: 'node'
scrape_interval: 15s
static_configs:
- targets:
- '10.0.0.11:9100'
- '10.0.0.12:9100'
labels:
env: 'production'
- targets:
- '10.0.0.51:9100'
labels:
env: 'staging'
Yapılandırmayı değiştirdikten sonra dosyayı doğrula ve Prometheus'a yeniden okut; süreci öldürmene gerek yok:
# Söz dizimi kontrolü
promtool check config /etc/prometheus/prometheus.yml
# Sıcak yeniden yükleme (--web.enable-lifecycle açıksa)
curl -X POST http://localhost:9090/-/reload
# Ya da klasik yöntem
sudo systemctl reload prometheus
Hedeflerin gerçekten toplanıp toplanmadığını Prometheus arayüzünde Status → Targets ekranından görürsün. Bir hedef DOWN görünüyorsa hata mesajı genelde tek satırda derdi anlatır: connection refused firewall ya da yanlış port, context deadline exceeded yavaş ya da ulaşılamayan sunucu demektir. Prometheus tarafındaki prometheus.yml yapısını ve saklama ayarlarını hiç kurcalamadıysan önce Prometheus kurulumu ve metrik toplama yazısına göz atman iyi olur.
Günlük Hayatta İşine Yarayacak Metrikler#
Node Exporter binden fazla metrik üretir ama pratikte sürekli baktığın liste kısadır. Aşağıdaki tablo, bir sunucunun sağlığını anlamak için yeterli olan çekirdek sorguları içeriyor:
| Ne öğrenmek istiyorsun | PromQL ifadesi | Notlar |
|---|---|---|
| CPU kullanım yüzdesi | 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) | idle dışını hesaplamak en güvenilir yöntem |
| Kullanılabilir bellek yüzdesi | node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 | MemFree değil, MemAvailable kullan |
| Kök disk doluluk yüzdesi | 100 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100) | tmpfs'i dışlamayı unutma |
| Disk dolma tahmini (4 saat) | predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[6h], 4*3600) < 0 | uyarı kuralı için ideal |
| Ağ giriş hızı (bit/sn) | rate(node_network_receive_bytes_total{device!~"lo|veth.*"}[5m]) * 8 | sanal arayüzleri dışla |
| Yük ortalaması / çekirdek | node_load5 / count by(instance)(node_cpu_seconds_total{mode="idle"}) | 1'in üstü doygunluk işareti |
| Sunucu ayakta kalma süresi | time() - node_boot_time_seconds | beklenmedik yeniden başlatmayı yakalar |
| Exporter erişilebilir mi | up{job="node"} == 0 | en temel uyarı budur |
İki ifadeyi özellikle vurgulamak isterim. Bellek: node_memory_MemFree_bytes üzerinden yüzde hesaplarsan sürekli "bellek bitti" alarmı alırsın, çünkü Linux boş belleği disk önbelleği olarak kullanır ve bu sağlıklı bir davranıştır; doğru gösterge MemAvailable'dır. Disk: eşik bazlı uyarı bir log patlamasında geç kalır, çünkü yüzde 70'ten yüzde 100'e yarım saatte gidilir. predict_linear sana o yarım saati kazandırır.
Collector'ları Açmak, Kapatmak ve Textfile ile Genişletmek#
Node Exporter her metrik ailesini ayrı bir collector modülünde toplar; yaklaşık kırk tanesi varsayılan olarak açık gelir. Elle açtığım ya da kapattığım collector'lar şunlar:
| Collector | Varsayılan | Ne verir / neden dokunulur |
|---|---|---|
systemd | Kapalı | Servis birimlerinin durumu; "nginx düştü" uyarısını mümkün kılar |
textfile | Açık (dizin boş) | Kendi yazdığın özel metrikler |
processes | Kapalı | Süreç sayısı ve durum dağılımı; fork bomb tespitine yarar |
mdadm | Açık | Yazılımsal RAID dizisi sağlığı |
nfs / nfsd | Açık | NFS istemci/sunucu sayaçları; kullanmıyorsan kapat |
arp | Açık | Büyük ağlarda binlerce satır üretir, gereksizse kapat |
hwmon | Açık | Sıcaklık ve fan sensörleri; sanal sunucuda anlamsızdır |
Parametreler --collector.ADI biçiminde açılır, --no-collector.ADI biçiminde kapatılır:
/usr/local/bin/node_exporter \
--collector.systemd \
--collector.processes \
--no-collector.arp \
--no-collector.hwmon \
--no-collector.nfs
Textfile collector ise en sevdiğim özelliktir: belirttiğin dizindeki .prom uzantılı düz metin dosyalarını okuyup metrik olarak yayımlar. Böylece Prometheus'un bilemeyeceği şeyleri — yedeğin ne zaman bittiği, sertifikanın kaç gün ömrü kaldığı — bir betikle üretebilirsin.
#!/usr/bin/env bash
# /usr/local/bin/backup-metric.sh — yedek bittikten sonra çalıştır
DIR=/var/lib/node_exporter/textfile
TMP=$(mktemp "$DIR/backup.prom.XXXXXX")
cat > "$TMP" <<EOF
# HELP backup_last_success_timestamp_seconds Son basarili yedegin zamani.
# TYPE backup_last_success_timestamp_seconds gauge
backup_last_success_timestamp_seconds $(date +%s)
EOF
# Atomik yer değiştirme: exporter yarım dosya okumasın
mv "$TMP" "$DIR/backup.prom"
chmod 644 "$DIR/backup.prom"
Buradaki mktemp + mv kalıbı zorunluluktur: dosyaya doğrudan yazarsan exporter tam o anda yarım satır okuyup o kazıma turunu atar. Docker uygulama yedekleme akışına böyle bir metrik eklemek, "yedek alındı sanıyorduk" durumunu ortadan kaldırır.
9100 Portu ve Güvenlik: En Sık Atlanan Adım#
Node Exporter kimlik doğrulaması olmadan çalışır ve varsayılan olarak 0.0.0.0:9100 adresine bağlanır. Hiçbir önlem almazsan sunucunun genel IP'sine gelen herkes çekirdek sürümünü, dosya sistemi bağlama noktalarını, ağ arayüzlerini ve systemd servis adlarını okuyabilir — saldırgan için mükemmel bir keşif kaynağı. Üç geçerli yaklaşım var:
- Yalnızca özel ağa bağla. Sunucuların arasında özel bir ağ varsa
--web.listen-address=10.0.0.11:9100ile sadece o arayüzü dinlet. - Firewall ile kaynak kısıtla. Portu açık tut ama yalnızca Prometheus sunucusunun IP'sinden gelen bağlantılara izin ver.
- TLS ve temel kimlik doğrulama ekle. Node Exporter'ın kendi
--web.config.filedesteği bunu yapar; internet üzerinden kazıma yapılacaksa şart.
# UFW ile: yalnızca Prometheus sunucusu (185.12.34.56) erişebilsin
sudo ufw allow from 185.12.34.56 to any port 9100 proto tcp
sudo ufw deny 9100/tcp
# firewalld kullanıyorsan zengin kural (rich rule) ile
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="185.12.34.56" port port="9100" protocol="tcp" accept'
sudo firewall-cmd --reload
İnternet üzerinden kazıma yapman gerekiyorsa --web.config.file ile bir web.yml gösterip tls_server_config ve basic_auth_users bloklarını doldurursun; parolayı elle uydurmak yerine şifre üretici aracımızla güçlü bir değer üretip bcrypt'e çevir. Exporter portları, dışa açık port listelerinin en çok unutulan kalemidir.
Sık Yapılan Hatalar ve Tuzaklar#
Konteynerdeki exporter'ın host'u ölçtüğünü sanmak. --path.rootfs vermezsen disk metriklerin konteynerin katman dosya sistemini gösterir, gerçek diskin dolduğunu göremezsin. node_filesystem_size_bytes{mountpoint="/"} değeri gerçek disk boyutunla uyuşmuyorsa bağlama yanlıştır.
Dosya sistemi metriklerini filtrelememek. Docker çalışan bir sunucuda her overlay katmanı ayrı dosya sistemi sayılır ve zaman serisi sayın patlar. --collector.filesystem.mount-points-exclude parametresini baştan ayarla.
rate() yerine ham sayaç kullanmak. node_cpu_seconds_total sürekli artan bir sayaçtır; grafiğe olduğu gibi koyarsan sonsuza giden düz bir çizgi görürsün. Anlamlı olan birim zamandaki artıştır.
instance etiketini IP olarak bırakmak. Sunucu yeniden kurulduğunda ya da IP değiştiğinde geçmiş veriyle bağ kopar. relabel_configs ile okunabilir bir isim ata; 10.0.0.11:9100 yerine web-01 görmek altı ay sonra çok fark eder.
Kazıma aralığını gereksiz kısaltmak. scrape_interval: 1s yazmak daha hassas izleme değildir; disk ve bellek kullanımını on beş katına çıkarır. Sunucu metrikleri için 15 saniye çoğu ekibe fazlasıyla yeter.
Exporter'ın kendisini izlememek. Node Exporter durursa metrikler durur ve gösterge panelin sessizce boşalır. Bunu felaket sanmak yerine tek satırlık up{job="node"} == 0 kuralıyla uyarıya bağla; sessizlik de bir sinyaldir.
Sıkça Sorulan Sorular#
Node Exporter sunucuya ne kadar yük bindirir#
Pratikte fark edilmeyecek kadar az. Tipik bir sunucuda 15-40 MB civarı bellek kullanır ve CPU tüketimi kazıma anları dışında sıfıra yakındır. Yük yaratan asıl şey collector sayısı ve dosya sistemi çokluğudur; yüzlerce overlay katmanı olan bir Docker host'unda filtreleme yapmazsan kazıma süresi uzar. Gereksiz collector'ları kapattığında en yoğun sunucuda bile görünmez bir maliyete iner.
Windows sunucular için Node Exporter kullanabilir miyim#
Hayır, Node Exporter yalnızca Linux ve BSD türevlerinde çalışır çünkü doğrudan /proc ve /sys okur. Windows için ayrı bir proje var: Windows Exporter (eski adıyla WMI Exporter). Metrik adları farklıdır (windows_cpu_time_total gibi) ama Prometheus'a ekleme şekli ve varsayılan portu birebir aynı mantıkla çalışır, yani aynı Prometheus sunucusuyla karma bir filoyu rahatça izleyebilirsin.
Metrikler geliyor ama Prometheus hedefi DOWN görünüyor, neden#
Neredeyse her zaman ağ katmanındadır. Exporter'ı 127.0.0.1:9100 adresine bağladıysan başka bir sunucudan erişilemez; ya özel ağ IP'sine bağla ya da Prometheus'u aynı makinede çalıştır. İkinci olasılık firewall'dur: curl http://SUNUCU_IP:9100/metrics komutunu Prometheus sunucusundan çalıştırıp gerçekten cevap gelip gelmediğini test et. connection refused bağlama adresini, zaman aşımı ise firewall kuralını işaret eder.
Node Exporter ücretsiz mi, lisansı ne#
Evet, Node Exporter Prometheus projesinin bir parçasıdır ve Apache 2.0 lisansıyla dağıtılır. Ticari kullanım dahil hiçbir kısıtı yoktur, kullanıcı ya da sunucu başına ücret ödemezsin. Aynı şey Prometheus'un kendisi ve resmi exporter'ların büyük çoğunluğu için de geçerlidir; maliyetin tamamı çalıştırdığın sunucu kaynaklarıdır.
Disk doluluk uyarısını hangi eşikte kurmalıyım#
Sabit bir yüzde yerine iki kuralı birlikte kullanmanı öneririm. Birincisi klasik eşik: kök dosya sisteminde yüzde 85'i geçince uyarı. İkincisi eğim tabanlı tahmin: predict_linear ile önümüzdeki dört saat içinde dolacağı öngörülüyorsa uyarı. Eşik tek başına yavaş büyümede iyi çalışır ama ani log patlamalarında geç kalır; tahmin ise ani büyümeyi yakalar. İkisini birlikte kurduğunda pratikte sürprizle karşılaşmazsın.
Kendi özel metriklerimi nasıl eklerim#
En pratik yol textfile collector'dır. --collector.textfile.directory ile bir dizin belirtirsin, oraya yazdığın .prom uzantılı düz metin dosyaları otomatik olarak metrik haline gelir. Bir cron ya da systemd timer ile çalışan kısa bir betik, yedek zamanı veya sertifika ömrü gibi değerleri bu dosyaya yazar. Tek kritik kural, dosyayı geçici bir isme yazıp mv ile yerine koymaktır; doğrudan yazarsan exporter yarım dosya okuyabilir.
Birden fazla sunucuyu tek tek yazmak yerine otomatik keşif yapabilir miyim#
Evet ve sunucu sayın onu geçtiğinde kesinlikle yapmalısın. Prometheus file_sd_configs ile bir JSON dosyasından hedef listesi okuyabilir; bu dosyayı Ansible ya da envanterinden üreten bir betikle güncellersin. Bulut ortamındaysan doğrudan sağlayıcı bazlı keşif modülleri, Kubernetes kullanıyorsan kubernetes_sd_configs işini görür. Böylece yeni sunucu açtığında prometheus.yml dosyasına elle satır eklemeyi unutma riski ortadan kalkar.
Kapanış#
Node Exporter, izleme yığınının en sessiz ama en vazgeçilmez parçasıdır: çekirdeğin zaten ürettiği sayaçları Prometheus'un okuyabileceği biçime çevirir, başka bir iddiası yoktur. Aklında kalması gereken dört alışkanlık şunlar: exporter'ı ayrı bir nologin kullanıcısıyla ve sertleştirilmiş bir systemd servisi olarak çalıştır, 9100 portunu asla internete açık bırakma, konteynerde çalıştırıyorsan --path.rootfs vermeyi unutma, ve bellek kullanımını MemFree değil MemAvailable üzerinden ölç. Bunların üstüne disk için eşik ve predict_linear uyarılarını birlikte kurarsan, sunucunla ilgili kötü sürprizlerin büyük bölümünü baştan elemiş olursun.
Bu metrikleri toplamak için tam root erişimine ihtiyacın var; paylaşımlı bir pakette exporter çalıştıramazsın. Kendi izleme yığınını kurmak istiyorsan VDS veya sanal sunucu paketlerimiz bunun için uygun bir başlangıç, kaynaklarını esnek büyütmek istersen bulut sunucu tarafına bakabilirsin. Kurulum ve bakım işini kendi üstüne almak istemiyorsan sunucu yönetimi hizmetimiz izleme yığınının kurulumunu ve uyarı kurallarının ayarlanmasını da kapsıyor.