Sunucun gece 03:00'te yavaşladı, sabah baktığında her şey normal. Log dosyalarında bir ipucu yok, top çıktısı sana o anı göstermiyor ve elinde tek kanıt bir müşterinin "site açılmıyordu" mesajı. Bu döngüden çıkmanın tek yolu, olayları yaşandığı anda ölçüp saklamaktır — ve açık kaynak dünyasında bunun fiilî standardı Prometheus'tur. Prometheus kurulumu göründüğünden basittir: tek bir binary, tek bir yapılandırma dosyası ve kendi içinde bir zaman serisi veritabanı.
Bu rehberde Prometheus'un çekme (pull) modelini nasıl işlettiğini, ikili dosyayla ve Docker Compose ile nasıl kurulacağını, prometheus.yml içindeki her bloğun ne işe yaradığını, ilk PromQL sorgularını nasıl yazacağını, diskin nasıl planlanacağını ve bu servisi internete açmanın neden ciddi bir hata olduğunu anlatacağım. Sonunda da ilk kurulumda herkesin düştüğü tuzakları toplayacağım.
Prometheus Nasıl Çalışır: Çekme Modeli#
Çoğu klasik izleme sisteminin aksine Prometheus, ajanların ona veri göndermesini beklemez; hedeflere kendisi gider ve HTTP üzerinden metrikleri çeker. Her hedef, /metrics adresinde düz metin bir çıktı sunar. Prometheus bu çıktıyı belirlediğin aralıkla indirir, ayrıştırır ve kendi disk üzerindeki zaman serisi veritabanına yazar. Bu tasarımın en büyük getirisi, izlenen tarafın hiçbir şey bilmek zorunda olmamasıdır: uygulaman sadece bir sayfa yayınlar, gerisi Prometheus'un işidir.
Metrik satırı şu biçimdedir: metrik adı, süslü parantez içinde etiketler ve bir sayısal değer. Etiketler (label) Prometheus'un kalbidir; aynı metriği farklı boyutlarda kesip biçmeni sağlar.
# Bir /metrics çıktısından örnek satırlar
# HELP http_requests_total Toplam HTTP istek sayısı
# TYPE http_requests_total counter
http_requests_total{method="GET",status="200",handler="/anasayfa"} 48291
http_requests_total{method="GET",status="500",handler="/anasayfa"} 17
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 78643200
Dört metrik tipi vardır ve karıştırmak yanlış grafiklere yol açar: counter sadece artar (istek sayısı, hata sayısı), gauge artıp azalabilir (bellek kullanımı, sıcaklık), histogram değerleri kovalara dağıtır (yanıt süresi dağılımı), summary ise istemci tarafında hesaplanmış yüzdelikler döner. Pratikte en çok counter ve gauge kullanırsın; counter'ları asla doğrudan çizdirmezsin, rate() ile saniyedeki değişimine bakarsın.
Kurulum: İkili Dosya ve systemd Servisi#
Prometheus tek bir statik ikili dosya olarak dağıtılır, bağımlılığı yoktur. Üretimde kendi kullanıcısıyla ve systemd altında çalıştırmak en temiz yöntemdir:
# Ayrı bir sistem kullanıcısı aç (giriş yapamayan)
sudo useradd --system --no-create-home --shell /usr/sbin/nologin prometheus
# Dizinleri hazırla
sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo chown prometheus:prometheus /var/lib/prometheus
# İndirilen arşivi açtıktan sonra ikili dosyaları yerleştir
sudo cp prometheus promtool /usr/local/bin/
sudo chown prometheus:prometheus /usr/local/bin/prometheus /usr/local/bin/promtool
Servis birimi şöyle olur. --web.enable-lifecycle bayrağı, yapılandırmayı yeniden başlatmadan HTTP ile yeniden yüklemeni sağlar; --storage.tsdb.retention.time ise verinin ne kadar saklanacağını belirler.
# /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
After=network-online.target
[Service]
User=prometheus
Group=prometheus
Type=simple
Restart=on-failure
ExecStart=/usr/local/bin/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/var/lib/prometheus \
--storage.tsdb.retention.time=30d \
--web.listen-address=127.0.0.1:9090 \
--web.enable-lifecycle
[Install]
WantedBy=multi-user.target
Konteyner tarafını tercih ediyorsan Docker Compose ile aynı işi birkaç satırda yaparsın. Yapılandırmayı ve veri dizinini mutlaka kalıcı hacimlere bağla; aksi halde konteyner yeniden oluşturulduğunda tüm geçmişin uçar.
# docker-compose.yml
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
ports:
# Sadece localhost'a bağla, ters vekil arkasına al
- "127.0.0.1:9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prom_data:/prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.retention.time=30d"
- "--web.enable-lifecycle"
volumes:
prom_data:
Kalıcı veri için adlandırılmış hacim kullanmanın nedenlerini merak ediyorsan Docker volume veri yönetimi yazısı konuyu ayrıntılı ele alıyor. Compose dosyasının yapısına aşina değilsen Docker Compose kullanımı iyi bir başlangıç noktası.
prometheus.yml Yapılandırması#
Tüm davranış tek bir YAML dosyasında toplanır. Aşağıdaki örnek, gerçek bir kurulumun iskeletidir ve her satırın ne yaptığı yorumlarda açıklanmıştır:
global:
# Hedefler kaç saniyede bir çekilsin
scrape_interval: 15s
# Tek bir çekme işlemi en fazla ne kadar sürsün
scrape_timeout: 10s
# Alarm kuralları kaç saniyede bir değerlendirilsin
evaluation_interval: 15s
# Tüm metriklere eklenecek ortak etiketler
external_labels:
ortam: uretim
bolge: tr-ist
# Alarm kurallarının bulunduğu dosyalar
rule_files:
- /etc/prometheus/rules/*.yml
# Uyarılar hangi Alertmanager'a gönderilecek
alerting:
alertmanagers:
- static_configs:
- targets: ["alertmanager:9093"]
scrape_configs:
# Prometheus kendi metriklerini de toplasın
- job_name: prometheus
static_configs:
- targets: ["localhost:9090"]
# Sunucu metrikleri
- job_name: node
static_configs:
- targets:
- "185.12.34.56:9100"
- "185.12.34.57:9100"
labels:
rol: web
# Hedefleri dosyadan oku; dosya değişince Prometheus otomatik algılar
- job_name: dinamik
file_sd_configs:
- files:
- /etc/prometheus/targets/*.yml
refresh_interval: 30s
static_configs küçük ortamlar için yeterlidir ama her yeni sunucuda dosyayı elle düzenlemek zorunda kalırsın. file_sd_configs bunu çözer: hedef listesini ayrı bir dosyaya yazarsın, Prometheus'u yeniden yüklemene bile gerek kalmaz. Değişiklikten sonra yapılandırmayı önce doğrula, sonra uygula:
# Söz dizimi kontrolü — bozuk YAML ile servisi hiç yeniden başlatma
promtool check config /etc/prometheus/prometheus.yml
# Yeniden başlatmadan yapılandırmayı yükle (--web.enable-lifecycle gerekli)
curl -X POST http://127.0.0.1:9090/-/reload
Kurulumun doğru çalıştığını http://127.0.0.1:9090/targets adresinden görürsün. Her hedef UP ya da DOWN olarak listelenir; DOWN olanların yanında hata sebebi yazar.
İlk PromQL Sorguları#
Prometheus'un sorgu dili PromQL, ilk bakışta yabancı gelir ama üç kalıbı öğrendiğinde işlerin yüzde sekseni biter. Web arayüzündeki Graph sekmesinden hemen deneyebilirsin.
# 1) Hangi hedefler ayakta? 1 = ayakta, 0 = ulaşılamıyor
up
# 2) Son 5 dakikadaki saniyelik istek hızı (counter -> rate)
rate(http_requests_total[5m])
# 3) Sunucu bazında toplam istek hızı (etiketlere göre topla)
sum by (instance) (rate(http_requests_total[5m]))
# 4) Hata oranı yüzdesi
100 * sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))
# 5) Histogram'dan 95. yüzdelik yanıt süresi
histogram_quantile(0.95,
sum by (le) (rate(http_request_duration_seconds_bucket[5m])))
| Fonksiyon | Ne zaman kullanılır | Dikkat |
|---|---|---|
rate() | Counter'ın saniyelik artışı | Aralık, scrape_interval'in en az 4 katı olmalı |
irate() | Ani dalgalanmayı görmek | Uyarı kuralında kullanma, gürültülüdür |
increase() | Aralıktaki toplam artış | Grafikte değil, raporda anlamlı |
avg_over_time() | Gauge'un ortalaması | Counter'da kullanma |
sum by (...) | Etiket bazında toplama | by yerine without da kullanılabilir |
histogram_quantile() | Yüzdelik hesabı | le etiketi mutlaka toplamada kalmalı |
En yaygın acemi hatası, counter tipindeki bir metriği doğrudan çizdirmektir. Grafikte sürekli yükselen bir doğru görürsün ve hiçbir şey anlamazsın; counter'ı her zaman rate() ya da increase() içine al.
Veri Saklama, Disk Planlaması ve Kardinalite#
Prometheus verisini kendi disk üzerindeki TSDB motorunda tutar ve varsayılan saklama süresi genellikle iki haftadır. Bunu --storage.tsdb.retention.time ile süre olarak, --storage.tsdb.retention.size ile de boyut olarak sınırlayabilirsin. İkisi birlikte tanımlanırsa hangisi önce dolarsa o uygulanır.
Disk ihtiyacını kabaca şöyle tahmin edersin: aktif zaman serisi sayısı × saklama süresindeki örnek sayısı × örnek başına yaklaşık bir-iki bayt. Yani asıl değişken aktif seri sayısıdır ve onu belirleyen şey etiket kardinalitesidir. Etiket değerlerinin her benzersiz kombinasyonu ayrı bir seri açar; kullanici_id, istek_id, oturum_id gibi sınırsız değer alabilen bir etiket koyarsan seri sayısı patlar ve Prometheus önce belleği, sonra diski tüketir.
# En çok seri üreten metrikleri bul (sorun avında ilk bakılacak yer)
topk(10, count by (__name__)({__name__=~".+"}))
# Prometheus'un o an tuttuğu toplam seri sayısı
prometheus_tsdb_head_series
| Ayar | Örnek değer | Etkisi |
|---|---|---|
scrape_interval | 15s – 60s | Küçültmek çözünürlüğü artırır, diski büyütür |
--storage.tsdb.retention.time | 15d – 90d | Geçmişin ne kadar geri gideceği |
--storage.tsdb.retention.size | 50GB | Disk dolmasına karşı sert tavan |
| Etiket kardinalitesi | Düşük tutulmalı | Bellek ve disk üzerindeki tek büyük etken |
Aylardan uzun geçmiş saklaman gerekiyorsa Prometheus'u tek başına zorlamak yerine remote_write ile uzun vadeli bir depoya aktarmak doğru yaklaşımdır. Diskin beklenmedik biçimde dolması Docker tabanlı kurulumlarda ayrı bir baş ağrısıdır; Docker diski doldurdu, nasıl temizlenir yazısı o tarafı ele alıyor.
Güvenlik: 9090 Portunu İnternete Açma#
Prometheus'un kendi kimlik doğrulaması yoktur. 9090 portunu dünyaya açarsan, adresi bilen herkes tüm metriklerini okuyabilir; bu da iç ağ topolojisi, sunucu adları, sürüm bilgileri ve trafik desenleri demektir. Dahası --web.enable-lifecycle açıkken herkes servisi yeniden yükleyebilir, --web.enable-admin-api açıkken ise veriyi silebilir.
Doğru yaklaşım üç katmanlıdır. Birincisi, --web.listen-address=127.0.0.1:9090 ile yalnızca yerel arayüze bağlan. İkincisi, dışarıdan erişim gerekiyorsa önüne TLS ve temel kimlik doğrulama yapan bir ters vekil koy. Üçüncüsü, güvenlik duvarında 9090 ve exporter portlarını yalnızca izleme sunucusunun IP'sine aç.
# Prometheus arayüzünü kimlik doğrulamalı ters vekil arkasına al
server {
listen 443 ssl;
server_name izleme.firmaniz.com;
ssl_certificate /etc/letsencrypt/live/izleme.firmaniz.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/izleme.firmaniz.com/privkey.pem;
location / {
auth_basic "Izleme";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://127.0.0.1:9090;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# Sadece izleme sunucusundan gelen çekmelere izin ver
sudo ufw allow from 185.12.34.56 to any port 9100 proto tcp
sudo ufw deny 9090/tcp
Ters vekil ve sertifika tarafında derinleşmek istersen Apache mı Nginx mi karşılaştırması iki seçeneğin farkını netleştirir. TLS sertifikası için SSL sertifikası sayfamıza da bakabilirsin.
Sık Yapılan Hatalar#
Hedef DOWN görünüyor ama servis çalışıyor. Neredeyse her zaman güvenlik duvarıdır. Önce izleme sunucusundan elle dene: curl -s http://185.12.34.56:9100/metrics | head. Cevap gelmiyorsa sorun Prometheus'ta değil, ağdadır.
Yapılandırmayı düzenledin ama hiçbir şey değişmedi. Prometheus dosyayı kendiliğinden izlemez; ya curl -X POST .../-/reload ile yükle ya da servisi yeniden başlat. Değişiklikten önce mutlaka promtool check config çalıştır.
Grafikler kesik kesik görünüyor. scrape_timeout, scrape_interval değerinden büyük olamaz ve hedef yavaşsa çekme başarısız olur. Hedefin /metrics sayfasının kaç saniyede döndüğünü ölç; binlerce seri üreten bir uygulama saniyeler sürebilir.
Zaman kayması. Sunucuların saati kaymışsa grafikler anlamsızlaşır, hatta gelecekteki örnekler reddedilir. timedatectl status ile NTP eşitlemesinin açık olduğunu doğrula.
Her şeyi tek Prometheus'a yıkmak. Yüzlerce hedefe ulaştığında tek örnek yetmemeye başlar. Ortama göre (üretim/test) ya da bölgeye göre ayrı örnekler çalıştırmak, hem sorumluluğu hem de patlama yarıçapını böler.
Sıkça Sorulan Sorular#
Prometheus ücretsiz mi#
Evet, Prometheus Apache 2.0 lisanslı, tamamen açık kaynak ve ücretsiz bir projedir; CNCF çatısı altında geliştirilir. Kurulum, kullanım ve ölçekleme için herhangi bir lisans ücreti ödemezsin. Tek maliyetin, üzerinde çalıştığın sunucunun kaynakları ve metrik verisinin kapladığı disk alanıdır.
Prometheus verileri ne kadar süre saklar#
Varsayılan saklama süresi genellikle iki haftadır ve --storage.tsdb.retention.time bayrağıyla değiştirilir; örneğin 30d yazarak bir aya çıkarabilirsin. Ayrıca --storage.tsdb.retention.size ile disk üzerinden sınır koyabilirsin. Aylarca ya da yıllarca geçmiş gerekiyorsa Prometheus'u uzun vadeli bir depoya remote_write ile bağlamak, tek örneği şişirmekten çok daha sağlıklıdır.
Prometheus ile Zabbix arasındaki fark nedir#
Prometheus çekme modeliyle çalışır, metrik odaklıdır ve zaman serisi sorgulama üzerine kuruludur; bulut ve konteyner ortamlarında güçlüdür. Zabbix ise ajan tabanlı, daha bütünleşik ve klasik altyapı izlemesine yakın bir sistemdir; kutudan çıkan bildirim, envanter ve arayüz özellikleri daha fazladır. Konteyner ağırlıklı bir ortamda Prometheus, karışık ve donanım ağırlıklı bir parkta Zabbix genelde daha az efor ister.
Uygulamama metrik eklemek için ne yapmalıyım#
Kullandığın dilin resmi Prometheus istemci kütüphanesini projene ekler ve bir /metrics uç noktası yayınlarsın. Kütüphane süreç düzeyindeki temel metrikleri kendiliğinden üretir; sen üzerine kendi sayaç ve gauge'larını eklersin. Sonrasında tek yapman gereken bu adresi prometheus.yml içindeki bir scrape_configs girdisine hedef olarak yazmaktır.
Prometheus'u Grafana olmadan kullanabilir miyim#
Kullanabilirsin; Prometheus'un kendi web arayüzünde sorgu çalıştırıp basit grafikler çizebilirsin. Ancak bu arayüz hata ayıklama içindir, sürekli izlenen bir pano için tasarlanmamıştır. Kalıcı panolar, değişkenler ve ekipçe paylaşılan görünümler için Grafana dashboard oluşturma adımlarını izleyerek Grafana eklemek çok daha verimlidir.
Ne kadar sunucuyu tek bir Prometheus ile izleyebilirim#
Mütevazı bir sunucuda birkaç yüz hedefi rahatlıkla toplayabilirsin; sınırı belirleyen hedef sayısından çok toplam aktif zaman serisi sayısıdır. Milyonlarca seriye çıktığında bellek kullanımı hızla artar ve sorgular yavaşlar. Ölçek büyüdükçe doğru hamle, tek örneği büyütmek yerine ortama veya bölgeye göre birden fazla Prometheus çalıştırıp üstte birleştirici bir katman kullanmaktır.
Kapanış#
Prometheus'u kurmak yarım saatlik bir iştir; onu faydalı hâle getiren şey kurulumdan sonraki alışkanlıklardır. Aklında dört madde kalsın: yapılandırmayı her değişiklikte promtool check config ile doğrula, counter metrikleri asla ham hâlde çizdirme, etiket kardinalitesini sınırsız değer alan alanlarla şişirme ve 9090 portunu asla kimlik doğrulamasız biçimde internete açma. Bu dördü, ilk yılda karşılaşacağın sorunların çoğunu daha doğmadan bitirir.
İzleme yığınını çalıştıracak ayrı bir makineye ihtiyacın varsa, tam root erişimli VDS ve sanal sunucu paketlerimizde Prometheus, Grafana ve exporter'ları rahatça bir arada barındırabilirsin. Kaynak ihtiyacın dalgalanıyorsa bulut sunucu tarafını, kurulum ve bakımı devretmek istersen sunucu yönetimi hizmetimizi değerlendirebilirsin.