Elasticsearch ile ELK Stack Kurulumu ve Yapılandırması

Modern altyapılarda log yönetimi ve analizi artık bir lüks değil, zorunluluk haline geldi. Yüzlerce sunucudan akan logları tek bir yerden analiz etmek, anomalileri tespit etmek ve güzel görsellerle sunmak istiyorsanız ELK Stack tam size göre. Elasticsearch, Logstash ve Kibana’dan oluşan bu üçlü, sektörün en popüler log analiz platformu konumunda. Bu yazıda sıfırdan production-ready bir ELK Stack kurulumu yapacağız.

ELK Stack Nedir?

ELK Stack üç temel bileşenden oluşur:

  • Elasticsearch: Dağıtık, RESTful arama ve analitik motoru. Verilerinizi saklar ve sorgular.
  • Logstash: Veri toplama, dönüştürme ve iletim pipeline’ı. Farklı kaynaklardan veri alır, işler ve Elasticsearch’e gönderir.
  • Kibana: Elasticsearch verilerini görselleştiren web arayüzü. Dashboard’lar, grafikler ve real-time izleme.

Son yıllarda bu stack’e Beats ailesi de eklendi. Filebeat, Metricbeat, Packetbeat gibi hafif veri toplayıcılar doğrudan sunuculara kurularak veri gönderir.

Gerçek dünya senaryomuz şu olacak: 5 uygulama sunucusundan nginx, application ve system loglarını merkezi bir ELK sunucusuna toplayacağız ve Kibana üzerinden analiz edeceğiz.

Sistem Gereksinimleri ve Planlama

Production ortam için minimum öneriler:

  • İşlemci: 4 vCPU (8 vCPU önerilir)
  • RAM: 16 GB (Elasticsearch için minimum 8 GB)
  • Disk: 500 GB SSD (log hacmine göre değişir)
  • OS: Ubuntu 22.04 LTS veya RHEL/CentOS 8+

Bu yazıda Ubuntu 22.04 kullanacağız. Elasticsearch ve Java birlikte geldiği için ayrı JDK kurmanıza gerek yok.

Java ve Sistem Hazırlığı

Elasticsearch kendi JVM’ini getiriyor ancak sistem limitleri kritik önem taşıyor. Önce temel ayarları yapalım:

# Sistem güncellemesi
sudo apt update && sudo apt upgrade -y

# Gerekli paketler
sudo apt install -y curl wget apt-transport-https gnupg2

# vm.max_map_count ayarı - Elasticsearch için zorunlu
sudo sysctl -w vm.max_map_count=262144

# Kalıcı hale getirme
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf

# File descriptor limitleri
sudo tee -a /etc/security/limits.conf << 'EOF'
elasticsearch soft nofile 65536
elasticsearch hard nofile 65536
elasticsearch soft nproc 4096
elasticsearch hard nproc 4096
EOF

Bu ayarları atlarsanız Elasticsearch başlamayı reddeder ya da performans sorunları yaşarsınız. Özellikle vm.max_map_count değerini production öncesi mutlaka kontrol edin.

Elasticsearch Kurulumu

Elastic’in resmi GPG anahtarı ve repository’sini ekleyerek kuruluma başlıyoruz:

# GPG anahtarı ekle
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | 
  sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg

# Repository ekle
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] 
  https://artifacts.elastic.co/packages/8.x/apt stable main" | 
  sudo tee /etc/apt/sources.list.d/elastic-8.x.list

# Elasticsearch kur
sudo apt update
sudo apt install -y elasticsearch

# Servisi etkinleştir ve başlat
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch

Kurulum sırasında terminal çıktısında otomatik oluşturulan elastic kullanıcı şifresini mutlaka kaydedin. Bu şifreyi kaybederseniz sıfırlamanız gerekir.

Elasticsearch Yapılandırması

Ana yapılandırma dosyasını düzenleyelim:

sudo nano /etc/elasticsearch/elasticsearch.yml

Dosya içeriğini şu şekilde güncelleyin:

# Cluster adı
cluster.name: production-elk

# Node adı (her node için benzersiz olmalı)
node.name: elk-master-01

# Veri ve log dizinleri
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

# Network ayarları
network.host: 0.0.0.0
http.port: 9200

# Discovery ayarları (single node için)
discovery.type: single-node

# Güvenlik ayarları
xpack.security.enabled: true
xpack.security.enrollment.enabled: true

# Memory lock - swap kullanımını engeller
bootstrap.memory_lock: true

JVM Heap Ayarları

Elasticsearch için bellek ayarları kritik. Genel kural: toplam RAM’in yarısını Elasticsearch’e ver, ama 32 GB’ı asma:

sudo nano /etc/elasticsearch/jvm.options.d/heap.options
# 16 GB RAM'li sistemde
-Xms8g
-Xmx8g

Ayarları uygulamak için servisi yeniden başlatın:

sudo systemctl restart elasticsearch

# Durumu kontrol et
sudo systemctl status elasticsearch

# API ile test et (şifreyi değiştirin)
curl -k -u elastic:SIFRENIZ https://localhost:9200

Başarılı yanıt şöyle görünmeli:

{
  "name" : "elk-master-01",
  "cluster_name" : "production-elk",
  "version" : { ... },
  "tagline" : "You Know, for Search"
}

Kibana Kurulumu

Elasticsearch çalışır durumdaysa Kibana’ya geçebiliriz:

# Kibana kur (aynı repository'den)
sudo apt install -y kibana

# Servis etkinleştir
sudo systemctl enable kibana

Kibana yapılandırmasını düzenleyelim:

sudo nano /etc/kibana/kibana.yml
# Kibana port ve host
server.port: 5601
server.host: "0.0.0.0"
server.name: "elk-master-01"

# Elasticsearch bağlantısı
elasticsearch.hosts: ["https://localhost:9200"]

# Güvenlik sertifikası
elasticsearch.ssl.certificateAuthorities: ["/etc/kibana/certs/http_ca.crt"]
elasticsearch.ssl.verificationMode: certificate

# Kibana sistem kullanıcısı için credentials
elasticsearch.username: "kibana_system"
elasticsearch.password: "KIBANA_SISTEM_SIFRESI"

Kibana için sistem kullanıcısı şifresini Elasticsearch üzerinden ayarlayın:

# Kibana sistem kullanıcısı şifresi
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u kibana_system

# CA sertifikasını Kibana'ya kopyala
sudo mkdir -p /etc/kibana/certs
sudo cp /etc/elasticsearch/certs/http_ca.crt /etc/kibana/certs/
sudo chown -R kibana:kibana /etc/kibana/certs

# Kibana başlat
sudo systemctl start kibana
sudo systemctl status kibana

Kibana’ya http://SUNUCU_IP:5601 adresinden erişebilirsiniz. İlk girişte elastic kullanıcısı ve kurulumda verilen şifreyi kullanın.

Logstash Kurulumu ve Pipeline Yapılandırması

Logstash, veri akışının beyni. Kurulum:

sudo apt install -y logstash
sudo systemctl enable logstash

Pipeline Yapılandırması

Logstash pipeline’ı üç aşamadan oluşur: input, filter ve output. Nginx logları için örnek bir pipeline:

sudo nano /etc/logstash/conf.d/nginx-logs.conf
input {
  beats {
    port => 5044
    ssl => false
  }
}

filter {
  if [fields][log_type] == "nginx_access" {
    grok {
      match => {
        "message" => '%{COMBINEDAPACHELOG}'
      }
    }
    date {
      match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
      target => "@timestamp"
    }
    geoip {
      source => "clientip"
      target => "geoip"
    }
    mutate {
      convert => {
        "response" => "integer"
        "bytes" => "integer"
      }
      remove_field => ["timestamp", "message"]
    }
  }

  if [fields][log_type] == "nginx_error" {
    grok {
      match => {
        "message" => '%{DATA:timestamp} [%{DATA:severity}] %{GREEDYDATA:error_message}'
      }
    }
  }
}

output {
  if [fields][log_type] =~ /nginx/ {
    elasticsearch {
      hosts => ["https://localhost:9200"]
      user => "elastic"
      password => "SIFRENIZ"
      ssl => true
      cacert => "/etc/logstash/certs/http_ca.crt"
      index => "nginx-logs-%{+YYYY.MM.dd}"
    }
  }
}

Bu pipeline Filebeat’ten gelen Nginx loglarını parse eder, IP adreslerini coğrafi konuma çevirir ve günlük index’lere yazar.

# Pipeline syntax kontrolü
sudo -u logstash /usr/share/logstash/bin/logstash 
  --path.settings /etc/logstash 
  -t -f /etc/logstash/conf.d/nginx-logs.conf

# Logstash başlat
sudo systemctl start logstash
sudo systemctl status logstash

Filebeat Kurulumu (Agent Sunucular)

Her uygulama sunucusuna Filebeat kurarak logları Logstash’e göndereceğiz:

# Uygulama sunucularında çalıştırın
sudo apt install -y filebeat

sudo nano /etc/filebeat/filebeat.yml
filebeat.inputs:
  - type: log
    enabled: true
    paths:
      - /var/log/nginx/access.log
    fields:
      log_type: nginx_access
      server_name: web-server-01
    fields_under_root: false
    multiline.pattern: '^d{4}/d{2}/d{2}'
    multiline.negate: true
    multiline.match: after

  - type: log
    enabled: true
    paths:
      - /var/log/nginx/error.log
    fields:
      log_type: nginx_error
      server_name: web-server-01

  - type: log
    enabled: true
    paths:
      - /var/log/syslog
    fields:
      log_type: syslog
      server_name: web-server-01

# Logstash'e gönder
output.logstash:
  hosts: ["ELK_SUNUCU_IP:5044"]

# Elasticsearch'e doğrudan göndermek isterseniz (Logstash bypass)
# output.elasticsearch:
#   hosts: ["https://ELK_SUNUCU_IP:9200"]

# Genel ayarlar
processors:
  - add_host_metadata:
      when.not.contains.tags: forwarded

logging.level: warning
logging.to_files: true
logging.files:
  path: /var/log/filebeat
  name: filebeat
  keepfiles: 7
# Filebeat başlat
sudo systemctl enable filebeat
sudo systemctl start filebeat

# Test - logların akıp akmadığını kontrol et
sudo filebeat test output
sudo filebeat test config

Index Lifecycle Management (ILM) Kurulumu

Production’da disk yönetimi kritik. Eski indexleri otomatik silmek için ILM policy oluşturalım:

# ILM policy oluştur
curl -k -X PUT "https://localhost:9200/_ilm/policy/nginx-logs-policy" 
  -u elastic:SIFRENIZ 
  -H 'Content-Type: application/json' 
  -d '{
  "policy": {
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_primary_shard_size": "50gb",
            "max_age": "7d"
          }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": {
          "shrink": {
            "number_of_shards": 1
          },
          "forcemerge": {
            "max_num_segments": 1
          }
        }
      },
      "cold": {
        "min_age": "30d",
        "actions": {
          "freeze": {}
        }
      },
      "delete": {
        "min_age": "90d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}'

Bu policy ile:

  • Hot fazı: Son 7 gün veya 50 GB dolunca yeni index’e geç
  • Warm fazı: 7 günden eski indexler shard sayısı azaltılır, merge edilir
  • Cold fazı: 30 günden eski indexler dondurulur (arama yavaş ama disk ekonomik)
  • Delete fazı: 90 günden eski indexler silinir

Elasticsearch Güvenlik Sertleştirmesi

Production’da temel güvenlik adımları:

# Güçlü şifre policy tanımla
curl -k -X PUT "https://localhost:9200/_security/role/readonly_user" 
  -u elastic:SIFRENIZ 
  -H 'Content-Type: application/json' 
  -d '{
  "indices": [
    {
      "names": ["nginx-logs-*", "syslog-*"],
      "privileges": ["read", "view_index_metadata"]
    }
  ]
}'

# Read-only kullanıcı oluştur
curl -k -X PUT "https://localhost:9200/_security/user/dashboard_user" 
  -u elastic:SIFRENIZ 
  -H 'Content-Type: application/json' 
  -d '{
  "password": "Guclu_Bir_Sifre_123!",
  "roles": ["readonly_user"],
  "full_name": "Dashboard Kullanici"
}'

Firewall kuralları da ihmal edilmemeli:

# UFW ile port yönetimi
sudo ufw allow from 192.168.1.0/24 to any port 9200  # Sadece internal
sudo ufw allow from 192.168.1.0/24 to any port 5601  # Kibana internal
sudo ufw allow 5044  # Filebeat için (gerekirse kısıtlayın)
sudo ufw enable

Kibana Dashboard Kurulumu ve Monitoring

Kibana’da ilk index pattern’i oluşturmak için Stack Management > Index Patterns yolunu takip edin. nginx-logs-* pattern’ini ekleyin ve @timestamp alanını zaman alanı olarak seçin.

Elasticsearch cluster sağlığını düzenli kontrol etmek için basit bir monitoring scripti:

sudo nano /usr/local/bin/elk-health-check.sh
#!/bin/bash

ES_HOST="https://localhost:9200"
ES_USER="elastic"
ES_PASS="SIFRENIZ"
ALERT_EMAIL="[email protected]"

# Cluster health kontrolü
HEALTH=$(curl -sk -u "${ES_USER}:${ES_PASS}" 
  "${ES_HOST}/_cluster/health" | python3 -c 
  "import sys, json; print(json.load(sys.stdin)['status'])")

DISK_USAGE=$(df /var/lib/elasticsearch | awk 'NR==2 {print $5}' | tr -d '%')

echo "$(date): Cluster Health: ${HEALTH}, Disk: ${DISK_USAGE}%"

if [ "${HEALTH}" == "red" ]; then
  echo "KRITIK: Elasticsearch cluster RED durumda!" | 
    mail -s "ELK ALERT: Cluster RED" "${ALERT_EMAIL}"
fi

if [ "${DISK_USAGE}" -gt 80 ]; then
  echo "UYARI: Elasticsearch disk kullanimi %${DISK_USAGE}" | 
    mail -s "ELK ALERT: Disk Dolmak Uzere" "${ALERT_EMAIL}"
fi

# Index sayısı ve boyutu
curl -sk -u "${ES_USER}:${ES_PASS}" 
  "${ES_HOST}/_cat/indices?v&s=store.size:desc" | head -20
sudo chmod +x /usr/local/bin/elk-health-check.sh

# Cron ile her 15 dakikada bir çalıştır
echo "*/15 * * * * root /usr/local/bin/elk-health-check.sh >> /var/log/elk-health.log 2>&1" | 
  sudo tee -a /etc/crontab

Yaygın Sorunlar ve Çözümleri

Kurulum ve işletim sırasında sıkça karşılaşılan sorunlar:

  • Elasticsearch başlamıyor: journalctl -u elasticsearch -f ile logları takip edin. Çoğunlukla vm.max_map_count veya memory lock sorunundan kaynaklanır.
  • Yüksek CPU kullanımı: Çok fazla shard olabilir. Her index için shard sayısını gözden geçirin. Küçük indexler için 1 primary shard yeterli.
  • Disk doldu, indexler kırmızıya döndü: Elasticsearch disk %95’in üzerine çıkınca otomatik read-only moda geçer. Disk temizledikten sonra index.blocks.read_only_allow_delete bloğunu kaldırmanız gerekir.
  • Logstash pipeline gecikmesi: Logstash pipeline.workers değerini CPU core sayısına göre artırın. /etc/logstash/logstash.yml dosyasında pipeline.workers: 4 şeklinde ayarlayın.
  • Filebeat log kaybı: Filebeat’in registry dosyasını kontrol edin. /var/lib/filebeat/registry altında hangi pozisyona kadar okuduğunu görebilirsiniz.

Performans İyileştirme İpuçları

  • Swap’ı devre dışı bırakın: Elasticsearch için swap ölüm öpücüğüdür. swapoff -a ile kapatın, /etc/fstab‘dan da kaldırın.
  • Index template kullanın: Her yeni index için aynı ayarların otomatik uygulanması için template oluşturun. Shard sayısı, replica sayısı ve field mapping’leri template’de tanımlayın.
  • Bulk indexing: Logstash’te flush_size ve idle_flush_time değerlerini ihtiyacınıza göre ayarlayın. Çok sık küçük write’lar yerine az sık büyük batch’ler Elasticsearch’i mutlu eder.
  • Curator veya ILM: Eski indexlerin yönetimi için ILM kullanmak Elasticsearch 7.x sonrası önerilir. Curator eski ama hala işlevsel bir alternatif.
  • Monitoring için Metricbeat: ELK Stack’in kendi sağlığını izlemek için Metricbeat kurun ve Elasticsearch/Kibana modüllerini aktif edin.

Sonuç

ELK Stack kurulumu ilk bakışta ürkütücü görünebilir ancak adım adım ilerlediğinizde oldukça tutarlı bir yapıyla karşılaşırsınız. Bu yazıda Elasticsearch’ün kurulumundan ILM ile otomatik disk yönetimine, Filebeat agent yapılandırmasından güvenlik sertleştirmesine kadar production’a hazır bir kurulum için gereken tüm temel adımları anlattık.

Unutmayın, ELK Stack’in en büyük güçlerinden biri esnekliği. Yüzlerce farklı input plugin, binlerce Kibana dashboard şablonu ve aktif bir topluluk mevcut. Sistemi ayağa kaldırdıktan sonra asıl eğlence, Kibana’da anlamlı dashboard’lar ve alertler oluşturmakla başlıyor. Anomaly detection için Elasticsearch’ün Machine Learning özelliklerini de incelemenizi tavsiye ederim; özellikle güvenlik loglarında beklenmedik pattern’leri yakalamak için oldukça güçlü araçlar sunuyor.

Prod ortama geçmeden önce bir test ortamında disaster recovery senaryolarını da mutlaka deneyin. Elasticsearch snapshot/restore mekanizmasını kurun ve düzenli olarak test edin. Loglarınız önemliyse onların yedekleri de en az o kadar önemli.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir