Bulut Bilişim

Kubernetes Monitoring Nasıl Kurulur?

Kubernetes monitoring kurulumu nereden başlamalı?

Kubernetes üzerinde çalışan bir uygulamanın ayakta olması, sağlıklı olduğu anlamına gelmez. Pod Running görünebilir; fakat CPU throttling artmış, bellek kullanımı limitine dayanmış, HTTP hataları çoğalmış veya disk dolmak üzere olabilir. Kullanıcı sorunu bildirdiğinde bunları fark ediyorsanız monitoring değil, olay sonrası inceleme yapıyorsunuz demektir.

Ben Kubernetes monitoring kurulumu için genellikle Prometheus, Grafana ve Alertmanager üçlüsünü tercih ediyorum. Prometheus metrikleri toplar, Grafana bunları okunabilir panellere çevirir, Alertmanager ise eşikleri aşan durumları e-posta, Slack veya başka bir bildirim kanalına gönderir. Kubernetes API’sinden gelen durum bilgileri için kube-state-metrics’i de bu yapıya eklerim.

Şöyle anlatayım: Monitoring kurarken ilk hedefiniz yüzlerce grafik oluşturmak değil, gece sizi gerçekten uyandıracak sinyalleri seçmektir. Bir pod’un yeniden başlatıldığını bilmek değerlidir; fakat bunun kaç kez olduğu, hangi deployment’a ait olduğu ve kullanıcı trafiğine yansıyıp yansımadığı daha değerlidir.

Hangi bileşen neyi izler?

Kubernetes monitoring kurulumu sırasında bileşenlerin görevlerini birbirine karıştırmak ileride gereksiz alarm üretir. Aşağıdaki ayrım pratikte işimi kolaylaştırıyor.

Bileşenİzlediği alanNe zaman kullanılır?
PrometheusNode, pod, uygulama ve Kubernetes metrikleriZaman serisi verisi ve sorgulama için
GrafanaPrometheus verisinin panelleriGörselleştirme ve operasyon takibi için
AlertmanagerPrometheus alarm kurallarından gelen bildirimlerUyarıları gruplamak, susturmak ve yönlendirmek için
kube-state-metricsDeployment, pod, job ve node durumlarıKubernetes nesnelerinin beklenen durumunu izlemek için
Node ExporterLinux işletim sistemi metrikleriCPU, RAM, dosya sistemi ve ağ takibi için
Metrics ServerAnlık kaynak kullanım özetikubectl top ve HPA için

Metrics Server ile Prometheus aynı şey değildir. Metrics Server kısa süreli kaynak görünümü sunar; geçmişe dönük sorgular, uygulama metrikleri ve ayrıntılı alarmlar için Prometheus gerekir. kubectl top nodes çalışıyor diye monitoring tamamlanmış sayılmaz.

Ön hazırlık: cluster ve Helm kontrolü

Kuruluma geçmeden önce cluster’a yönetici yetkiniz olduğunu, Helm’in çalıştığını ve hangi Kubernetes sürümünde olduğunuzu kontrol edin. Ben bu kontrolleri doğrudan üretimde değil, önce evdeki Proxmox üzerindeki test cluster’ında yapıyorum. Deneme sırasında bozuk bir chart veya yanlış bir Service türü müşterinin trafiğini etkilememeli.

kubectl cluster-info
kubectl get nodes -o wide
kubectl version
helm version

İlk komut API sunucusunun erişilebilir olduğunu, ikinci komut node’ların durumunu gösterir. helm version çıktısı gelmiyorsa chart kurmaya geçmeden önce Helm kurulmalıdır.

Monitoring bileşenlerini ayrı bir namespace içinde tutmak için önce namespace oluşturun:

kubectl create namespace monitoring
kubectl get namespace monitoring

Namespace zaten mevcutsa AlreadyExists mesajı hata gibi görünse de kurulumun önünde engel değildir. Üretimde komutları tekrar çalıştırılabilir hale getirmek için --dry-run=client -o yaml çıktısını Git’te saklamak daha düzenlidir.

Prometheus Stack kurulumu

Pratik başlangıçlardan biri Prometheus Community tarafından sürdürülen kube-prometheus-stack chart’ıdır. Bu chart Prometheus Operator, Prometheus, Grafana, Alertmanager, node-exporter ve kube-state-metrics bileşenlerini birlikte yönetebilir. Chart sürümünü sabitlemenizi öneririm; rastgele bir güncellemenin CRD davranışını değiştirmesini istemezsiniz.

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm search repo prometheus-community/kube-prometheus-stack

Repository eklenir ve güncel chart listesi alınır. Kurulumdan önce chart’ın sürümünü bu listeden not edin.

Basit bir test ortamında varsayılan değerlerle kurulum yapılabilir:

helm install monitoring prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace

Bu komut monitoring adlı Helm release oluşturur. Üretimde varsayılan değerlerle ilerlemek yerine bir values.yaml dosyası hazırlayın; özellikle kalıcı disk, kaynak limitleri ve Grafana erişimi bu dosyada açıkça tanımlanmalıdır.

Üretim için temel values.yaml

Aşağıdaki örnek başlangıç seviyesinde bir yapılandırmadır. StorageClass adını kendi cluster’ınızda kubectl get storageclass çıktısına göre değiştirin. Her ortamın disk performansı, saklama süresi ve node kapasitesi farklıdır.

grafana:
  admin:
    existingSecret: grafana-admin
  persistence:
    enabled: true
    storageClassName: standard
    size: 10Gi
  resources:
    requests:
      cpu: 100m
      memory: 256Mi
    limits:
      cpu: 500m
      memory: 512Mi

prometheus:
  prometheusSpec:
    retention: 15d
    retentionSize: 40GB
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: standard
          accessModes: ['ReadWriteOnce']
          resources:
            requests:
              storage: 50Gi
    resources:
      requests:
        cpu: 500m
        memory: 1Gi
      limits:
        cpu: 2
        memory: 4Gi

alertmanager:
  alertmanagerSpec:
    storage:
      volumeClaimTemplate:
        spec:
          storageClassName: standard
          accessModes: ['ReadWriteOnce']
          resources:
            requests:
              storage: 10Gi

Burada Prometheus verisi ve Grafana ayarları pod silinse bile kalıcı disk üzerinde tutulur. Disk boyutu yalnızca pod sayısına göre belirlenmez; scrape aralığı, etiket kardinalitesi ve retention süresi de hesaba katılır.

Dosyayı kullanarak kurulumu veya güncellemeyi şöyle yapabilirsiniz:

helm upgrade --install monitoring prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --values values.yaml \
  --wait \
  --timeout 10m

--wait kaynakların hazır olmasını bekler, fakat her sorunu çözmez. Komut timeout verirse hemen tekrar kurmak yerine pod, event ve PVC durumunu kontrol edin.

Kurulumun çalıştığını nasıl doğrularım?

Önce namespace içindeki pod’ları izleyin:

kubectl get pods -n monitoring -w

Pod’ların Running veya uygun olanlarda Completed durumuna geçmesini bekleyin. Pending bir pod genellikle kaynak yetersizliği, uygun node seçilememesi veya PVC’nin bağlanamaması anlamına gelir.

kubectl get pvc -n monitoring
kubectl get svc -n monitoring
kubectl get events -n monitoring --sort-by=.lastTimestamp

Bu üç komut depolama, servis ve namespace event’lerini birlikte gösterir. Özellikle FailedScheduling, FailedMount ve image çekme hataları kurulumun neden hazır olmadığını çoğu zaman açık eder.

Prometheus ve Grafana’ya ilk test için port yönlendirme kullanabilirsiniz:

kubectl port-forward -n monitoring svc/monitoring-kube-prometheus-prometheus 9090:9090
kubectl port-forward -n monitoring svc/monitoring-grafana 3000:80

Sonra yerel makinenizde http://127.0.0.1:9090 ve http://127.0.0.1:3000 adreslerini açın. Port-forward yalnızca geçici test içindir; Grafana’yı internete doğrudan açmak yerine VPN, bastion host veya kimlik doğrulamalı bir reverse proxy kullanın. Hosting panellerine erişimde VPN ve bastion yaklaşımını anlattığım VPN ve Bastion Host ile Hosting Panellerine Güvenli Uzaktan Erişim Mimarisi yazısındaki prensipler burada da geçerlidir.

Prometheus arayüzünde up sorgusunu çalıştırın. Değeri 1 olan hedef erişilebilir, 0 olan hedef ise scrape edilemiyor demektir. Grafana’da hazır Kubernetes panelleri görünür; fakat panelin görünmesi verinin doğru olduğu anlamına gelmez. Zaman aralığını değiştirerek gerçekten veri akışı olup olmadığını kontrol edin.

Uygulama metriklerini Prometheus’a açmak

Node ve Kubernetes nesnelerini izlemek yeterli değildir. Kullanıcıya hizmet veren uygulamanın istek sayısı, yanıt süresi ve hata oranı gibi metrikleri de üretmesi gerekir. Birçok framework için Prometheus client kütüphaneleri bulunur. Uygulama genellikle /metrics endpoint’ini açar.

Prometheus Operator kullandığınızda bu endpoint’i bir ServiceMonitor nesnesiyle tanımlarsınız. Önce uygulamanın servisi doğru label ile seçilmeli:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: orders-api
  namespace: monitoring
  labels:
    release: monitoring
spec:
  namespaceSelector:
    matchNames:
      - production
  selector:
    matchLabels:
      app: orders-api
  endpoints:
    - port: metrics
      path: /metrics
      interval: 30s

Buradaki release: monitoring label’ı chart’ın Prometheus seçicisiyle uyumlu olmalıdır; sizin values dosyanızda farklı bir selector varsa onu kullanın. Service üzerinde name: metrics adlı port bulunmuyorsa ServiceMonitor oluşturulsa bile veri gelmez.

Kontrol için Prometheus arayüzündeki Status ve Targets sayfalarına bakın. Hedef UP görünmüyorsa önce DNS, port, path ve NetworkPolicy kontrol edilir. Uygulama endpoint’i dışarıdan erişilebilir değilse bu tek başına sorun değildir; Prometheus’un bulunduğu namespace’ten erişilebilir olması yeterlidir.

Alarm kuralları: çok alarm değil, doğru alarm

Alertmanager yapılandırılmadan alarm kuralı yazmak eksik bir kurulumdur. Prometheus alarmı üretir; Alertmanager aynı alarmı gruplayabilir, susturabilir ve doğru ekibe gönderebilir. Pending süresi tanımlamak da kısa süreli dalgalanmaların gece bildirimi üretmesini engeller.

Örneğin bir deployment’ın hazır pod sayısı beklenenin altındaysa şu kural kullanılabilir:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: application-alerts
  namespace: monitoring
  labels:
    release: monitoring
spec:
  groups:
    - name: application.rules
      rules:
        - alert: DeploymentReplicasMismatch
          expr: kube_deployment_status_replicas_available{namespace="production"} < kube_deployment_spec_replicas{namespace="production"}
          for: 10m
          labels:
            severity: warning
          annotations:
            summary: "Deployment beklenen pod sayısına ulaşamadı"
            description: "{{ $labels.deployment }} için hazır pod sayısı 10 dakikadır düşük."

        - alert: InstanceDown
          expr: up{job=~".*"} == 0
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: "Monitoring hedefi erişilemiyor"
            description: "{{ $labels.instance }} hedefi scrape edilemiyor."

İlk alarm deployment kapasitesindeki kalıcı düşüşü, ikincisi scrape hedefindeki erişim problemini bildirir. Gerçek ortamda up == 0 kuralını her hedefe uygulamak yerine kritik job’ları ayrıca seçmek gerekebilir; bakım sırasında gereksiz alarm yağmuru istemezsiniz.

Alertmanager’da alıcı tanımlarken SMTP parolasını YAML içine düz metin yazmayın. Kubernetes Secret veya secret yönetim sistemi kullanın. Bildirim kanalını kurduktan sonra kontrollü bir test alarmı üretip mesajın gerçekten ulaştığını doğrulayın. Sessizce duran Alertmanager, çalışmayan bir yangın alarmına benzer.

Kaynak kullanımı ve kardinalite tuzağı

Prometheus’un kendisi de izlenmesi gereken bir servistir. Bellek kullanımı artıyorsa ilk şüphelilerden biri yüksek kardinalitedir. Her istek için benzersiz URL, kullanıcı ID’si veya sipariş numarasını label yapmak zaman serisi sayısını hızla büyütür.

Şu iki label yaklaşımı aynı değildir:

http_requests_total{path="/orders/847291"}
http_requests_total{route="/orders/:id"}

İlk örnekte her sipariş için yeni bir seri oluşabilir. İkinci örnek route’u geneller ve daha yönetilebilir bir kardinalite üretir. Metrik isimleri ve label’lar uygulama geliştirme aşamasında kararlaştırılmalı; sorun çıktıktan sonra temizlemek daha zahmetlidir.

Prometheus pod’u sürekli yeniden başlıyorsa şunlara bakın:

kubectl describe pod -n monitoring -l app.kubernetes.io/name=prometheus
kubectl logs -n monitoring -l app.kubernetes.io/name=prometheus --previous
kubectl top pod -n monitoring

--previous seçeneği, yeniden başlatılmış container’ın bir önceki logunu gösterir. OOMKilled görürseniz doğrudan limiti artırmak yerine retention, scrape aralığı ve yüksek kardinaliteli metrikleri de inceleyin.

Bir DDoS gecesinde monitoring’in gerçek sınavı

İlk büyük DDoS gecemde dashboard’lar çalışıyor, node metrikleri normal görünüyor, fakat uygulama erişilebilirlik kontrollerinde hata oranı yükseliyordu. İlk bakışta trafik artışını gerçek kullanıcı yoğunluğu sanmak kolaydı. Metrikleri istek kaynakları ve yanıt kodlarıyla birlikte incelediğimizde isteklerin önemli bölümünün gerçek ziyaretçi davranışına benzemediği ortaya çıktı.

Rate limit, coğrafi filtre ve ingress katmanındaki bağlantı limitlerini devreye alırken müşteriye şu ayrımı anlatmam gerekti: Her HTTP isteği gerçek ziyaretçi değildir. Monitoring yalnızca CPU ve bellek grafiği sunmamalı; HTTP 4xx/5xx oranını, istek hacmini, yanıt süresini ve mümkünse kaynak dağılımını da göstermelidir.

O geceden sonra alarm kurallarını yalnızca node sağlığına göre bırakmadım. Ingress 5xx oranı, ani istek artışı ve uygulamanın dışarıdan yanıt verip vermediği ayrı sinyaller olarak tanımlandı. Alarmın kendisini de izlemek gerekir; Prometheus hedefleri scrape edemiyorsa, Grafana veri kaynağına bağlanamıyorsa veya Alertmanager bildirim gönderemiyorsa bunlar ayrı alarm üretmelidir.

Güvenlik, erişim ve maliyet

Grafana panelleri zararsız görünür; fakat metriklerde servis adları, namespace’ler, node isimleri ve bazen müşteri bilgisine dönüşebilecek label değerleri bulunabilir. Grafana’yı anonim erişime açmayın. Kubernetes API’ye geniş yetkili bir ServiceAccount vermek de gereksiz risk oluşturur; chart’ın ihtiyaç duyduğu RBAC izinlerini ve oluşturulan kaynakları inceleyin.

NetworkPolicy kullanıyorsanız Prometheus’un kube-state-metrics, node-exporter ve uygulama metric servislerine erişebildiğinden emin olun. Önce policy’siz test edip sonra kademeli kısıtlama uygulamak, her şeyi aynı anda kapatıp sorunun kaynağını aramaktan daha hızlıdır.

Veri saklama süresi de maliyet yaratır. On beş günlük ayrıntılı metrik çoğu küçük cluster için başlangıçta yeterli olabilir; fakat kapasite planlaması için aylarca veri gerekiyorsa uzun süreli saklama sistemleri veya uzaktan yazma seçenekleri değerlendirilir. Prometheus diskini sınırsız büyütmek yerine retention ve retention size birlikte belirlenmelidir.

Monitoring’i işletmek: kurulumdan sonraki işler

Bir dashboard’u açıp bırakmayın. Her hafta hangi alarmların üretildiğini, kaçının susturulduğunu ve hangilerinin aksiyona dönüşmediğini inceleyin. Üç kez yanlış alarm üreten bir kural ya eşik, ya sorgu, ya da hizmetin tasarımı açısından yeniden ele alınmalıdır.

Bakım sırasında alarmları susturmak gerekiyorsa süre ve açıklama girin. Sonsuza kadar açık bir silence, alarmı kapatmanın daha şık yazılmış halidir. Deployment değişikliklerinden sonra özellikle şu kontrolleri otomatikleştirebilirsiniz:

  • Prometheus target durumları
  • Grafana veri kaynağı erişimi
  • Alertmanager alıcılarına test bildirimi
  • PVC doluluk oranı
  • Pod restart sayısı ve OOMKilled olayları
  • Node disk, CPU ve bellek baskısı
  • Ingress HTTP 5xx oranı ve yanıt süresi

Uygulamanız Kubernetes üzerinde çalışsa bile kullanıcı gözünden yapılan sentetik kontrolleri ayrıca tutun. Pod’ların sağlıklı görünmesi, ödeme endpoint’inin gerçekten cevap verdiğini kanıtlamaz. Dışarıdan bir HTTP kontrolü ve içerideki Prometheus metrikleri birlikte değerlendirildiğinde yanlış teşhis ihtimali azalır.

Kubernetes operasyonlarının yanında uygulama katmanındaki kontrolleri de ihmal etmeyin. Bir WordPress sunucusunda farklı türde sağlık sinyallerini okumak için WordPress Site Sağlığı Raporu Nasıl Okunur? başlıklı rehberdeki yaklaşım burada da işe yarar: uyarıyı görmek yetmez, hangi bileşenin ve hangi kullanıcı akışının etkilendiğini ayırmak gerekir.

Kendi lab ortamımda chart güncellemelerini önce ayrı bir namespace’te deniyor, ardından test alarmı üretip dashboard sorgularını karşılaştırıyorum. Üretimde bir grafiğin boş kalması çoğu zaman Prometheus’un bozuk olduğunu değil, label selector’ın yeni deployment ile artık eşleşmediğini gösteriyor. Bu küçük ayrım, saatler süren gereksiz incelemeyi önlüyor.

Sık Sorulan Sorular

Prometheus ile Metrics Server arasındaki fark nedir?

Metrics Server anlık CPU ve bellek kullanımını Kubernetes API’ye sunar; kubectl top ve Horizontal Pod Autoscaler gibi özelliklerde kullanılır. Prometheus ise zaman serisi verisini saklar, uygulama metriklerini toplar ve alarm kuralları çalıştırır.

Kubernetes monitoring için Grafana kurmak zorunlu mu?

Hayır. Prometheus sorguları ve Alertmanager ile Grafana olmadan da monitoring yapılabilir. Grafana, çok sayıda metriği ekiplerin daha hızlı okuyabileceği panellere dönüştürdüğü için pratikte sık tercih edilir.

Prometheus verileri ne kadar süre saklanmalı?

Bu süre cluster büyüklüğüne, disk kapasitesine ve geçmiş analiz ihtiyacına bağlıdır. Başlangıçta 7-15 günlük bir retention belirleyip disk kullanımını izlemek, sınırsız saklama tanımlamaktan daha güvenlidir.

Alarm sayısını nasıl azaltabilirim?

Önce aynı olayı farklı kuralların bildirip bildirmediğini kontrol edin. Kısa süreli dalgalanmalar için for süresi ekleyin, kritik ve bilgilendirici seviyeleri ayırın; hiçbir işlem gerektirmeyen alarmı silmekten çekinmeyin.