C# İle Özel Bir Docker Konteyner İzleme Aracı Nasıl Yapılır?

C# İle Özel Bir Docker Konteyner İzleme Aracı Nasıl Yapılır?
C# İle Özel Bir Docker Konteyner İzleme Aracı Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projenize başlamadan önce sisteminizde aşağıdaki araçların kurulu olduğundan emin olmalısınız. Docker API ile iletişim kurmak için .NET 9.0 veya üzeri bir sürüm kullanmanız önerilir.

  • .NET SDK 9.0+: En güncel C# özelliklerini kullanmak için gereklidir.
  • Docker Desktop veya Docker Engine: Uygulamanızın konteynerlerle konuşabilmesi için yerel makinenizde bir Docker daemon çalışıyor olmalıdır.
  • Docker.DotNet Kütüphanesi: Docker API ile C# arasında köprü kuran resmi olmayan ancak sektör standardı olan NuGet paketidir.

Projeyi oluşturmak için terminalinize dotnet new console -n DockerMonitor komutunu yazarak başlayabilirsiniz. Ardından gerekli kütüphaneyi şu komutla ekleyin:

dotnet add package Docker.DotNet

Docker Engine API'sine Bağlantı Kurma

Docker API'sine erişmek için bir DockerClient nesnesi oluşturmamız gerekir. Bu nesne, Docker daemon'ın soket dosyası (Linux'ta /var/run/docker.sock, Windows'ta npipe:////./pipe/docker_engine) üzerinden iletişim kurar.

using Docker.DotNet;
using System.Runtime.InteropServices;

var dockerUri = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) 
    ? new Uri("npipe:////./pipe/docker_engine") 
    : new Uri("unix:///var/run/docker.sock");

var client = new DockerClientConfiguration(dockerUri).CreateClient();
Console.WriteLine("Docker API bağlantısı başarıyla kuruldu.");

Bu kod bloğu, işletim sistemini kontrol ederek doğru soket adresini belirler. Güvenlik nedeniyle, bu sokete erişim yetkilerinin doğru yapılandırıldığından emin olun.

Konteyner Listesini ve Durumlarını Çekme

İzleme aracımızın ilk adımı, o an çalışan veya durmuş olan konteynerleri listelemektir. Containers.ListContainersAsync metodu, sistemdeki tüm konteynerlerin meta verilerini döndürür.

var containers = await client.Containers.ListContainersAsync(new Docker.DotNet.Models.ContainersListParameters() { All = true });

foreach (var container in containers)
{
    Console.WriteLine($"ID: {container.ID.Substring(0, 12)} | İsim: {string.Join(", ", container.Names)} | Durum: {container.State}");
}

Burada All = true parametresi, sadece çalışanları değil, durdurulmuş konteynerleri de görmemizi sağlar. ID.Substring(0, 12) kullanımı, Docker'ın standart kısa ID formatını ekrana yansıtmak için tercih edilmiştir.

Gerçek Zamanlı Kaynak Tüketimi İzleme

Konteynerlerin CPU ve bellek kullanımını takip etmek için ContainerStatsParameters kullanılır. Bu işlem, Docker'ın sağladığı bir stream (akış) üzerinden gerçekleşir. Aşağıdaki örnek, belirli bir konteynerin istatistiklerini nasıl okuyacağınızı gösterir.

var statsResponse = await client.Containers.GetContainerStatsAsync("konteyner_id_buraya", new Docker.DotNet.Models.ContainerStatsParameters(), CancellationToken.None);

using (var reader = new StreamReader(statsResponse))
{
    string line;
    while ((line = await reader.ReadLineAsync()) != null)
    {
        // Gelen JSON verisini işleyin
        Console.WriteLine(line);
    }
}

Bu yöntem, konteynerin o anki performans verilerini sürekli bir akış olarak döndürür. Bu verileri ayrıştırarak (parsing), CPU kullanım yüzdesini hesaplayabilir ve belirli bir eşiği geçtiğinde uyarı veren bir mantık kurabilirsiniz.

İzleme Aracı Karşılaştırma Tablosu

Aşağıdaki tablo, özel bir izleme aracı ile hazır araçların kullanım senaryolarını özetlemektedir.

Özellik Özel C# Aracı Hazır Araçlar (Grafana/Portainer)
Özelleştirme Tam Kontrol Sınırlı
Performans Düşük Kaynak Tüketimi Yüksek Kaynak Tüketimi
Entegrasyon Kod İçine Gömülü Harici Servis

Güvenlik ve Performans İpuçları

Kritik Uyarı: Docker soketine erişim, sistem üzerinde tam yetki (root/admin) ile eşdeğerdir. Uygulamanızı çalıştırırken en az ayrıcalık prensibine (Principle of Least Privilege) uyun. Konteyner izleme servisini asla dış dünyaya açık bir portta çalıştırmayın.

Performans için, istatistikleri her saniye çekmek yerine, verileri bir buffer (tampon) içinde toplayıp 5-10 saniyelik periyotlarla işlemek CPU üzerindeki yükü ciddi oranda azaltacaktır.

Sıkça Sorulan Sorular

Docker API'sine erişirken "Access Denied" hatası alıyorum, ne yapmalıyım?

Bu genellikle kullanıcı hesabınızın docker grubuna dahil olmamasından kaynaklanır. Linux sistemlerde sudo usermod -aG docker $USER komutu ile yetkiyi güncelleyebilir ve oturumu kapatıp açabilirsiniz.

Konteyner istatistikleri neden JSON formatında geliyor?

Docker, API üzerinden verileri yapılandırılmış veri alışverişi için JSON formatında sunar. C# tarafında System.Text.Json kullanarak bu verileri kolayca nesnelere dönüştürebilirsiniz.

Uygulamayı bir konteyner içinde çalıştırabilir miyim?

Evet, izleme aracınızı da bir konteyner olarak çalıştırabilirsiniz. Bunun için Docker soketini (/var/run/docker.sock) konteynerinize volume olarak bağlamanız (mount) yeterlidir.

CPU kullanım yüzdesini nasıl doğru hesaplarım?

Docker API'si ham CPU verisi sağlar. Yüzdeyi hesaplamak için (delta_cpu / delta_system) * 100 formülünü kullanmalısınız. Bu, hem konteynerin hem de ana makinenin CPU kullanımındaki değişimi baz alır.

Bu aracı üretim ortamında kullanabilir miyim?

Evet, ancak hata yönetimi (try-catch blokları), loglama ve bağlantı kopmalarına karşı yeniden bağlanma (reconnection) mekanizmalarını eklemeniz şarttır.

İleri Seviye İzleme: Veri Görselleştirme ve Zaman Serisi Entegrasyonu

Topladığınız ham Docker verilerini anlamlı kılmak için bu verileri bir zaman serisi veritabanına aktarmak en profesyonel yaklaşımdır. InfluxDB, Docker metriklerini saklamak için endüstri standardıdır. Aşağıdaki örnek, C# uygulamanızdan InfluxDB'ye nasıl veri yazabileceğinizi gösterir.

InfluxDB'ye Metrik Gönderme

Öncelikle projenize InfluxDB.Client NuGet paketini ekleyin. Ardından, Docker'dan çektiğiniz CPU ve bellek verilerini şu şekilde işleyebilirsiniz:

using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Writes;

public async Task WriteMetricToInflux(string containerName, double cpuUsage, double memoryUsage)
{
    var client = InfluxDBClientFactory.Create("http://localhost:8086", "my-token");
    var point = PointData.Measurement("docker_stats")
        .Tag("container_name", containerName)
        .Field("cpu_usage", cpuUsage)
        .Field("memory_usage", memoryUsage)
        .Timestamp(DateTime.UtcNow, WritePrecision.Ns);

    using (var writeApi = client.GetWriteApiAsync())
    {
        await writeApi.WritePointAsync(point, "my-bucket", "my-org");
    }
}

Uygulama Performansını Optimize Etme

Docker API'si ile sürekli iletişim kurmak (polling), özellikle yüzlerce konteynerin olduğu sistemlerde ağ trafiğini ve CPU'yu yorabilir. Performansı artırmak için şu stratejileri uygulayın:

  • Asenkron Akış (Streaming): Docker.DotNet kütüphanesinin sağladığı GetContainerStatsAsync metodunu kullanırken, verileri sürekli bir döngü yerine IProgress veya Channel yapıları ile asenkron olarak tüketin.
  • Önbellekleme (Caching): Konteyner isimleri ve ID'leri gibi statik bilgiler her saniye değişmez. Bu verileri bir MemoryCache içinde saklayın ve sadece yeni konteyner eklendiğinde veya silindiğinde güncelleyin.
  • Batch İşleme: Veritabanına her saniye tek bir veri yazmak yerine, verileri bir ConcurrentQueue içinde biriktirip 5-10 saniyelik paketler halinde (batch) gönderin.

Hata Ayıklama (Debugging) ve Loglama

Docker API bağlantısının koptuğu durumları yönetmek için Polly kütüphanesini kullanarak bir "Retry" (Yeniden Deneme) stratejisi oluşturun. Bağlantı hatalarını izlemek için Microsoft.Extensions.Logging kullanarak yapılandırılmış loglar tutun.

// Polly ile bağlantı hatası yönetimi
var retryPolicy = Policy
    .Handle()
    .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));

await retryPolicy.ExecuteAsync(async () => 
{
    await _dockerClient.Containers.ListContainersAsync(new ContainersListParameters());
});

Bu yapı, ağ dalgalanmalarında uygulamanızın çökmesini engeller ve sistemin kendi kendini onarmasına olanak tanır. Özellikle Docker daemon'ın yeniden başlatıldığı senaryolarda bu mekanizma hayati önem taşır.

Sonuç

C# ile kendi Docker izleme aracınızı oluşturmak, .NET yeteneklerinizi sistem mimarisi ile birleştirmenin en etkili yoludur. Bu rehberde, Docker API bağlantısı kurmayı, konteynerleri listelemeyi ve gerçek zamanlı performans verilerini okumayı öğrendiniz. Bir sonraki adım olarak, bu verileri bir veritabanına (örneğin InfluxDB) kaydederek zaman serisi grafiklerini oluşturabilir veya belirli bir eşik aşıldığında e-posta/SMS gönderen bir bildirim sistemi ekleyebilirsiniz.

Yasal Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamlarında kullanmadan önce tüm güvenlik açıklarını gözden geçirmeli ve gerekli ağ izolasyonlarını sağlamalısınız.

Bu yazıya tepkinizi paylaşın:
Mert Özdemir

Teknoloji ve dijital dünyadaki karmaşık süreçleri adım adım rehberlerle sadeleştiriyorum. Kullanıcıların dijital araçlardan en yüksek verimi alması için anlaşılır ve öğretici içerikler yazıyorum.

Yorumlar (0)

Yorum Yaz