Elasticsearch ile Yüksek Erişilebilirlik Kurulumu

Üretim ortamında Elasticsearch kümesi kurmak, “apt install elasticsearch” yapıp servisi başlatmaktan çok daha fazlasını gerektiriyor. Tek node üzerinde çalışan bir Elasticsearch kurulumu, hem veri kaybı riski hem de hizmet kesintisi açısından ciddi tehditler barındırıyor. Bu yazıda, gerçek bir üretim ortamı için yüksek erişilebilirlik (HA) prensipleri doğrultusunda Elasticsearch kümesi nasıl kurulur, adım adım ele alacağız.

Mimari Genel Bakış

Elasticsearch’ün HA mimarisi üç temel kavram üzerine inşa edilmiş: master node, data node ve coordinating node. Küçük bir üretim ortamı için minimum 3 master-eligible node önerisi, split-brain senaryosunu önlemek amacıyla “quorum” mantığından geliyor.

Bizim kuracağımız ortamda şu yapı olacak:

  • 3 adet dedicated master node: Küme yönetimi, shard allocation, node durumu takibi
  • 3 adet data node: Gerçek verinin depolandığı ve sorguların işlendiği node’lar
  • 1 adet coordinating node: Gelen istekleri ilgili data node’lara yönlendiren, istemci tarafındaki yük dengeleyici

Tüm node’lar Ubuntu 22.04 LTS üzerinde çalışacak ve Elasticsearch 8.x kullanacağız.

Ön Gereksinimler ve Sistem Hazırlığı

Her node üzerinde yapılması gereken hazırlıklar var. Bu adımları atlamak, ilerleyen süreçte performans sorunları ve garip davranışlara yol açıyor.

JVM ve Sistem Ayarları

Elasticsearch, JVM üzerinde çalışıyor ve heap memory yönetimi kritik önem taşıyor. Önce tüm node’larda sistem limitlerini ayarlayalım:

# /etc/sysctl.conf dosyasına ekle
cat >> /etc/sysctl.conf << 'EOF'
vm.max_map_count=262144
vm.swappiness=1
net.core.somaxconn=65535
net.ipv4.tcp_max_syn_backlog=65535
EOF

sysctl -p

# Kalıcı ulimit ayarları
cat >> /etc/security/limits.conf << 'EOF'
elasticsearch soft nofile 65536
elasticsearch hard nofile 65536
elasticsearch soft nproc 4096
elasticsearch hard nproc 4096
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited
EOF

vm.max_map_count ayarı, Elasticsearch’ün mmapped dosya sayısını arttırması için şart. Bu değeri set etmeden Elasticsearch başlamayı bile reddediyor. vm.swappiness=1 ise heap memory’nin swap’a yazılmasını neredeyse tamamen engelliyor; Elasticsearch için swap, ciddi gecikme sorunlarına neden oluyor.

Elasticsearch Kurulumu

GPG key ve repo ekleme işlemlerini yapalım:

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

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

# Kur
apt update && apt install -y elasticsearch

# Otomatik başlatmayı şimdilik devre dışı bırak, önce config yapacağız
systemctl disable elasticsearch

TLS/SSL Sertifika Oluşturma

Elasticsearch 8.x’te güvenlik varsayılan olarak açık geliyor. Küme içi iletişim için TLS zorunlu. Sertifikaları ilk master node üzerinde oluşturup diğer node’lara dağıtacağız.

# CA ve node sertifikalarını oluştur (master01 üzerinde)
cd /usr/share/elasticsearch

# Önce CA oluştur
bin/elasticsearch-certutil ca 
  --out /etc/elasticsearch/certs/elastic-stack-ca.p12 
  --pass "GucluBirSifre123!"

# Tüm node'lar için sertifika üret
bin/elasticsearch-certutil cert 
  --ca /etc/elasticsearch/certs/elastic-stack-ca.p12 
  --ca-pass "GucluBirSifre123!" 
  --out /etc/elasticsearch/certs/elastic-certificates.p12 
  --pass "NodeSertifikaSifresi!"

# HTTP katmanı için sertifika (bu adım interaktif)
bin/elasticsearch-certutil http

# Sertifika izinlerini ayarla
chown -R elasticsearch:elasticsearch /etc/elasticsearch/certs/
chmod 640 /etc/elasticsearch/certs/*.p12

Oluşturulan sertifikaları tüm node’lara kopyalayalım:

# SCP ile diğer node'lara kopyala
for node in master02 master03 data01 data02 data03 coordinating01; do
  ssh $node "mkdir -p /etc/elasticsearch/certs"
  scp /etc/elasticsearch/certs/*.p12 $node:/etc/elasticsearch/certs/
  ssh $node "chown -R elasticsearch:elasticsearch /etc/elasticsearch/certs/ && 
             chmod 640 /etc/elasticsearch/certs/*.p12"
done

Master Node Konfigürasyonu

Her master node için /etc/elasticsearch/elasticsearch.yml dosyasını yapılandıralım. Üç master node birbirinden farklı node.name değeri alacak, geri kalan kısımlar benzer olacak.

master01 için konfigürasyon:

# /etc/elasticsearch/elasticsearch.yml - master01

cluster.name: production-cluster
node.name: master01
node.roles: [master]

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

# Discovery - tüm master node'ların IP'leri
discovery.seed_hosts:
  - "192.168.1.10:9300"
  - "192.168.1.11:9300"
  - "192.168.1.12:9300"

# İlk kurulumda quorum için master node listesi
cluster.initial_master_nodes:
  - "master01"
  - "master02"
  - "master03"

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

# TLS - Transport katmanı
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12

# TLS - HTTP katmanı
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/http.p12

# Güvenlik
xpack.security.enabled: true

# Master node'da veri tutmuyoruz
node.data: false
node.ingest: false

cluster.initial_master_nodes parametresi sadece ilk cluster oluşturma sırasında kullanılıyor. Küme bir kez kurulup çalışmaya başladıktan sonra bu satırı kaldırmak iyi pratik, yoksa node yeniden başlatılırken sorun çıkarabiliyor.

Data Node Konfigürasyonu

Data node’lar gerçek indexlerin ve shard’ların yaşadığı yerler. Bu node’lar için daha fazla heap memory ve disk I/O optimizasyonu gerekiyor.

# /etc/elasticsearch/elasticsearch.yml - data01

cluster.name: production-cluster
node.name: data01
node.roles: [data, ingest]

network.host: 0.0.0.0
http.port: 9200
transport.port: 9300

discovery.seed_hosts:
  - "192.168.1.10:9300"
  - "192.168.1.11:9300"
  - "192.168.1.12:9300"

# Data node'da initial_master_nodes YOK
# Bu node kümeye sonradan katılıyor

path.data:
  - /data1/elasticsearch
  - /data2/elasticsearch
path.logs: /var/log/elasticsearch

# Data node'a özel ayarlar
indices.memory.index_buffer_size: 30%
indices.fielddata.cache.size: 20%

# TLS ayarları (master ile aynı)
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/http.p12
xpack.security.enabled: true

Data node’larda path.data için birden fazla disk yolu verdiğimize dikkat edin. Bu sayede Elasticsearch shard’ları birden fazla disk üzerine dağıtabiliyor, I/O performansı önemli ölçüde artıyor.

JVM Heap Boyutu Ayarı

Her node için JVM heap boyutunu jvm.options.d/ altında ayarla. Genel kural: toplam RAM’in %50’si ama asla 31GB’ı geçme (compressed OOPs sınırı).

# data01 üzerinde - 64GB RAM varsayımıyla
cat > /etc/elasticsearch/jvm.options.d/heap.options << 'EOF'
-Xms31g
-Xmx31g
EOF

# Master node'lar için daha az heap yeterli - 16GB RAM varsayımı
cat > /etc/elasticsearch/jvm.options.d/heap.options << 'EOF'
-Xms8g
-Xmx8g
EOF

Keystore ile Şifre Yönetimi

Sertifika şifrelerini config dosyasına düz metin olarak yazmak yerine Elasticsearch keystore kullanıyoruz:

# Her node'da çalıştır
/usr/share/elasticsearch/bin/elasticsearch-keystore create

# Transport SSL şifresi
echo "NodeSertifikaSifresi!" | 
  /usr/share/elasticsearch/bin/elasticsearch-keystore add 
  --stdin xpack.security.transport.ssl.keystore.secure_password

echo "NodeSertifikaSifresi!" | 
  /usr/share/elasticsearch/bin/elasticsearch-keystore add 
  --stdin xpack.security.transport.ssl.truststore.secure_password

# HTTP SSL şifresi
echo "HttpSertifikaSifresi!" | 
  /usr/share/elasticsearch/bin/elasticsearch-keystore add 
  --stdin xpack.security.http.ssl.keystore.secure_password

Kümeyi Başlatma ve İlk Yapılandırma

Sıralı başlatma önemli. Önce master node’ları, ardından data node’larını ve en son coordinating node’u başlatıyoruz:

# Master node'larda sırayla
systemctl start elasticsearch
systemctl enable elasticsearch

# Logları takip et
journalctl -u elasticsearch -f

İlk master node çalışmaya başladıktan sonra elastic kullanıcısının şifresini ayarlayalım:

# master01 üzerinde
/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic

# Kibana_system kullanıcısı için
/usr/share/elasticsearch/bin/elasticsearch-reset-password -u kibana_system

# Küme durumunu kontrol et
curl -k -u elastic:SifreniziGirin 
  https://localhost:9200/_cluster/health?pretty

Sağlıklı bir küme şu çıktıyı vermeli:

{
  "cluster_name": "production-cluster",
  "status": "green",
  "number_of_nodes": 7,
  "number_of_data_nodes": 3,
  "active_primary_shards": 0,
  "active_shards": 0
}

Index Template ve Shard Stratejisi

Yüksek erişilebilirlik için index oluşturma stratejisi de kritik. Her index en az 1 replica shard içermeli:

# Production log index template oluştur
curl -k -u elastic:SifreniziGirin 
  -X PUT "https://localhost:9200/_index_template/production-logs" 
  -H 'Content-Type: application/json' 
  -d '{
    "index_patterns": ["logs-*", "app-*"],
    "template": {
      "settings": {
        "number_of_shards": 3,
        "number_of_replicas": 1,
        "routing.allocation.total_shards_per_node": 3,
        "index.refresh_interval": "30s",
        "index.translog.durability": "request",
        "index.unassigned.node_left.delayed_timeout": "5m"
      },
      "mappings": {
        "dynamic": "strict",
        "_source": {
          "enabled": true
        }
      }
    },
    "priority": 100
  }'

index.unassigned.node_left.delayed_timeout parametresi çok önemli. Bir data node geçici olarak düşerse Elasticsearch hemen shard’ları redistribute etmeye başlamıyor, 5 dakika bekliyor. Bu, gereksiz yeniden dengeleme operasyonlarını önlüyor.

Shard Allocation Awareness

Data center veya rack farkındalığı eklemek, HA açısından kritik bir adım. Farklı rack’lerdeki node’lara replica shard’lar dağıtılırsa, bir rack tamamen çökse bile veri kaybı yaşanmıyor:

# data01 ve data02 - rack1'de
# elasticsearch.yml'e ekle
node.attr.rack: rack1
node.attr.zone: zone-a

# data03 - rack2'de  
node.attr.rack: rack2
node.attr.zone: zone-b

# Cluster ayarında awareness'ı aktif et
curl -k -u elastic:SifreniziGirin 
  -X PUT "https://localhost:9200/_cluster/settings" 
  -H 'Content-Type: application/json' 
  -d '{
    "persistent": {
      "cluster.routing.allocation.awareness.attributes": "rack",
      "cluster.routing.allocation.awareness.force.rack.values": "rack1,rack2"
    }
  }'

Snapshot ile Yedekleme

HA tek başına yeterli değil; snapshot mekanizması olmadan gerçek bir disaster recovery stratejisi kurulamıyor. S3 uyumlu depolama (MinIO veya AWS S3) üzerine snapshot reposu tanımlayalım:

# S3 plugin kurulumu (tüm node'larda)
/usr/share/elasticsearch/bin/elasticsearch-plugin install repository-s3

# S3 credentials keystore'a ekle
echo "AKIAIOSFODNN7EXAMPLE" | 
  /usr/share/elasticsearch/bin/elasticsearch-keystore add 
  --stdin s3.client.default.access_key

echo "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | 
  /usr/share/elasticsearch/bin/elasticsearch-keystore add 
  --stdin s3.client.default.secret_key

# Servisleri yeniden başlat
systemctl restart elasticsearch

# Snapshot repository tanımla
curl -k -u elastic:SifreniziGirin 
  -X PUT "https://localhost:9200/_snapshot/s3-backup" 
  -H 'Content-Type: application/json' 
  -d '{
    "type": "s3",
    "settings": {
      "bucket": "elasticsearch-backups",
      "region": "eu-west-1",
      "base_path": "production-cluster",
      "compress": true,
      "chunk_size": "1gb"
    }
  }'

# Otomatik snapshot policy oluştur
curl -k -u elastic:SifreniziGirin 
  -X PUT "https://localhost:9200/_slm/policy/daily-snapshots" 
  -H 'Content-Type: application/json' 
  -d '{
    "schedule": "0 30 2 * * ?",
    "name": "<daily-snap-{now/d}>",
    "repository": "s3-backup",
    "config": {
      "indices": ["*"],
      "ignore_unavailable": false,
      "include_global_state": true
    },
    "retention": {
      "expire_after": "30d",
      "min_count": 7,
      "max_count": 30
    }
  }'

İzleme ve Alarm Kurulumu

Küme sağlığını takip etmek için basit bir bash script yazalım. Bu script cron ile çalışıp Slack veya e-posta bildirimi gönderebilir:

#!/bin/bash
# /usr/local/bin/es-health-check.sh

ES_HOST="https://localhost:9200"
ES_USER="elastic"
ES_PASS="SifreniziGirin"
SLACK_WEBHOOK="https://hooks.slack.com/services/XXXXX"

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

STATUS=$(echo $HEALTH | awk '{print $1}')
NODES=$(echo $HEALTH | awk '{print $2}')
UNASSIGNED=$(echo $HEALTH | awk '{print $3}')

if [ "$STATUS" != "green" ] || [ "$UNASSIGNED" -gt "0" ]; then
  MSG="UYARI: Elasticsearch durumu=$STATUS, node_sayisi=$NODES, atanmamis_shard=$UNASSIGNED"
  curl -s -X POST "$SLACK_WEBHOOK" 
    -H 'Content-type: application/json' 
    --data "{"text":"$MSG"}"
fi

# Disk kullanimi kontrol
curl -sk -u $ES_USER:$ES_PASS 
  "$ES_HOST/_cat/allocation?v&h=node,disk.used_percent" | 
  awk 'NR>1 {if ($2+0 > 80) print "DISK UYARI: "$1" - %"$2}'
# Crontab'a ekle
chmod +x /usr/local/bin/es-health-check.sh
echo "*/5 * * * * root /usr/local/bin/es-health-check.sh >> /var/log/es-health.log 2>&1" 
  >> /etc/cron.d/elasticsearch-health

Yaygın Sorunlar ve Çözümleri

Gerçek ortamlarda en sık karşılaşılan durumlar:

Split-Brain Durumu: minimum_master_nodes hesabı yanlış yapılırsa iki ayrı küme oluşabilir. Elasticsearch 7.x’ten itibaren bu parametre kaldırıldı, yerine cluster.initial_master_nodes ve quorum tabanlı seçim geldi. 3 master node ile bu risk büyük ölçüde ortadan kalkıyor.

Red Cluster Durumu: Unassigned shard’lar genellikle disk doluluk sınırı veya node kaybı nedeniyle oluşuyor. Hızlı müdahale için:

  • disk.watermark.low (85%): Yeni shard allocation durur
  • disk.watermark.high (90%): Mevcut shard’lar taşınmaya başlar
  • disk.watermark.flood_stage (95%): Index read-only moda geçer

JVM GC Basıncı: Heap %75’i geçince GC pause süreleri artıyor. _nodes/stats API üzerinden jvm.gc.collectors metriklerini takip etmek önemli.

Rolling Restart ve Güncelleme

Kümeyi durdurmadan güncelleme yapmak için rolling restart prosedürü uygulanıyor:

# 1. Shard allocation'ı geçici olarak durdur
curl -k -u elastic:SifreniziGirin 
  -X PUT "https://localhost:9200/_cluster/settings" 
  -H 'Content-Type: application/json' 
  -d '{"persistent": {"cluster.routing.allocation.enable": "primaries"}}'

# 2. Hedef node'da flush yap
curl -k -u elastic:SifreniziGirin 
  -X POST "https://localhost:9200/_flush"

# 3. Node'u durdur, güncelle, başlat
systemctl stop elasticsearch
apt install -y elasticsearch
systemctl start elasticsearch

# 4. Node'un kümeye katıldığını doğrula
curl -k -u elastic:SifreniziGirin 
  "https://localhost:9200/_cat/nodes?v"

# 5. Allocation'ı tekrar aktif et
curl -k -u elastic:SifreniziGirin 
  -X PUT "https://localhost:9200/_cluster/settings" 
  -H 'Content-Type: application/json' 
  -d '{"persistent": {"cluster.routing.allocation.enable": null}}'

Her node için bu adımları tekrarla. Bir node tamamen recover olmadan bir sonrakine geçme.

Sonuç

Elasticsearch HA kurulumu, doğru yapılandırıldığında hem veri güvenliği hem de hizmet sürekliliği açısından oldukça sağlam bir altyapı sunuyor. Bu yazıda ele aldığımız mimari kararlar; dedicated master node’lar, shard allocation awareness, snapshot otomasyonu ve rolling restart prosedürü, gerçek üretim ortamlarında kanıtlanmış yaklaşımlar.

Özellikle vurgulamak istediğim birkaç nokta var: cluster.initial_master_nodes parametresini küme kurulduktan sonra kaldırmayı unutma, heap boyutunu asla 31GB üzerine çıkarma ve disk watermark değerlerini varsayılanda bırakmayın. Küçük görünen bu detaylar, gece yarısı alarm geldiğinde hayat kurtarıcı oluyor.

Bir sonraki adım olarak Kibana üzerinden Stack Monitoring kurulumu ve ILM (Index Lifecycle Management) politikaları ile eski indexlerin otomatik yönetimi konularına bakabilirsin. Özellikle log yoğun ortamlarda ILM olmadan disk yönetimi çok zorlaşıyor.

Bir yanıt yazın

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