ELK Stack ile DevOps Log Merkezi Kurulumu
Üretim ortamında çalışan bir sistemin loglarını takip etmek, özellikle onlarca sunucu, onlarca servis söz konusu olduğunda gerçek bir kabus haline gelebilir. Bir geceyarısı alarm çaldığında “hangi sunucuda ne oldu?” sorusuna dakikalar içinde cevap verebilmek, iyi kurulmuş bir log merkezi altyapısıyla mümkün. Ben bu yazıda size ELK Stack kullanarak sıfırdan çalışan bir DevOps log merkezi nasıl kurulur, onu anlatacağım. Teorik değil, gerçekten kullandığım, üretimde çalışan bir kurulumun adımlarını paylaşacağım.
ELK Stack Nedir ve Neden ELK?
ELK, üç açık kaynak aracın baş harflerinden oluşuyor: Elasticsearch, Logstash ve Kibana. Günümüzde bu stack’e Beats ailesini de ekleyince BELK ya da Elastic Stack deniyor, ama herkes hâlâ ELK diyor.
- Elasticsearch: Dağıtık arama ve analiz motoru. Loglarınızı burada saklıyorsunuz ve sorgu atıyorsunuz.
- Logstash: Log toplama, dönüştürme ve Elasticsearch’e gönderme pipeline’ı.
- Kibana: Elasticsearch üzerindeki görselleştirme ve dashboard katmanı.
- Filebeat / Metricbeat: Sunuculardan log toplayan hafif agent’lar.
Neden ELK? Splunk gibi ticari alternatiflere kıyasla maliyet açısından çok avantajlı, Graylog’a kıyasla ekosistem çok daha olgun, Loki+Grafana kombinasyonuna göre ise özellikle uygulama logları için çok daha güçlü sorgu yetenekleri sunuyor. Tabii her şeyin bir bedeli var; ELK kaynak tüketimi yüksek bir stack, bunu baştan söyleyeyim.
Mimari Tasarım
Küçük bir ortam için bile doğru mimariyi baştan kurmak önemli. Ben genellikle şu yapıyı kullanıyorum:
- Her uygulama sunucusuna Filebeat kuruyorum (log agent)
- Filebeat logları doğrudan Logstash‘a gönderiyor
- Logstash parse edip Elasticsearch‘e yazıyor
- Kibana Elasticsearch üzerinden verileri görselleştiriyor
Bu yazıda Ubuntu 22.04 üzerinde tek node bir kurulum yapacağız. Üretim için multi-node Elasticsearch cluster kurmanızı öneririm ama kavramları öğrenmek ve orta ölçekli ortamlar için bu yeterli.
Sistem Gereksinimleri
ELK Stack için minimum gereksinimler şu şekilde:
- CPU: En az 4 vCPU (8 önerilir)
- RAM: En az 8 GB (16 GB önerilir, Elasticsearch JVM heap için kritik)
- Disk: SSD tercih edilmeli, en az 100 GB
- OS: Ubuntu 22.04 LTS veya RHEL/CentOS 8+
- Java: Elasticsearch kendi JVM’ini getiriyor, ayrıca kurmanıza gerek yok
Kurulum Öncesi Hazırlık
Önce sistemi güncelleyelim ve gerekli paketleri kuralım:
sudo apt update && sudo apt upgrade -y
sudo apt install apt-transport-https curl gnupg2 -y
# Elastic GPG anahtarını ekle
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elastic-keyring.gpg
# Elastic repository ekle
echo "deb [signed-by=/usr/share/keyrings/elastic-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt update
Elasticsearch heap boyutunu düzgün ayarlamak için sistem parametrelerini de düzenleyelim:
# vm.max_map_count ayarı - Elasticsearch için zorunlu
sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
# Ulimit ayarları
sudo bash -c 'cat >> /etc/security/limits.conf << EOF
elasticsearch soft nofile 65536
elasticsearch hard nofile 65536
elasticsearch soft nproc 4096
elasticsearch hard nproc 4096
EOF'
Elasticsearch Kurulumu ve Yapılandırması
sudo apt install elasticsearch -y
Kurulum tamamlandıktan sonra yapılandırma dosyasını düzenleyelim:
sudo nano /etc/elasticsearch/elasticsearch.yml
Tek node geliştirme/staging ortamı için şu ayarları kullanıyorum:
# /etc/elasticsearch/elasticsearch.yml içeriği
cluster.name: devops-log-center
node.name: elk-node-01
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.type: single-node
# Güvenlik ayarları - üretimde mutlaka aktif olsun
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
JVM heap ayarlarını da düzenleyelim. Sunucu RAM’inin yarısını Elasticsearch’e veriyoruz, ama 32 GB’ı aşmamalı:
# 16 GB RAM'li sunucu için
sudo bash -c 'cat > /etc/elasticsearch/jvm.options.d/heap.options << EOF
-Xms4g
-Xmx4g
EOF'
Servisi başlatıp kontrol edelim:
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
# Elasticsearch şifrelerini otomatik oluştur
sudo /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto
# Durumu kontrol et
curl -k -u elastic:SIFRENIZ https://localhost:9200/_cluster/health?pretty
Buradan dönen yanıtta "status": "green" veya "status": "yellow" görmeniz gerekiyor. Single-node kurulumda yellow normal, paniklemeyın.
Kibana Kurulumu ve Yapılandırması
sudo apt install kibana -y
sudo nano /etc/kibana/kibana.yml
# /etc/kibana/kibana.yml temel ayarlar
server.port: 5601
server.host: "0.0.0.0"
server.name: "devops-log-center"
elasticsearch.hosts: ["https://localhost:9200"]
elasticsearch.username: "kibana_system"
elasticsearch.password: "KIBANA_SISTEM_SIFRESI"
elasticsearch.ssl.verificationMode: none
# Kibana için encryption key - rastgele 32 karakter
xpack.encryptedSavedObjects.encryptionKey: "buraya32karakterrastgelebirstring"
sudo systemctl enable kibana
sudo systemctl start kibana
sudo systemctl status kibana
Kibana başlaması birkaç dakika alabilir. http://SUNUCU_IP:5601 adresine gidip elastic kullanıcısıyla giriş yapabilirsiniz.
Logstash Kurulumu ve Pipeline Yapılandırması
Logstash, ELK’nın en güçlü ve en çok kaynak tüketen parçası. Log parse etme, dönüştürme ve zenginleştirme burada oluyor.
sudo apt install logstash -y
Önce Elasticsearch bağlantısı için kullanıcı oluşturalım:
# Logstash için özel kullanıcı oluştur
curl -k -u elastic:SIFRENIZ -X POST "https://localhost:9200/_security/user/logstash_writer"
-H 'Content-Type: application/json'
-d '{
"password": "logstash_guclu_sifre",
"roles": ["logstash_writer"],
"full_name": "Logstash Writer"
}'
Şimdi asıl pipeline’ı oluşturalım. Ben genellikle input, filter ve output dosyalarını ayrı tutuyorum:
sudo nano /etc/logstash/conf.d/01-beats-input.conf
# Input konfigürasyonu - Filebeat'ten gelen logları dinle
input {
beats {
port => 5044
ssl => false
}
}
sudo nano /etc/logstash/conf.d/10-filter.conf
# Filter konfigürasyonu
filter {
# Nginx access log parse
if [log][file][path] =~ "nginx" {
grok {
match => {
"message" => '%{COMBINEDAPACHELOG}'
}
}
date {
match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
target => "@timestamp"
}
mutate {
convert => { "bytes" => "integer" }
convert => { "response" => "integer" }
}
geoip {
source => "clientip"
target => "geoip"
}
}
# Uygulama logları için JSON parse
if [log][file][path] =~ "app" {
json {
source => "message"
target => "app_log"
}
}
# Ortak temizlik
mutate {
remove_field => ["agent", "ecs", "input", "log"]
}
}
sudo nano /etc/logstash/conf.d/30-output.conf
# Output konfigürasyonu
output {
if "_grokparsefailure" not in [tags] {
elasticsearch {
hosts => ["https://localhost:9200"]
user => "logstash_writer"
password => "logstash_guclu_sifre"
ssl => true
ssl_certificate_verification => false
index => "logs-%{[fields][service]}-%{+YYYY.MM.dd}"
template_name => "logs"
template_overwrite => false
}
} else {
# Parse edilemeyen logları ayrı indekse yaz
elasticsearch {
hosts => ["https://localhost:9200"]
user => "logstash_writer"
password => "logstash_guclu_sifre"
ssl => true
ssl_certificate_verification => false
index => "logs-failed-%{+YYYY.MM.dd}"
}
}
}
Logstash pipeline konfigürasyonunu test edelim:
sudo -u logstash /usr/share/logstash/bin/logstash --path.settings /etc/logstash -t
sudo systemctl enable logstash
sudo systemctl start logstash
Filebeat Kurulumu (Uygulama Sunucularında)
Filebeat’i log göndermek istediğiniz her sunucuya kurmanız gerekiyor. Bu kurulum hem ELK sunucusunda hem de agent olarak çalışacak diğer sunucularda yapılıyor.
# Uygulama sunucusunda
sudo apt install filebeat -y
sudo nano /etc/filebeat/filebeat.yml
# /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
fields:
service: nginx
environment: production
fields_under_root: false
- type: log
enabled: true
paths:
- /var/log/myapp/*.log
fields:
service: myapp
environment: production
multiline.pattern: '^d{4}-d{2}-d{2}'
multiline.negate: true
multiline.match: after
# Logstash'a gönder
output.logstash:
hosts: ["ELK_SUNUCU_IP:5044"]
# Filebeat kendi loglama ayarı
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
sudo systemctl enable filebeat
sudo systemctl start filebeat
# Logların akmaya başladığını kontrol et
sudo filebeat test output
sudo tail -f /var/log/filebeat/filebeat
Index Lifecycle Management (ILM) Kurulumu
Loglar birikiyor, disk doluyor. ILM ile bu sorunu otomatik yönetebilirsiniz. 7 gün sıcak, 14 gün ılık, 30 günden eski logları sil gibi kurallar tanımlayabilirsiniz:
# ILM policy oluştur
curl -k -u elastic:SIFRENIZ -X PUT "https://localhost:9200/_ilm/policy/logs-policy"
-H 'Content-Type: application/json'
-d '{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_primary_shard_size": "10gb",
"max_age": "1d"
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"shrink": {
"number_of_shards": 1
},
"forcemerge": {
"max_num_segments": 1
}
}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
}'
Kibana’da Dashboard Oluşturma
Kibana’ya girdikten sonra ilk yapmanız gereken Index Pattern tanımlamak. Stack Management > Index Patterns yolunu takip edin ve logs-* pattern’ini oluşturun. Timestamp field olarak @timestamp seçin.
Pratik olarak kullandığım ve herkese önereceğim bazı visualizationlar:
- Error Rate Over Time:
response >= 400filtresiyle zaman serisi grafik - Top 10 Endpoints:
request.keywordüzerinde terms aggregation - Response Time P95:
bytesfield üzerinde percentile aggregation - Geo Map: GeoIP verisiyle dünya haritası üzerinde istek dağılımı
- Log Levels Distribution:
level.keywordüzerinde pie chart
Bu visualizationları bir dashboard’a ekleyip kaydedin. Sabah işe geldiğinizde tek bakışta geceyi görebiliyorsunuz.
Alert Kurulumu
Kibana Alerting ile önemli eşiklerde bildirim alabilirsiniz. Stack Management > Rules and Connectors bölümünden ayarlayabilirsiniz. Ben genellikle şu kuralları kurarım:
- 5xx Error Spike: Son 5 dakikada 50’den fazla 500 hatası
- Log Volume Drop: Beklenen log hacminin %80 altına düşmesi (servis çökmüş olabilir)
- Specific Error Pattern: Belirli bir exception mesajının görülmesi
Webhook ile Slack ya da PagerDuty entegrasyonu kurmak çok kolay, Connectors bölümünden birkaç tıklamayla halledebiliyorsunuz.
Performans Optimizasyonu İpuçları
Gerçek hayatta karşılaştığım sorunlar ve çözümleri:
Logstash yavaş çalışıyorsa:
# /etc/logstash/logstash.yml
pipeline.workers: 4 # CPU çekirdeği sayısı kadar
pipeline.batch.size: 1000 # Varsayılan 125, artırmak throughput'u yükseltir
pipeline.batch.delay: 50
queue.type: persisted # Bellekte değil diskte kuyruk - daha güvenli
queue.max_bytes: 4gb
Elasticsearch shard sayısını gözden geçirin:
Günlük indeks oluşturuyorsanız ve çok fazla shard birikiyor ise bu ciddi performans sorunlarına yol açar. Küçük ortamlar için tek bir shard yeterli olabilir:
# Index template ile varsayılan shard sayısını ayarla
curl -k -u elastic:SIFRENIZ -X PUT "https://localhost:9200/_index_template/logs-template"
-H 'Content-Type: application/json'
-d '{
"index_patterns": ["logs-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"index.lifecycle.name": "logs-policy"
}
}
}'
Filebeat backpressure sorunu:
Logstash meşgul olduğunda Filebeat kuyruğa alır. Eğer çok fazla log üretiyorsanız:
# filebeat.yml içine ekle
queue.mem:
events: 4096
flush.min_events: 512
flush.timeout: 5s
Güvenlik ve Erişim Kontrolü
Üretime gitmeden önce mutlaka yapmanız gerekenler:
- Elasticsearch’e doğrudan dışarıdan erişim kapatılmalı, Kibana önüne nginx reverse proxy koyun
- Kibana için SSL sertifikası kurun
- Role-based access control ile farklı ekiplere farklı indekslere erişim verin
- Filebeat trafiği için mutual TLS düşünün
Nginx ile Kibana önüne basit bir reverse proxy:
sudo nano /etc/nginx/sites-available/kibana
# İçerik:
server {
listen 443 ssl;
server_name kibana.sirketiniz.com;
ssl_certificate /etc/ssl/kibana.crt;
ssl_certificate_key /etc/ssl/kibana.key;
auth_basic "ELK Log Center";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://localhost:5601;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Sonuç
ELK Stack kurulumu ilk bakışta karmaşık görünebilir ama adımları tek tek izlediğinizde anlaşılır bir yapısı var. Bu yazıda anlattığım kurulumla birkaç saatte çalışan bir log merkezi elde edebilirsiniz.
Birkaç hafta kullandıktan sonra şunu göreceksiniz: Daha önce “hangi sunucuda ne oldu?” diye SSH ile sunucu sunucu dolaştığınız durumları artık Kibana’da birkaç sorguyla çözüyorsunuz. Bir incident sırasında saatlerce log grep’lerken, artık dakikalar içinde root cause’a ulaşabiliyorsunuz.
Sonraki adım olarak Metricbeat ile sistem metriklerini de (CPU, RAM, disk I/O) aynı Elasticsearch cluster’a atmayı ve APM Server ile uygulama performance monitoring eklemeyi öneririm. O noktada gerçekten her şeyi tek bir camdan gördüğünüz bir observability platformuna kavuşmuş olursunuz.
Stack’i büyütürken en kritik nokta Elasticsearch cluster’ının kapasitesini doğru planlamak. Log hacminizi ölçün, retention policy’nizi belirleyin, disk hesabını yapın, sonra node sayısını ve shard stratejisini buna göre tasarlayın. Bu planlamayı baştan yapmayan ortamlarda “Elasticsearch doldu, Kibana açılmıyor” türünden krizlerle karşılaşılıyor, söyleyelim.
