Kibana Query Language (KQL) nedir?

27 Haz

Kibana Query Language (KQL), Kibana uygulamasında kullanılan bir sorgulama dilidir. Bu dil, Kibana uygulamasındaki Discover bölümünün en temel bileşenidir. KQL sayesinde Elasticsearch üzerindeki index’lerde basit bir şekilde arama işlemleri gerçekleştirilebilmektedir. Yazılan basit sorgular, arka planda otomatik olarak Elasticsearch DLS query formatına dönüştürülerek aramalar yapılmaktadır.

Kibana Query yazma penceresi

Örnek KQL kodu:

product.price : 200

Dönüştürülmüş Elasticsearch query kodu:

 "query": {
   "bool": {
	"filter": [
	  {
		"bool": {
		  "should": [
			{
			  "match": {
				"product.price": "200"
			  }
			}
		  ]
		}
	  }
	]
  }
}

Karmaşık Elasticsearch DSL sorguları tek bir satırda basit bir şekilde KQL ile gerçekleştirilebilmektedir.

KQL free text search

Her bir kelimeyi ayrı ayrı arayıp bulmak için kelimeler arasında boşluklar bırakılarak yapılan aramalardır. Örneğin içinde apple veya banana geçen dokümanları elde etmek için aşağıdaki gibi aralarında boşluklar bırakarak arandığında ilgili Elasticsearch DSL sorgusu üretilecektir. Free text search, elastic tarafında multi_match türünde bir filter uygular. Dokümandaki tüm alanlarda ilgili kayıtların aranması sağlanır. Bunu sağlayan “best_fields” parametresidir.

apple banana
"query": {
  "bool": {
	"filter": [
	  {
		"multi_match": {
		  "type": "best_fields",
		  "query": "apple banana",
		  "lenient": true
		}
	  }
	]
  }
}

KQL free text – phrase search

Bu tür aramalarda, ilgili metin tırnak içinde aratılarak ilgili kelime veya cümle ile tam eşleşen dokümanlar aranmaktadır. Bunu sağlayan “phrase” parametresidir. Örneğin “apple banana” araması yapıldığında, doküman alanlarında aranan metni aynı şekilde arar. apple ve banan şeklinde ayırıp aramaz.

"apple banana"
"query": {
  "bool": {
	"filter": [
	  {
		"multi_match": {
		  "type": "phrase",
		  "query": "apple banana",
		  "lenient": true
		}
	  }
	]
  }
}

KQL field level search

Bu aramalarda arama kutusuna <field name><operator><value> şeklinde giriş yapılır.

product.name: computer

Bu aramalarda; “:” operatörü eşittir anlamına gelmektedir. Bu aramanın DSl sorgusu aşağıdaki gibidir.

"query": {
  "match": {
	"product.name": "computer"
  }
}
Range Operatörleri:    <      >      <=      >=

Bu operatörlerin DSL dönüşümü aşağıdaki gibidir.

product.price < 2500 
"query": {
  "range": {
	"product.name": { "lt": 250 }
  }
}

KQL boolean operators

product.size >= 100 and product.size <= 500
"query": {
  "bool": {
	"filter": [
	  {
		"range": {
		  "product.size ": { "gte": 100 }
		}
	  },
	  {
		"range": {
		  "product.size ": { "lte": 500 }
		}
	  }
	]
  }
}
product.size: 100 or product.size: 500
"query": {
  "bool": {
	"should": [
	  {
		"match": {
		  "product.size ": 100
		}
	  },
	  {
		"match": {
		  "product.size ": 500 
		}
	  }
	]
  }
}

Boolean kısa yazım şekli

product.size: ( 100 or 500 )

KQL boolean operator grup

Sorgulamalarda parantezlar yardımı ile boolean ifadeler gruplanabilir.

product.price: 1500 and (product.size: M or Product.size: L)

KQL boolean ters

İfadelerin başına “not” yazılarak ters mantıksal işlem yapılabilir. Örneğin kategorisi “computers” olmayanlar için sorgu:

not product.category: computers

Gruplanmış ifadelerde de ters mantıksal işlemler kulanılabilir.

product.price: 1500 and not (product.size: M or Product.size: L)

Wildcard (*) ifadesiyle ilgili alana sahip dokümanların aranması

İlgili alana sahip olan dokümanların aranması için aşağıdaki sorgu kullanılabilir. Örneğin product.category alanını içeren dokümanları aramak için:

product.category: *
"query": {
  "exist": {
	"field": "product.name"
  }
}

Wildcard (*) ifadesiyle ilgili alana ve değere sahip dokümanların aranması

product.category: phones*
"query": {
  "query_string": {
	"fields": ["product.name"],
        "query": "phones*"
  }
}

Elasticsearch null value

24 Şub

Elasticsearch üzerinde null değerler index üzerine eklenemez ve aranamaz. Yani property değeri null olan kayıtları getirmek için bir sorgu yazdığınızda doğru cevap alınamaz. Bir alan null olarak girildiğinde, o alanın değeri yokmuş gibi değerlendirilir. Bir alan boş bir dizi olarak girildiğinde de yokmuş gibi değerlendirilir.

Örneğin, aşağıdaki sorguda, name değeri null olan kayıtlar alınamaz.

GET products-idx/_search
{
  "query": {
    "term": {
      "name": null 
    }
  }
}

Bu gibi durumlarda, index mapping oluşturulurken, alana ait property ayarlarında null_value parametresi ile null yerine bir değer atanır.

PUT products-idx
{
  "mappings": {
    "properties": {
      "name": {
        "type": "keyword",
        "null_value": "NULL" 
      }
    }
  }
}

Burada, null olarak gelen name değerleri, “NULL” ile değiştirilmiştir. Bu sayede NULL şeklinde arama yapmak mümkün hale gelmektedir. Aşağıdaki şekilde yeni değerler eklendiğinde;

PUT products-idx/_doc/1
{
  "name": null
}

PUT products-idx/_doc/1
{
  "name": []
}

Artık aşağıdaki gibi arama yapılabilmektedir.

GET products-idx/_search
{
  "query": {
    "term": {
      "name": "NULL" 
    }
  }
}

Boş diziler null değere sahip olmadığı için “NULL” ile değiştirilmez. Bu sorgunun sonucunda 1 numaralı doküman elde edilir ancak 2 numaralı doküman elde edilemez.

Not: null_value değeri alan veri tipi ile uygun olmalıdır. Örneğin long tipinde bir alana string tipinde null_value değeri atanamaz.

Not: null_value yalnızca verilerin index’e alınma şeklini etkiler, _source dokümanını değiştirmez.

PostgreSQL Database ve Table Boyutları

21 Şub

PostgreSQL veri tabanında zamanla veri boyutları artar ve disklerdeki boş alanlar azalır. Bakım yapılmak istendiğinde öncelikle tüketilen kaynaklar öğrenilmelidir.

  • Veritabanı disk üzerinde ne kadar yer kaplıyor.
  • Tablola disk üzerinde ne kadar yer kaplıyor.

Veritabanı toplam boyutunu veren sorgu;

select pg_size_pretty(pg_database_size('my_db'));

Bir tablonun boyutunu veren sorgu;

select pg_size_pretty(pg_total_relation_size('my_table'));

Bazı şemalardaki tablolara ait boyutları veren sorgu;

SELECT schemaname,
       tablename,
       pg_size_pretty(
           pg_total_relation_size(
               schemaname || '.' || tablename
           )
       ) size
FROM pg_catalog.pg_tables
WHERE schemaname in ('my_schema1', 'my_schema2')
ORDER BY schemaname, tablename;

Elasticsearch Mapping

22 Oca

Elasticsearch dünyasında mapping, bir dokümanın (document) ve onun alanlarının (fields) nasıl tutulacağı ve indeksleneceğini belirtir.

Mapping tanımlamalarının düzgün yapılması ile;

  • Elasticsearch performansı optimize edilir.
  • Disk alanlarından tasarruf edilir.

(Bu yazıda, doküman indeksleme işlemleri sırasında gösterilen örnekler, kibana developer tools üzerinden yapılabilir.)

Doküman indexleme

Aşağıdaki istek ile bir doküman indeksi oluşturmak mümkündür.

POST <index-name>/_doc
{
  "field": "value"
}

Örnek:

POST fruits/_doc
{
  "name": "Banana",
  "produce_type": "Fruit",
  "date_purchased": "2020-06-02T12:15:35",
  "quantity": 120,
  "unit_price": 6.21,
  "description": "a tropical fruit.",
  "vendor_details": {
    "vendor": "Tropical Fruit Growers of Turkey",
    "contact": "Bayram Üçüncü",
    "location": "Turkey"
  }
}

Bu istek çalıştırıldığında aşağıdaki gibi bir cevap dönecektir.

{
  "_index" : "fruits",
  "_type" : "_doc",
  "_id" : "68LPgn4BbIMmYeUuNtYB",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

Elasticsearch üzerinde indeksler için iki tür mapping oluşturma yöntemi vardır. Bunlar;

  • Dynamic mapping (Dinamik Eşleştirme)
  • Explicit mapping (Önceden Belirlenen Eşleştirme)

Dynamic Mapping (Dinamik Eşleştirme)

Bir kullanıcı yukarıdaki örnekte olduğu gibi mapping tanımını önceden yapmadığında, Elasticsearch eşlemeyi varsayılan olarak gerektiği gibi oluşturur veya günceller. Bu dinamik eşleştirme (dynamic mapping) olarak bilinir.

Dinamik eşleştirmede, alan tipleri veri içeriğinden çıkarılmaktadır. Bu noktada eğer index oluşturulurken girilen verilerden biri sayısal olarak girilmişse ve başka verilere göre metinsel değerler de alabilecek durumdaysa, örneğin float olarak oluşturulan bir alana metinsel bir ifade yazılmaya çalışıldığında hata oluşacaktır.

Dinamik eşleme ile Elasticsearch her alana bakar ve alan içeriğinden veri türünü çıkarmaya çalışır. Ardından, her alana bir tür atar ve eşleme olarak bilinen alan adları ve türlerin bir listesini oluşturur.

Atanan alan türüne bağlı olarak, her alan dizine alınır ve farklı istek türleri (full text search, aggregations, sorting) için hazırlanır. Bu nedenle eşleştirme, Elasticsearch’ün verileri nasıl depoladığı ve aradığı konusunda önemli bir rol oynar.

Bir indekse ait mapping değerlerine ulaşmak için şu sorgu çalıştırılabilir.

GET fruits/_mapping
{
  "fruits" : {
    "mappings" : {
      "properties" : {
        "date_purchased" : {
          "type" : "date"
        },
        "description" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "produce_type" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "quantity" : {
          "type" : "long"
        },
        "unit_price" : {
          "type" : "float"
        },
        "vendor_details" : {
          "properties" : {
            "contact" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "location" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "vendor" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            }
          }
        }
      }
    }
  }
}

Mapping JSON verisi içerisinde, indeksteki alanların adlarının ve türlerinin bir listesini bulunur. Elasticsearch alan türleri (field types) bilgilerine detaylı olarak buradan ulaşılabilir.

Metin İndeksleme

Metinsel alanlar için iki farklı tür bulunur:

  1. Text field
  2. Keyword field

Varsayılan olarak, her string, metin (text) alanı ve anahtar kelime (keyword) çoklu alanı olarak iki kez eşlenir. Her alan türü, farklı istek türleri için hazırlanır.

Text alan türü, full-text search yapabilmek için tasarlanmıştır.

Keyword alan türü, kesin aramalar (exact searches), toplamlar (Aggregations) ve sıralamalar (sorting) için tasarlanmıştır.

Text Field (Metin Alanlar)

Metin Analizi

Elasticsearch’te arama yaptığınızda, büyük/küçük harfe duyarlı olmadığını veya noktalama işaretlerinin önemi yoktur. Bunun nedeni, veriler indekse eklendiğinde, metin analizinin gerçekleşmesidir.

Varsayılan olarak, metinler indekse alındığında analiz edilir. Metin, belirteçler (token) olarak da bilinen ayrık sözcüklere bölünür. Çözümleyici (analyzer), her kelimeyi küçük harflere dönüştürür ve noktalama işaretlerini kaldırır.

Analiz sonucunda ortaya çıkan metinler, bir inverted index tablosuna kaydedilir.

Bu işlem, indekse her doküman eklendiğinde tekrarlanır. Zamanla inverted index tablosu aşağıdaki gibi değişikliğe uğrar.

Bu durumda, “this book” şeklinde bir arama yapıldığında, arama sonucunda 1,2,3 numaralı dokümanlar bulunur.

Keyword Field (Anahtar Alanlar)

Keyword alanlar, kesin aramalar, toplamlar ve sıralamalar için kullanılır. Aranan değerlerde, ilgili dokümanın sahip olduğu değerleri bulmak için doküman kimliğini tarar

PUT fruits/_doc/1
{
  "country": "İstanbul"
}
PUT fruits/_doc/2
{
  "country": "Ankara"
}
PUT fruits/_doc/3
{
  "country": "Manisa"
}
PUT fruits/_doc/4
{
  "country": "Trabzon"
}
PUT fruits/_doc/5
{
  "country": "Van"
}
PUT fruits/_doc/6
{
  "country": "Antalya"
}
PUT fruits/_doc/7
{
  "country": "Bolu"
}

Elasticsearch sizin için dinamik olarak bir eşleme oluşturduğunda, bir metni ne için kullanmak istediğinizi bilemez, bu nedenle tüm metinleri her iki alan türüne eşler. Örneğin vendor alanı:

            "vendor" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            }

Her iki alan türüne de ihtiyacınız olmadığı durumlarda, disk alanları israf edilmiş olur. Çünkü inverted index kullanımına gerek olmayan durumlarda gereksiz yere inverted index alanları oluşturulmuş olur.

Explicit Mapping (Önceden Belirlenen Eşleştirme)

Mapping (tip eşleştirme) işlemini kendiniz tanımlamak istediğiniz durumlarda, bunu index oluşturma sırasında yapabilirsiniz. Bu sayede eşleştirme tanımını kendiniz tasarlayabilirsiniz. Örneğin:

  • Hangi metinsel alanların Full-text search alanları olarak ele alınacağını belirtebilirsiniz.
  • Hangi alanların sayı, tarih veya geolocation olacağını belirtebilirsiniz.
  • Tarih alanlarının biçimini belirtebilirsiniz.
  • Kaynak kullanımını ve performansı dengelemek için çalışma zamanı alanlarını (runtime fields) indekse alınmış alanlarla birlikte kullanabilirsiniz. Index daha küçük olacaktır, ancak arama performansı daha yavaş olacaktır.

Her index için tek bir eşleştirme (mapping) belirlenir. İndeks oluşturulduktan sonra, bir eşlemeye yalnızca yeni alanlar eklenebilir. Mevcut bir alanın eşleşmesi değiştirilemez. Eğer mevcut bir alanın türünün değiştirilmesi gerekiyorsa, istenen eşlemeyle yeni bir indeks oluşturulur ve ardından tüm dokümanlar yeni dizine yeniden aktarılır.

PUT fruit_index
{

    "index": {
      "number_of_replicas": "1",
      "number_of_shards": "2"
    },
    "mappings" : {
      "properties" : {
        "date_purchased" : {
          "type" : "date"
        },
        "description" : {
          "type" : "text"
        },
        "name" : {
          "type" : "text"
        },
        "produce_type" : {
          "type" : "text"
        },
        "quantity" : {
          "type" : "long"
        },
        "unit_price" : {
          "type" : "float"
        },
        "vendor_details" : {
          "enabled" : false
        }
      }
    }
}

Field tanımlamaları properties içerisinde belirtilmektedir. Her field için ad ve tip belirtilmektedir. Kendi oluşturduğunuz eşleştirmelerde gereksiz alan tanımlamalarını iptal ederek optimum bir indeks oluşturabilirsiniz. Oluşturduğunuz indekslerde, alanlara istediğiniz analyzer atamalarını yapabilirsiniz.

Dikkat

Bir indekste çok fazla alan tanımlamak, yetersiz bellek hatalarına ve kurtarılması zor durumlardan kaynaklanabilecek bir eşleme patlamasına neden olabilir. Eklenen her yeni belgenin dinamik eşleme gibi yeni alanlar sunduğu bir durumu düşünün. Her yeni alan, indekste mapping olarak eklenir ve mapping büyüdükçe bir sorun haline gelebilir. Bu durumlara karşı Elasticsearch ayarlarında “mapping limit settings” kullanılarak, mapping alan sayısı sınırlandırılabilir.

Kaynaklar

  • https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
  • https://github.com/LisaHJung/Part-5-Understanding-Mapping-with-Elasticsearch-and-Kibana
  • https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-mapping-fields.html
  • https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-settings-limit.html

Asp.net MVC FileResult Dosyasını JQuery Ajax ile Yakalamak

1 Eyl

Asp.net mvc projelerinde dosya sonuçlarını kullanıcıya dönmek için action sonucunda File() metodu ile dönüş yapılabilmektedir.

Örneğin bir PDF için.

[HttpPos]
public FileContentResult Test(TestViewModel vm)
{
    var stream = new MemoryStream();
    //... add content to the stream.

    return File(stream.GetBuffer(), "application/pdf", "test.pdf");
}

Excel için;

[HttpPost]
public FileContentResult Test(TestViewModel vm)
{
    var stream = new MemoryStream();
    //... add content to the stream.

    return File(stream.GetBuffer(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "File.xlsx");
}

Bu oluşturulan dosyaya javascript tarafından jquery ile request gönderilirken dikkat edilmesi gereken bir husus, jquery’nin dosyayı bozmasıdır. Benzer bir durum burada yaşanmıştır. Dosya indiriliyor fakat bozuk olduğu için excel tarafından açılamıyor.

Bunu düzeltmek için xhrFields alanında responseType olarak arraybufffer değeri verilmelidir.

$.ajax({
    url: '/server/url',
    type: 'POST',
    contentType: "application/json; charset=utf-8",
    xhrFields : {
	   responseType : 'arraybuffer'
    },
    data: JSON.stringify(jsonData),   
    success: function (data) {
        var blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
        var downloadUrl = URL.createObjectURL(blob);
        var a = document.createElement("a");
        a.href = downloadUrl;
        a.download = "data.xls";
        a.click();
    },
});

Asp.net MVC web site oluşturma platformu olması dolayısı ile günümüzde çok sık kullanılmasa bile hala günümüzde yaygın olarak kullanılmaktadır. Dosya indirme konusunda internette epeyce aranmış ve çok fazla çözüm gösterilememiş bir konuya açılık getirmek istedim.

SQL Tablo Kolonlarından C# class Property Nasıl üretilir?

28 Ağu

Entity Framwork gibi ORM araçları ile veritabanı işlemleri yaparken bir tablonun her kolonunu C# sınıfına bir property olarak atamak durumunda kalırız. Hele ki veritabanında çok fazla kolon varsa, tek tek property oluşturmak biraz sıkıcı olabilir. Bu drumda kolon isimleri adım adım C# property tipine dönüştürülebilir.

Postgresql’de bir tablodaki kolon isimlerini almak için gerekli sorgu şu şekildedir:

SELECT column_name
  FROM information_schema.columns
 WHERE table_schema = 'cms'
   AND table_name   = 'consumptions';

Result >

 id
 subscription_id
 created_at
 meter_number
 meter_value
 meter_reading_type

Kolon isimlerini elde ettikten sonra bunları değişik formatlarda çıktılar haline dönüştürebiliriz. SQL kodu ile c# class property üretmek de mümkündür.

SELECT 'public string ' || 
        replace(initcap(column_name),'_','') || 
        ' { get; set; }'
 FROM information_schema.columns
 WHERE table_schema = 'cms'
    AND table_name   = 'consumptions';

Result >
 public string Id { get; set; }
 public string SubscriptionId { get; set; }
 public string CreatedAt { get; set; }
 public string MeterNumber { get; set; }
 public string MeterValue { get; set; }
 public string MeterReadingType { get; set; }

Ancak bütün propert tipleri string oldu ve pek kullanışlı olmadı. Bir adım daha ilerleterek tipleri de data_type kolonundan elde edebiliriz.

SELECT 'public' ||
            (CASE
                WHEN data_type = 'uuid' THEN ' string '
                WHEN data_type = 'integer' THEN ' int '
                WHEN data_type = 'numeric' THEN ' double '
                WHEN data_type = 'timestamp without time zone' THEN ' DateTime '
                ELSE ' string '
            END) ||
       replace(initcap(column_name),'_','') ||
       ' { get; set; }'
  FROM information_schema.columns
 WHERE table_schema = 'cms'
   AND table_name   = 'consumptions';

Result >
 public string Id { get; set; }
 public string SubscriptionId { get; set; }
 public DateTime CreatedAt { get; set; }
 public int MeterNumber { get; set; }
 public double MeterValue { get; set; }
 public int MeterReadingType { get; set; }

Property’ler Column attribute ile biraz daha süslenerek Entity Framework’ün kolay mapping yapmasına imkan sağlanabilir.

SELECT '[Column("' || column_name || '")] '
       'public' ||
            (CASE
                WHEN data_type = 'uuid' THEN ' string '
                WHEN data_type = 'integer' THEN ' int '
                WHEN data_type = 'numeric' THEN ' double '
                WHEN data_type = 'timestamp without time zone' THEN ' DateTime '
                ELSE ' string '
            END) ||
       replace(initcap(column_name),'_','') ||
       ' { get; set; }'
  FROM information_schema.columns
 WHERE table_schema = 'cms'
   AND table_name   = 'consumptions';

Result >
 [Column("id")] public string Id { get; set; }
 [Column("subscription_id")] public string SubscriptionId { get; set; }
 [Column("created_at")] public DateTime CreatedAt { get; set; }
 [Column("meter_number")] public int MeterNumber { get; set; }
 [Column("meter_value")] public double MeterValue { get; set; }
 [Column("meter_reading_type")] public int MeterReadingType { get; set; }

WSL Ubuntu Versiyon Güncelleme

26 Ağu

WSL üzerinde çalışan ubuntu veya diğer ürünlerin versionunu görüntülemek için aşağıdaki komut kullanılır.

wsl -l -v

 NAME                   STATE           VERSION
 docker-desktop-data    Stopped         2
 Ubuntu-20.04           Running         1
 docker-desktop         Stopped         2 

Ubuntu versionunu 2 yapmak için kullanılacak komut, kurulu olan ubuntu versiyonuna göre aşağıdaki şekilde yapılmaktadır. Örnekteki 20.04 sürümü kurulumunuza göre değişebilir.

wsl --set-version Ubuntu-20.04 2

 Conversion in progress, this may take a few minutes…
 For information on key differences with WSL 2 please visit https://aka.ms/wsl2
 Conversion complete.

İşlem tamamlandıktan sonra yeni version listesi aşağıdaki gibi olacaktır.

wsl -l -v

 NAME                   STATE           VERSION
 docker-desktop-data    Stopped         2
 Ubuntu-20.04           Running         2
 docker-desktop         Stopped         2 

Docker Komutları

25 Ağu

Dcoker kurulu bir sistemde CLI üzerinden girilen komutlar ile docker işlemlerini gerçekleştirebilmekteyiz. Docker CLI bilindiği üzere bir Rest API aracılığı ile komutları arka plan servisi olan Daemon’a aktarmaktadır. Docker kullanımında faydalı komutlar aşağıda listelenmiştir.

1 – docker

CLI üzerinde docker ile ilgili komutların listesi ve parametreleri “docker” komutu ile öğrenilebilmektedir.

C:\Users\Bayram docker
A self-sufficient runtime for containers
 Options:
       --config string      Location of client config files (default
                            "C:\Users\Bayram\.docker")
   -c, --context string     Name of the context to use to connect to the
                            daemon (overrides DOCKER_HOST env var and
                            default context set with "docker context use")
   -D, --debug              Enable debug mode
   -H, --host list          Daemon socket(s) to connect to
   -l, --log-level string   Set the logging level
                            ("debug"|"info"|"warn"|"error"|"fatal")
                            (default "info")
       --tls                Use TLS; implied by --tlsverify
       --tlscacert string   Trust certs signed only by this CA (default
                            "C:\Users\Bayram\.docker\ca.pem")
       --tlscert string     Path to TLS certificate file (default
                            "C:\Users\Bayram\.docker\cert.pem")
       --tlskey string      Path to TLS key file (default
                            "C:\Users\Bayram\.docker\key.pem")
       --tlsverify          Use TLS and verify the remote
   -v, --version            Print version information and quit
 Management Commands:
   builder     Manage builds
   buildx*     Build with BuildKit (Docker Inc., v0.5.1-docker)
   compose*    Docker Compose (Docker Inc., v2.0.0-beta.6)
   config      Manage Docker configs
   container   Manage containers
   context     Manage contexts
   image       Manage images
   manifest    Manage Docker image manifests and manifest lists
   network     Manage networks
   node        Manage Swarm nodes
   plugin      Manage plugins
   scan*       Docker Scan (Docker Inc., v0.8.0)
   secret      Manage Docker secrets
   service     Manage services
   stack       Manage Docker stacks
   swarm       Manage Swarm
   system      Manage Docker
   trust       Manage trust on Docker images
   volume      Manage volumes
 Commands:
   attach      Attach local standard input, output, and error streams to a running container
   build       Build an image from a Dockerfile
   commit      Create a new image from a container's changes
   cp          Copy files/folders between a container and the local filesystem
   create      Create a new container
   diff        Inspect changes to files or directories on a container's filesystem
   events      Get real time events from the server
   exec        Run a command in a running container
   export      Export a container's filesystem as a tar archive
   history     Show the history of an image
   images      List images
   import      Import the contents from a tarball to create a filesystem image
   info        Display system-wide information
   inspect     Return low-level information on Docker objects
   kill        Kill one or more running containers
   load        Load an image from a tar archive or STDIN
   login       Log in to a Docker registry
   logout      Log out from a Docker registry
   logs        Fetch the logs of a container
   pause       Pause all processes within one or more containers
   port        List port mappings or a specific mapping for the container
   ps          List containers
   pull        Pull an image or a repository from a registry
   push        Push an image or a repository to a registry
   rename      Rename a container
   restart     Restart one or more containers
   rm          Remove one or more containers
   rmi         Remove one or more images
   run         Run a command in a new container
   save        Save one or more images to a tar archive (streamed to STDOUT by default)
   search      Search the Docker Hub for images
   start       Start one or more stopped containers
   stats       Display a live stream of container(s) resource usage statistics
   stop        Stop one or more running containers
   tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
   top         Display the running processes of a container
   unpause     Unpause all processes within one or more containers
   update      Update configuration of one or more containers
   version     Show the Docker version information
   wait        Block until one or more containers stop, then print their exit codes

2 – docker version

Docker version komutu ile client ve server hakkında bilgiler edinilmektedir. Bu ekranda hata alınması durumunda daemon servisi ayakta olmayabilir.

C:\Users\Bayram docker
Client:
  Cloud integration: 1.0.17
  Version:           20.10.7
  API version:       1.41
  Go version:        go1.16.4
  Git commit:        f0df350
  Built:             Wed Jun  2 12:00:56 2021
  OS/Arch:           windows/amd64
  Context:           default
  Experimental:      true
 Server: Docker Engine - Community
  Engine:
   Version:          20.10.7
   API version:      1.41 (minimum version 1.12)
   Go version:       go1.13.15
   Git commit:       b0f5bc3
   Built:            Wed Jun  2 11:54:58 2021
   OS/Arch:          linux/amd64
   Experimental:     false
  containerd:
   Version:          1.4.6
   GitCommit:        d71fcd7d8303wbf684402823e425e9dd2e99285d
  runc:
   Version:          1.0.0-rc95
   GitCommit:        b9ee9c6314499f1b4a7f497e1f1f856fe433d3b7
  docker-init:
   Version:          0.19.0
   GitCommit:        de40ae0

3 – docker info

Bu komut sayesinde sistemde kaç adet container olduğu, çalışan, durmuş olan container sayıları, imaj sayıları ve diğer teknik bilgiler yer almaktarır.

C:\Users\Bayram docker
Client:
  Context:    default
  Debug Mode: false
  Plugins:
   buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)
   compose: Docker Compose (Docker Inc., v2.0.0-beta.6)
   scan: Docker Scan (Docker Inc., v0.8.0)
 Server:
  Containers: 5
   Running: 0
   Paused: 0
   Stopped: 5
  Images: 3
  Server Version: 20.10.7
  Storage Driver: overlay2
   Backing Filesystem: extfs
   Supports d_type: true
   Native Overlay Diff: true
   userxattr: false
  Logging Driver: json-file
  Cgroup Driver: cgroupfs
  Cgroup Version: 1
  Plugins:
   Volume: local
   Network: bridge host ipvlan macvlan null overlay
   Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
  Swarm: inactive
  Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
  Default Runtime: runc
  Init Binary: docker-init
  containerd version: d71fcd7d8303cbf684402823e425e9dd2e99285d
  init version: de40ad0
  Security Options:
   seccomp
    Profile: default
  Kernel Version: 4.19.104-microsoft-standard
  Operating System: Docker Desktop
  OSType: linux
  Architecture: x86_64
  CPUs: 8
  Total Memory: 12.4GiB
  Name: docker-desktop
  ID: E4O2:DUVG:VVJK:SP2R:2WVA:7WBN:OC65:RUOF:XIAB:BTGL:EQH4:Y67U
  Docker Root Dir: /var/lib/docker
  Debug Mode: true
   File Descriptors: 38
   Goroutines: 40
   System Time: 2021-08-22T19:12:04.9565663Z
   EventsListeners: 2
  Registry: https://index.docker.io/v1/
  Labels:
  Experimental: false
  Insecure Registries:
   127.0.0.0/8
  Live Restore Enabled: false

4 – docker <komut> –help

Docker komut listesinden bir komutun hangi parametreler ile çalıştığını öğrenebilmek için –help parametresi kullanılır.

C:\Users\Bayram docker push --help

Usage:  docker push [OPTIONS] NAME[:TAG]
 Push an image or a repository to a registry
 Options:
   -a, --all-tags                Push all tagged images in the repository
       --disable-content-trust   Skip image signing (default true)
   -q, --quiet                   Suppress verbose output

5 – docker <object> <komut>

Docker komut listesinde çok fazla komut olduğundan dolayı, docker mühendisleri komuttan önce obje isminin kullanılmasını sağlayarak komut karmaşasının önüne geçmek istemişlerdir. Burada obje ismi container, image gibi docker objeleridir. Obje isminin kullanılması zorunlu değil ancak önerilir.

C:\Users\Bayram docker container run hello-world

Komutu aşağıdaki komut ile aynı işi yapar

C:\Users\Bayram docker run hello-world

6 – docker run <image>

Hangi imajdan bir container oluşturulacağı bildirilir. Bu komut daha önce belirtildiği gibi CLI üzerinden Daemon tarafına Rest API ile gönderilir. Örneğin “hello-word” isimli imajdan bir container oluşturulması komutu gönderildiğinde, eğerr daha önce indirilmediyse öncelikle bu imaj Docker Hub üzerinden indirilir. Daha sonra da bu imajdan bir container oluşturulur.

C:\Users\Bayram docker run hello-world

Hello from Docker!
 This message shows that your installation appears to be working correctly.
 To generate this message, Docker took the following steps:
 The Docker client contacted the Docker daemon.
 The Docker daemon pulled the "hello-world" image from the Docker Hub.
 (amd64)
 The Docker daemon created a new container from that image which runs the
 executable that produces the output you are currently reading.
 The Docker daemon streamed that output to the Docker client, which sent it
 to your terminal. 
 To try something more ambitious, you can run an Ubuntu container with:
  $ docker run -it ubuntu bash
 Share images, automate workflows, and more with a free Docker ID:
  https://hub.docker.com/
 For more examples and ideas, visit:
  https://docs.docker.com/get-started/

Container oluştuurlduğunda içerisindeki ugyulama çalışır ve bu uygulama çalışmaya devam ettiği sürece container çalışmaya devam eder. Uygulama çalışıp bittiğinde container kapatılır. Yukarıdaki örnekte “hello-world” imajı içerisinde planlana uygulama ekrana birşeyler yazdı ve işlemini bitirdi. Bu durumda container da kapatıldı.

7 – docker ps

Çalışan container listesini veren komuttur.

C:\Users\Bayram docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Bu durumda sistemde çalışan bir container olmadığı anlaşılmaktadır.

docker ps -a komutu ile hem çalışan hem de durdurulmuş container’ları gösterir.

C:\Users\Bayram docker ps -a
CONTAINER ID   IMAGE                   COMMAND                  CREATED          STATUS                      PORTS                      NAMES
03499e6b9b2b   hello-world             "/hello"                 17 minutes ago   Exited (0) 16 minutes ago                              affectionate_euclid

Listede görüldüğü üzere her container için unique bir ID ve NAME belirlenir. Container’lar üzerinde işlem yapılırken ID ve NAME kullanılır. Eğer container oluşturulurken isim verilmez ise docker kendi belirlediği ismi kullanır.

8 – docker rm <conatainer id veya name>

Oluşturulan container’ları silmek için kullanılır.

C:\Users\Bayram docker rm 03499e6b9b2b
03499e6b9b2b

Not: Çalışan bir container silinmek sitediğinde sistem hata mesajı verir. Bu durumda ya container durdurulur ve silinir. Ya da “docker rm -f <container>” ile force edilerek silinir.

9 – docker start <conatainer id veya name>

Durdurulmuş bir container’ı çalıştırmak için kullanılır. Daha önceki örneklerde olduğu gibi, bir uygulama çalışıp işini bitirdiğinde container durdurulur. Tekrar çalıştırmak için start komutu kullanılır.

C:\Users\Bayram docker start c48d7640c752
c48d7640c752

10 – docker logs <conatainer id veya name>

Container içerisinde üretilen log’ları listeler. Container içerisinde çalışan program tarafından üretilen çıktıları buradan listelenebilir. Örneğin hello-world isimli container ne kadar çalıştırılırsa log tarafına o kadar çıktı eklenir.

C:\Users\Bayram docker logs c48d7640c752
Hello from Docker!
 This message shows that your installation appears to be working correctly.
 To generate this message, Docker took the following steps:
 The Docker client contacted the Docker daemon.
 The Docker daemon pulled the "hello-world" image from the Docker Hub.
 (amd64)
 The Docker daemon created a new container from that image which runs the
 executable that produces the output you are currently reading.
 The Docker daemon streamed that output to the Docker client, which sent it
 to your terminal. 
 To try something more ambitious, you can run an Ubuntu container with:
  $ docker run -it ubuntu bash
 Share images, automate workflows, and more with a free Docker ID:
  https://hub.docker.com/
 For more examples and ideas, visit:
  https://docs.docker.com/get-started/

11 – docker run -d <image> ile arka planda çalışan container’lar

Her container, çalışıp işini bitirip kapanan türde değildi. Bazı container’lar sürekli çalışan uygulamalar şeklinde planlandığı için bir kez çalştırıldığında ugyulama hata almadığı ve container durdurulmadığı sürece çalışmaya devam eder. Örneğin httpd imajından oluşturulan container’alr bu şekildedir.

C:\Users\Bayram docker run -d httpd
Unable to find image 'httpd:latest' locally
 latest: Pulling from library/httpd
 e1acddbe380c: Pull complete
 3707e996fb4c: Pull complete
 c14c6b866b5c: Pull complete
 68cf2274a624: Pull complete
 bd362b482eb5: Pull complete
 Digest: sha256:307e3a2f43cd2c58ac37a093dd9adfc2598d00ca4cc0dd978cb1a56ccad4a39f
 Status: Downloaded newer image for httpd:latest
 b62ee5b7e16b7723b665087d1cc30b96ba9590bc6dbb3c0102ee18312afae62d

C:\Users\Bayram docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS          PORTS     NAMES
b62ee5b7e16b   httpd     "httpd-foreground"   31 seconds ago   Up 27 seconds   80/tcp    admiring_buck

Öncelikle local sistemde kayıtlı olmayan httpd imajı indidilri ve arkaplanda çalıştırıldı ve dcoker ps komutu ile görüntülendi.

Not: docker uygulamaların stdout ve stderr çıkışlarına bağlanır.

Docker bir uygulama için container çalıştırıdığında mevcut shell, ya da kullanılan komut satırını container da çalışan uygulamanın stdout ve stderr çıkışlarına bağlar. Sürekli arka planda çalışan uygulamalar için run komutu ile -d parametresinin kullanılma sebebi, uygulamanın konsolu kilitlememesidir. Bu parametre ile uygulama arka planda çalşımaya devam eder.

12 – docker exec -it <containerid> sh ile container shell bağlantısı

Docker container içerisinde çalışan shell bağlantısını yapmak için exec komutu çalıştırılır.

C:\Users\Bayram docker exec -it 420F sh
# ls
 bin  build  cgi-bin  conf  error  htdocs  icons  include  logs  modules
# exit

Komutta kullanılan “-it” parametresi “interactive terminal” anlamına gelir. “sh” parametresi ise shell anlamına gelmektedir. Linux container olduğu için, ls komutu ile container içindeki dosyalar listelelenebilir. exit komutu ile container içerisinden çıkılabilir. Container çalışmaya devam eder.

13- docker <object> inspect <id veya name>

inspect komutu, ilgili obje hakkında çok detaylı bilgiler verir.

C:\Users\Bayram docker container inspect 4f
[
     {
         "Id": "4f200ee8aa19197260259e78636de7df39fbb946b8363f6aa1122051832e81d6",
         "Created": "2021-08-24T18:53:04.4160754Z",
         "Path": "httpd-foreground",
         "Args": [],
         "State": {
             "Status": "running",
             "Running": true,
             "Paused": false,
             "Restarting": false,
             "OOMKilled": false,
             "Dead": false,
             "Pid": 1137,
             "ExitCode": 0,
             "Error": "",
             "StartedAt": "2021-08-24T18:53:05.0525906Z",
             "FinishedAt": "0001-01-01T00:00:00Z"
         },
    ....
    ....

Sadece container değil image gibi objeler ile ilgili bilgiler alınabilmektedir.

Docker Nedir?

24 Ağu

Docker nasıl ortaya çıkmıştır?

Docker container teknolojisi, Linux işletim sisteminin çekirdeğine 2008 yılında eklenen Linux Containers (LXC) özelliği ile birlikte doğmuş bir fikirdir. LXC, Linux işletim sistemindeki control groups (cgroups) ve namespaces özellikleri kullanılarak uygulandı ve herhangi bir patch gerektirmeden tek bir Linux çekirdeği üzerinden çalıştırıldı.

Namespaces özelliği, işletim sistemi üzerinde birden fazla process yada uygulama birbirinden izole bir şekilde uygulanbilirliği sağlar. Örneğin Network, Mount, User, Control Group gibi birden fazla namespace bulunabilmektedir.

Control Groups (cgroups) özelliği ise google mühendisleri tarafından linux işletim sistemine eklenmiş bir özelliktir. Bu özellik sayesinde namespace ile izole edilen process’lere ya da uygulamalara CPU, I/O, memory, network gibi kaynak sınırlaması getirilebilmektedir.

Bu gelişmeler ile birlikte Linux işletim sisteminde çalışan iki farklı A ve B uygulamlarını Linux namespaces özelliği ile izeole edip, control groups özelliği ile de A uygulamasına 4Gb Ram, 2 CPU ve B uygulamasına da 2Gb Ram, 1CPU kullanım sınırlaması gibi yapılandırmalar sağlanabilir hale geldi.

Uygulamaların izolasyonu sayesinde her uygulama için bir sanal makine açmak yerine, bir LXC açarak daha ölçeklenebilir bir mimari tasarlanmıştır. Çünkü her uygulama için açılan sanal makinede kullanılamayan atıl kapasiteler meydana gelmektedir. Container yapısı sayesinde atıl kapasiteler daha uygun bir biçimde bölüştürülerek daha fazla uygulamaya hizmet verebilecek hale gelmiştir.

Linux Container ile uygulamaların izolasyonu için ayarlamaların yapılması, paket halinde sunulmuş bir çözüm değildi. Bu nedenle uygulamalarını izole etmek isteyen developer’lar için LXC kullanmak biraz zahmetliydi. Bunun çözümünü 2013 yılında San Francisco’da dotClud firması, Docker isimli açık kaynak kodlu biz çözüm geliştirerek kullanıcılara sunmuştur. Bu gelişme ile birlikte developer ve mühendisler, Docker teknolojisi ile çalışarak, uygulama izolasyonunu kolay bir şekilde sağlayabilmiş ve bu nedenle Docker teknolojisi çok hızlı bir biçimde yaygınlaşmıştır.

Docker her ne kadar açık kaynak ve ücretsiz olsa da, 2014 yıllarında Docker firması şirketlerin ihtiyaçlarını karşılayacak ürünler geliştirerek Docker Enterprise versiyonunu da piyasaya sunmuştur.

Docker nasıl çalışır?

Docker’ın çalışabilmesi için öncelikle siteme bir docker engine kurulmalıdır. Docker engine, aşağıdaki üç temel bileşeni kullanarak uygulamaları geliştirmenize, birleştirmenize, göndermenize ve çalıştırmanıza imkan sağlar. (https://www.docker.com üzerinden indirilerek kurulum yapılabilir.)

Docker Daemon: Docker imajları, container’ları, ağları ve depolama birimlerini oluşturup yöneten bileşendir.

Docker Engine REST API: Docker daemon servisine dışarıdan CLI veya uygulamalar tarafından Rest API aracılığı ile erişerek komutlar verebilmeyi sağlayan bileşendir.

Docker CLI: Docker daemon ile iletişim kurmayı sağlayan komut satırı ya da konsol arayüz bileşenidir.

Docker sayesinde tek bir işletim sistemi üzerinde birden fazla uygulama birbirinden izole bir şekilde çalışabilmektedir.

Windows Üzerinde Docker Kullanımı

Docker kurulabilmesi için Windows’un sanallaştırma özelliğinin açılması istenir. Docker mimarisi Linux üzerinde inşa edildiğinden dolayı Windows işletim sisteminde de kurulan Docker desktop uygulaması, Windows işletim sistemi üzerinde bir Linux sanal makine oluşturmaktadır. Bu sanal makine üzerine docker kurulmaktadır.

Docker Mimarisi

Docker mimarisi, client-server modelini kullanır ve Docker Client, Docker Host, Network, Storage ve Docker Registery/Hub bileşenlerinden oluşur.

Docker Mimarisi

Docker Client

Kullanıcıların Docker Daemon ile iletişim kurabilmesini sağlar. Bir client aynı hostta bulunan Daemon ile veya uzaktaki bir hostta bulunan Daemon ile bağlantı kurabilir. Docker client, kullanıcılara sunduğu komut satırı arabirimi (CLI) ile daemon üzerinde build, run, stop gibi komutlar ile işlemler yapabilmeyi sağlar. Temel amacı, imajların regestry kaynağından çekilerek host’ta çalışmasını sağlamaktır. Genel client komutları:

docker build
docker pull
docker run

Docker Host

Uygulamaları çalıştırmak ve yürütmek için sunulan ortamdır. Host bileşenleri; Docker Daemon, Imaj, Container, Nerwork ve Storage şeklindedir. Docker daemon bütün komutları CLI üzerinden Rest API aracılığı ile alır. Gerektiğinde hizmetlerini yürütebilmek için diğer daemon’lar ile iletişim kurabilir. Daemon, client tarafından istenen container imajlarını çeker ve build eder. Client tarafından istenen imajı çektikten sonra build file(Dockerfile) olarak adlandırılan dosyadaki talimatları uygulayarak container için çalışan bir model oluşturur. Dockerfile içerisinde, container çalıştırılmadan önce Daemon tarafından yüklenmesi gereken bileşenlere ait yönergeler veya container çalıştırıldıktan sonra komut satırından çalıştırılacak talimat ve komutlar bulunmaktadır.

Docker Objects

Uygulamanın container üzerinde ayağa kaldırılması sırasında birçok obje kullanılır. Bunlar:

  • Image
  • Container
  • Network
  • Storage

Image

Image nesnesi, container oluşturmak için kullanılan salt okunur bir binary şablondur. Container ihtiyaçlarını ve yeteneklerini açıklayan meta veriler içerir. Temel olarak uygulamaları depolamak ve taşımak için kullanılır. Örneğin bir asp.net uygulaması yazdığınızda, bu uygulama için oluşturulan container image nesnesi, uygulamanın bütün bağımlılıklarını ve runtime ortamını içeren bir paket şablon oluşturulur. Bu imajlar, şirket içerisinde özel olarak veya dış dünya ile genel olarak Docker Hub gibi genel kayıt alanlarına aktarılarak paylaşılabilir.

Container

Imaj ile planlanmış ve hazırlanmış uygulamanın çalışan haline container denir. Bir imajdan container oluşturulurken network ve storage gibi ek sınırlamalar belirlenebilir. Container çalıştırıldıktan sonra, çalışan container’a bağlanarak içerisinde konfigurasyon ayarları yapmak ta mümkündür. Ancak bu pek önerilen bir işlem değildir. Bunun yerine imaj içerisinde gerekli düzenlemeler yaparak yeniden bir container oluşturmak daha iyi bir yöntemdir. Çünkü container’lar kullan at mantığında çalıştırılan objeler olduğu için, container içerisinde bir problemin çözülmesi durumunda o anlık çözüm oluşturulmuş olur. Container yeniden oluşturulduğunda aynı problem ile ayağa kalkacaktır.

Bir imajdan bir container oluşturulurken ek erişim belirtilmedikçe container sadece imajda belirlenen kaynaklara erişebilir. Container’lar sanal makinelerden çok daha küçük boyutta olduğundan dolayı saniyeler içinde ayağa kalkabilirler. Aynı imajdan birden fazla container oluşturmak da mümkündür.

Network

Docker uygulama odaklı bir biçimde ağ oluşturmayı sağlar ve geliştiricilere ağ ayarlarını belirleme imkanı sunar. Temel olarak Default Doceker Network ve User Defined Network olmak üzere iki türlü ağ kullanılabilmektedir. Varsayılan olarak Default kurulumunda None, Bridge ve Host olmak üzere üç farklı ağ tanımlıdır. None ve Host ağları Docker’daki ağ yığınının bir parçasıdır. Bridge ise otomatik olarak bir gateway ve IP subnet oluşturur ve bu ağa dahil tüm container’lar IP adresleme yoluyla birbirleri ile konuşabilirler. Ancak default bridge network iyi ölçeklenemediği ve ağ kullanılabilirliği açısından kısıtlamaları olduğu için pek tercih edilmez.

Dİğer bir tür ise user-defined ağlardır. Yöneticiler, birden çok kullanıcı tanımlı ağı yapılandırabilir. Bunlar:

  • Bridge Network: Default bridge network ile benzer şekilde çalışır ancak farklı olarak ağ içindeki konteynerlerin birbirleriyle iletişim kurmaları için port yönlendirmeye gerek yoktur. Diğer fark, otomatik ağ keşfi için tam desteğe sahip olmasıdır.
  • Overlay Network: Container’ların farklı host’larda barındırıldığı durumda overlay network (yerel paylaşım ağı) kullanılır. Burada dikkat edilmesi gereken şey, Docker engine’lerin swarm modunun cluster için etkinleştirilmesi gerekir.
  • Macvlan Network: Bridge ve Overlay ağlarını kullanırken, container ile host arasında bir köprü bulunur. Bir Macvlan ağı bu köprüyü kaldırarak, port yönlendirme ile uğraşmadan container kaynaklarını harici ağlara gösterme imkanı sağlar. Bu işlem, IP adresleri yerine MAC adresleri kullanılarak gerçekleştirilir.

Storage

Container içerisinde veri saklayabilmek için bir writable layer bulunur. Container silindiğinde bu writable-layer da silineceğinden dolayı veri kaybı yaşanır. Örneğin bir postgresql container oluşturulup içerisine veriler kaydedildikten sonra container silinirse veritabanına kaydedilen bütün bilgiler de silinmiş olur. Kalıcı veri depolaması için Docker dört seçenek sunar.

  • Data Volumes: Kalıcı bir depolama birimi oluşturma, birim ismini değiştirme, birimleri listeleme ve ayrıca birim ile ilişkili container’ları listelemeyi sağlar. Depolama birimi(volume) host dosya sistemi üzerinde oluşturulur. Veriler container dışına aktarıldığı için container silindiğinde kaybolmaz. Yeni oluşturulan container için aynı dosya yolu berlilendiğinde yeni container da aynı yere yazabilir.
  • Data Volume Container: Özel bir container üzerine bir depolama birimi oluşturularak diğer container’ların da buraya yazması sağlanabilir. Bu sayede volume container ile application container birbirinden bağımsız olur ve bu sayade birden fazla container ile paylaşılabilir.
  • Directory Mounts: Host’ta bulunan bir dizinin bir container’a monte edilmesidir. Önceki bahsedilen durumlarda depolama birimlerin(Volume) Docker birimleri klasörü içinde olması gerekirken, directory mout söz konusu olduğunda, host’taki herhangi bir dizin birim için kaynak olarak kullanılabilir.
  • Storage Plugins: Harici depolama platformlarına bağlanma yeteneği sağlar. Bu eklentiler, depolamayı ana bilgisayardan bir depolama dizisi veya bir cihaz gibi harici bir kaynağa eşler. Docker’ın Eklenti sayfasında bir depolama eklentisi listesi bulunabilir.
    • HPE 3PAR
    • EMC (ScaleIO, XtremIO, VMAX, Isilon)
    • NetApp
    • Azure File Storage
    • Google Compute Platform

Docker Registries

Imajları depolayabileceğiniz ve indirebileceğiniz konumlar sağlayan hizmetlerdir. Başka bir deyişle, bir Docker registry, bir veya daha fazla Docker imajını barındıran Docker depolarını içerir. Public regitery’ler Docker Hub ve Docker Cloud ortamlarıdır. Genel registery komutları:

docker push
docker pull
docker run

Kaynaklar

  • https://www.aquasec.com/cloud-native-academy/docker-container/docker-architecture
  • https://docs.docker.com/get-started/overview

Container ve Sanal Makineler Arasındaki Farklar

22 Ağu
Conatiner vs Virtual Machines

Sanal Makineler

Sanal makineler donanımsal altyapının(infrastructure) üzerine bir Hypervisor sistem kurularak yapılandırılrlar. Piyasada bir çok sanallaştırma platformu bulunmaktadır.

  • Microsoft hyper-v
  • Virtual Box
  • VMware

Hypervisor üzerine de sanal makineler kurulmaktadır. Her bir sanal makine genelde Linux veya Windows işletim sistemine sahiptir.

Container’lar

Container sistemleri için donanımsal altyapı(infrastructure) üzerine tek bir işletim sistemi ve bu işletim sistemi üzerine de Docker gibi container engine kurulur.

Container kullanmanın en önemli özelliklerinden biri, bir uygulamayı, kendine ait bağımlılıkları ve framework altyapılarıyla birlikte paketleyip dış dünyaya sunabilme imkanı vermesidir. Yukarıdaki şemada bulunan APP1, APP2, APP3 gibi uygulamaların her biri bir imaj haline getirilerek tüm dünyanın kullanımına açılacak şekilde Docker Registry üzerinden dağıtılabilir. Bu süreç deterministiktir. Yani uygulama imajın oluşturulduğu makinede nasıl çalışıyorsa başka birinin docker sisteminde de aynı şekilde çalışır.

Karşılaştırmalar

Bir sanal makine eğer tek bir uygulamanın barındırılması amacıyla kuruluyorsa, bu durumda işletim sistemi üzerinde uygulamanın altyapısal yönetimi ve işletim sisteminin yönetiminin yapılması gerekmektedir. Ancak container sistemlerde tek bir işletim sistemi bulunduğundan ve uygulama altyapıları container içerisine image aracılığı ile inşa edildiğinden dolayı bu tür bakım gereksinimleri ortadan kalkar.

Sanal makineler tek bir uygulama için kurulduğunda atıl kapasiteler meydana gelmektedir. Örneğin 4GB ram varsa işletim sistemi bunun bir kısmını kendi ihtiyaçları için kullanır ve üzerine kurulan uygulama da aynı şekilde ihtiyacı olanı kullandığında arta kalan memory miktarı ve işletim sisteminin kendi ihtiyaçları için kullandığı memory miktarı boşa giden kaynaklar olarak değerlendirilebilir. Container sistemlerde tek bir işletim sistemi kendi ihtiyacını kullanırken kalan kaynaklar uygulama ihtiyaçlarına göre tasnif edilerek kullanılır. Artan kaynaklar da yeni container’lar için boşta bekletilebilir. Bu sayede daha ölçeklenebilir bir yapı oluşturulabilir.

Container sistemlerde yönetilmesi gereken tek bir işletim sistemi varken, sanallaştırma sistemlerde yönetilmesi gereken birden fazla işletim sistemi bulunur.

Container endine direk donanım üzerindeki işletim sistemine değil de, sanal makineler üzerine de kurulabilir. Sanallaştırma sistemleri container sistemler için altyapı oluşturabilirler.

Container sistemlerde oluşturulan imajlar dünyanın her yerinde çalıştırılabilir hafif yüklü paketlerdir. Sanal makineler de her ne kadar paketlenebilir olsa da, paketin çalışabilmesi için diğer sistemde aynı hypervisor ve benzer donanımsal sistemlerin olması gerekir. Ayrıca paket boyutları çok büyük oladuğu için taşınabilirlik daha zor olabilmektedir.