Docker - ELK Stack

Cihat Topsakal
6 min readDec 24, 2020

Merhaba bügün sizlerle elasticsearch’e adım atacak ve bu bölümümüzde;

  1. Elasticsearch, Logstash ve Kibana Hakkında bilgiler edineceğiz.
  2. Docker ile Elasticsearch, Logstash, Kibana kurulumu yapacağız.
ELK

Elasticsearch: Java ile yazılmış açık kaynak kodlu text arama ve analiz motorudur.

Veri saklama biçimi ilişkisel değil document oriented’dır. İndexleme mantığı olduğundan çok hızlıdır. Dökümanları JSON formatında indexler.

Elasticsearch cluster yapısına sahiptir. Ve her node üzerinde Elasticsearch çalışır. Veriler Apache Lucene alt yapısı ile indexlenir.

Kibana: Elasticsearch için hazırlanmış zengin raporlar ve görsel çıktılar almamızı sağlayan ve ayrıca loglarımızı anlık olarak takip edeceğimiz üründür.

Logstash: Logların toplayan işleyen ve Elasticsearch’e aktaran bir üründür.

Öncelikle Elasticsearch hakkında biraz daha detaylı bilgiler edinelim. Elasticsearch verileri nasıl saklıyor. Cluster yapısı var ama arka tarafta neler oluyor? Kısaca bu konulara bakalım.

Cluster

Bir index’i okumak ve yazmak için birbiriyle iletişim kuran node’lar kümesidir.

Node

Bir node bir cluster’a ait olan çalışan bir elasticsearch örneğidir. Test amacıyla bir sunucuda birden fazla node kaldırabiliriz. Ama genellikle tek bir sunucu üzerinde tek bir node olmalıdır.

Shard

Elasticsearch dağıtılmış mimarisi nedeniyle ölçeklendirilebilirdir. Ölçeklendirmeyi sağlayan yapılardan biriside shard’lardır. Shard’a neden ihitiyaç duyarız? İndex’in tek bir node donanımının sınırlarını aştığı durumlarda shard yardımımıza koşar. Indexleri sharding adlı küçük parçalara bölerek bu sorunu çözer. Shard’lar kendi içinde bağımsız ve işlevseldir. Bir index parçalandığınd, o indexdeki belirli bir belge sadece bir shard’a depolanır. Cluster içerisindeki herhangi bir node’a depolanabilir.

index shard ilişkisi

Replica

Elasticsearch Donanım ve yazılım hatalarına karşın shard’ların kopyalanmasını destekler. Yani shard’ları kopyalar. Replica ile nodeların ve shard’ların başarısız olma durumunda kullanabilirliği sağlamaktadır. Çoğlatılan parçalara primary shard, oluşan kopyalara replica shard denir. Replica shard ve primary shard’lar asla aynı node üzerinde bulunmaz.

cluster

Peki Replica shardlar nasıl güncel kalıyor?

Elasticsearch’e “userEmail” alanı eklediğimizi düşünelim. Eklenen veri 1 Primary shard ve 3 replica shard’a eklenecek. Öncelikle istemciden isteği primary shard alır kendini günceller. Daha sonra senkron olarak 3replica shard’a aynı işlem talebinde bulunur. Replica shardlar “userEmail” eklemesini tamamlar ve primary shard’a sonucu döndürür. Ardından istemciye primary shard sonucu dönerek replica shardlarında güncel kalmasını sağlamaktadır.

Örnek bir search cevabını inceleyelim.

Örnek bir seacrh sonuc

Index: JSON belgelerinin optimize edilmiş bir koleksiyonudur. Bir index, bir veya daha fazla primary shard ile eşleşen ve sıfır veya daha fazla replica shard’a sahip olabilen mantıksal bir ad alanıdır.

Type: Dökümanın türünü temsil eder.

Document: Elasticsearch’e eklenen her veri Json olarak saklanır. Document saklanan her bir Json nesnesine denir. Relation Database’de bulunan table’daki “row” gibi düşünülebilir. Her bir document bir index’de saklanır ve type’ı ve Id’si vardır.

Field: İlişkisel bir veritabanındaki tablodaki bir sütuna benzer.

Score: Varsayılan olarak Elasticsearch, eşleşen arama sonuçlarını , her belgenin bir sorguyla ne kadar iyi eşleştiğini ölçer puana göre sıralar. Yani sonucun sorgu parametreleriyle ne kadar iyi eşleştiğini gösterir.

Source: Json belgesi source alanında depolanır. Ve tüm arama isteklerinde döndürülecektir.

Elasticsearch ve Relational Database Kavramları

Elasticsearch DSL Sorgusu

Elasticsearch’de JSON tabanlı sorgu kullanılarak arama yapılır.

  1. Leaf Query Clauses: Belirli bir alanda belirli bir değeri arar. Bu sorgular tekil olarak kullanılabilir. Match, Term ve Range buna örnektir.
  2. Compound Query Clauses: Bu sorgular, istenen bilgileri çıkarmak için leaf query ve diğer bileşik sorguların bir kombinasyonudur.

Match: Full-text arama yapar. Aramada bulunan kelimelerden herhangi biri varsa eşleşir. Case sensitive değildir.

{
"query": {
"match": {
"message": {
"query": "full-text arama sorgusu"
}
}
}
}

Multi-Match: Eşleşme sorgusunu birden fazla alanda yapar.

{
"query": {
"multi_match" : {
"query": "subject ve message alanlarında ara",
"fields": [ "subject", "message" ]
}
}
}

Match-All: Tüm içeriği döndürür.

{
"query": {
"multi_all" : {}
}
}

Term: Case sensitive’dir. Kesin bir değere göre belgeleri bulmak istediğimizde kullanırız. Full-Text aramalarında kullanılması tavsiye edilmez. Sebebi ise tam eşleştirme yaptığı için tam sonucu döndüremeyebilir.

{
"query": {
"term": {
"user.id": {
"value": "cihat",
"boost": 1.0
}
}
}
}

Range: Arama yapılan alanda belirtilen aralıktaki sonuçları döner.

{
"query": {
"range": {
"age": {
"gte": 10, // Büyük eşittir.
"lte": 20 // Küçük eşittir.
}
}
}
}

Docker Engine kurulu hostunuzun var olduğunu varsayarak aşağıdaki proje structure’ı uyguluyoruz.

elasticsearch.yml

docker-compose.yml

Docker volume kabiliyetini kullanarak elasticsearch içerisinde bulunan config altındaki elasticsearch.yml dosyasını kendi proje folder’ımızda bulunan elasticsearch.yml ile ezeceğiz.

Docker Volume

Docker der ki; Volume’ler Docker kapsayıcıları tarafından oluşturulan ve kullanılan, verileri kalıcı hale getirmek için kullanılan mekanizmadır.

Volume container içerisinde boş veya dolu dizine mount edilirse ne oluyor?

  • Eğer bir volume mount edildiğinde dizin mevcut değilse bu dizini yaratır. Ve volume içerisinde hangi dosyalar var ise o dizin içerisinde de o dosyaları görürüz.
  • Eğer bir volume image içerisinde mevcut bir dizine mount edilirse;
  1. Dizin boş ise o anda volume içerisinde hangi dosyalar var ise o dosyaları görürüz.
  2. Dizin dolu ve volume boş ise bu sefer klasör içerindeki dosyalar volume içerisinde kopyalanır.
  3. Dizinde dosya var yada yok volume boş değilse bu sefer o dizin içerisinde volume içerisinde ne varsa onu görürüz.

Docker Volume’un bu kabiliyetini kullanarak kendi yazdığımız Proje folderındaki elasticsearch.yml dosyamızı kullandık.

kibana.yml

logstash.conf

logstash.yml

Docker compose’u güncelliyoruz. Compose üzerinde bridge network tanımlıyoruz.

Bridge Network

Varsayılan driver’dır. Her docker kurulu host üzerinde bridger diriver ile yaratılmış “Bridge” adında network bulunur ve container yaratılırken aksi belirtilmediği taktirde bu networke bağlanır.

  • Aynı bridge networke bağlı container’lar birbirleriyle direk haberleşebilirler.
  • Kullanıcı tanımlı bridge networkler birbirleri ile isim ile erişim sağlayabilir. Dns çözümü sağlamaktadır.
  • Containerlar çalışır durumdayken de kullanıcı tanınlı bridge network’e bağlanabilir ve bağlantıyı kesebilirler.

docker-compose.yml

Proje Folder’ında Terminal açıp “docker-compose up” ile Container’ları ayağa kaldırıyoruz.

Elasticsearch için “http://localhost:9200/” ziyaret ediyoruz. Karşımıza aşağıdaki sonuç çıkar ise elasticsearch’ü kullanmaya başlayabiliriz. Bu ekranda elasticsearch, lucene versiyonlarını ayrıca cluster hakkında kısa bilgileri bulabiliriz.

Kibana için “http://localhost:5601/” ziyaret ediyoruz. Karşımıza çıkan ekran ile kibana dünyasına ilk adımı atmış oluyoruz.

Elasticsearch, Kibana ve Logstash’i Containerlar yardımı ile ayağa kaldırdık. Şimdi Elasticsearch için bazı komutları ve çıktılarını inceleyelim. Daha sonra bu komutları SpringData ile gerçekliyor olacağız.

Elasticsearch Rest API

ElasticStack verileri entegre etmek, sorgulamak, yönetmek ve cluster, node, indexlerimiz hakkında bilgiler almamız için Rest API’lar sağlamaktadır.

İndex Eklemek

curl -X PUT http://localhost:9200/index-name

İndexleri listelemek

curl -X GET 'http://localhost:9200/_cat/indices?v'
index list

Yukarıda Rest API’ın bize dönmüş olduğu cevabı görüyoruz. Burada health bölümü altındaki renklendirmelerin karşılığını altta bulunan görsel açıklamaktadır.

Veri Eklemek

curl -XPUT --header 'Content-Type: application/json' http://localhost:9200/index-name/_doc/1 -d '{"orderMode" : "Delivery"}'

Url ile sorgulama

curl -X GET http://localhost:9200/index-name/_search?q=orderMode:Delivery

İndexteki tüm Dökümanları Listemek

curl -X GET 'http://localhost:9200/index-name/_search'

İndex’i silmek

curl -X DELETE 'http://localhost:9200/indexname'

--

--