Linux Cgroups v2 ile Kaynak İzolasyonu ve Yönetimi: Derinlemesine Bir Bakış

 · 

Linux Cgroups v2 ile Kaynak İzolasyonu ve Yönetimi: Derinlemesine Bir Bakış

Linux Cgroups v2 ile Kaynak İzolasyonu ve Yönetimi: Derinlemesine Bir Bakış

Linux sistemlerinde çalışan süreçlerin kaynak tüketimini kontrol altında tutmak, stabilite ve öngörülebilir performans sağlamak için kritik bir öneme sahiptir. Cgroups (Control Groups) teknolojisi, bir grup süreci belirli kaynak kısıtlamalarına tabi tutarak bu kontrolü mümkün kılar. Özellikle Cgroups v2, selefi v1'in karmaşıklıklarını gidererek ve daha yetenekli bir mimari sunarak modern konteynerizasyon ve sistem yönetimi ihtiyaçlarına daha iyi yanıt verir.

Cgroups v1'den v2'ye Geçiş: Temel Farklar ve Birleşik Hiyerarşi

Cgroups v1, birden fazla bağımsız hiyerarşi ve kontrolcü (CPU, bellek, I/O gibi) ile çalışırken, bu durum yönetimde karmaşıklıklara ve çakışan davranışlara yol açabiliyordu. Cgroups v2, bu sorunları tek, birleşik ve ağaç benzeri bir hiyerarşi sunarak çözer. Bu birleşik hiyerarşi, kaynakların daha tutarlı bir şekilde yönetilmesini ve her kontrolcünün yalnızca tek bir hiyerarşiye ait olmasını sağlar. Delegasyon modeli sayesinde, alt gruplara kaynak yönetimi yetkisi devredilebilir, bu da konteyner orkestrasyon sistemleri için hayati bir özelliktir.

Cgroups v2 hiyerarşisi genellikle `/sys/fs/cgroup` altında bulunur. Bir sistemde v2'nin aktif olup olmadığını kontrol etmek için:

mount | grep cgroup2

Çıktı genellikle şöyle görünür:

cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)

Bu, sistemin Cgroups v2'yi kullandığını ve `nsdelegate` seçeneğiyle namespace delegasyonuna izin verdiğini gösterir.

Çekirdek Kaynak Kontrolörleri ve Yapılandırma

Cgroups v2, CPU, bellek ve I/O gibi temel sistem kaynaklarını yönetmek için çeşitli kontrolörler sunar. Her kontrolcü, kendi alt dizininde kaynak limitlerini ve istatistiklerini barındıran dosyalar içerir.

CPU Kaynak Yönetimi (`cpu` kontrolörü)

CPU kontrolörü, süreç gruplarına atanacak CPU süresini belirler. Cgroups v2'de `cpu.max` ve `cpu.weight` olmak üzere iki ana parametre öne çıkar.

  • cpu.max: Belirli bir zaman dilimi (genellikle 100ms) içinde bir cgroup'a tanınan maksimum CPU süresini belirler. Örneğin, "50000 100000" değeri, cgroup'un 100ms'lik dilimde 50ms (yani CPU'nun %50'si) kullanabileceği anlamına gelir.
  • cpu.weight: Bir cgroup'un CPU kaynakları üzerindeki nispi ağırlığını belirler (1'den 10000'e kadar, varsayılan 100). Bu, birden fazla cgroup aynı anda CPU talep ettiğinde, ağırlığına göre orantılı olarak CPU süresi almasını sağlar.

Senaryo: Yoğun Raporlama Servisinin İzolasyonu

Bir sunucu üzerinde hem kritik ön uç web servisleri hem de yoğun CPU kullanan arka plan raporlama servisleri çalıştığını varsayalım. Raporlama servisinin anlık yükselen CPU kullanımı, web servislerinin yanıt sürelerini etkilememelidir. Bunun için raporlama servisini ayrı bir cgroup'a alıp CPU limitini belirleyebiliriz. Systemd ile bir servis için bu limitleri ayarlamak en yaygın yöntemdir:

# /etc/systemd/system/raporlama.service.d/cpu.conf[Service]CPUShares=200CPUQuota=50%

Yukarıdaki konfigürasyon, `raporlama.service` için CPU ağırlığını (CPUShares) varsayılanın iki katına çıkarırken, `CPUQuota=50%` ile maksimum CPU kullanımını tek bir çekirdeğin %50'si ile sınırlar. Bu sayede raporlama servisi, ihtiyaç duyduğunda daha fazla CPU alabilir ancak hiçbir zaman belirlenen %50'lik limiti aşamaz.

Bellek Kaynak Yönetimi (`memory` kontrolörü)

Bellek kontrolörü, bir cgroup'un kullanabileceği RAM ve swap alanını sınırlar.

  • memory.max: Bir cgroup'un kullanabileceği maksimum RAM miktarını belirler.
  • memory.swap.max: Bir cgroup'un kullanabileceği maksimum swap alanı miktarını belirler.
  • memory.high: Bellek kullanımının bu seviyeye ulaştığında, cgroup içindeki süreçlerin belleği geri bırakması için agresif önlemlerin alınmasını tetikler.

Senaryo: Bellek Sızıntısı Olası Bir Uygulamanın Kontrolü

Geliştirme aşamasında olan veya potansiyel bellek sızıntısı riski taşıyan bir uygulamanın (örneğin, yeni bir Python mikroservisi) tüm sunucunun belleğini tüketerek diğer kritik servisleri etkilemesini önlemek için bellek limiti belirlemek elzemdir.

# /etc/systemd/system/yeni-mikroservis.service.d/memory.conf[Service]MemoryMax=2GMemorySwapMax=1G

Bu ayar, `yeni-mikroservis.service`'in 2GB RAM ve 1GB swap alanından fazla kullanmasını engeller. Limite ulaşıldığında, OOM (Out Of Memory) katili devreye girerek cgroup içindeki süreçleri sonlandırabilir, ancak bu sayede tüm sistemin belleksizlikten çökmesi engellenmiş olur.

I/O Kaynak Yönetimi (`io` kontrolörü)

I/O kontrolörü, disk I/O'sunu sınırlar. Bu, özellikle paylaşımlı depolama ortamlarında veya disk yoğun operasyonlarda diğer servislerin performansının düşmesini engellemek için önemlidir.

  • io.max: Belirli bir disk cihazı için okuma/yazma bant genişliği (bytes/s) veya I/O operasyonları (IOPS) limitini belirler.
  • io.weight: Bir cgroup'un belirli bir cihaz üzerindeki I/O önceliğini belirler.

Senaryo: Disk Yoğun Yedekleme İşleminin İzolasyonu

Bir veritabanı sunucusu üzerinde gece yapılan tam yedekleme işlemleri, disk I/O'sunu aşırı derecede yükselterek gün içindeki kritik veritabanı işlemlerinin performansını etkileyebilir. Yedekleme script'ini çalıştıran sürecin I/O'sunu sınırlayarak bu etki minimize edilebilir.

Önce disk cihazının major:minor numaralarını bulalım:

lsblk -o NAME,MAJ:MIN

Diyelim ki `/dev/sda` için `8:0` olsun. Ardından, bir cgroup oluşturup I/O limitlerini manuel olarak ayarlayabiliriz (veya systemd ile):

mkdir /sys/fs/cgroup/yedeklemeecho "8:0 50M" > /sys/fs/cgroup/yedekleme/io.maxecho <PID_yedekleme_islemi> > /sys/fs/cgroup/yedekleme/cgroup.procs

Bu örnek, `/dev/sda` üzerindeki yazma bant genişliğini saniyede 50 megabayt ile sınırlar. Okuma ve yazma için ayrı ayrı veya toplam olarak limitler tanımlanabilir. Systemd birimleri genellikle bu tür manuel adımların önüne geçer ve daha kalıcı çözümler sunar.

Gerçek Dünya Senaryoları ve En İyi Uygulamalar

Konteyner Ortamlarında Cgroups v2

Docker, Podman ve Kubernetes gibi modern konteyner orkestrasyon platformları, arkada Cgroups v2'yi kullanarak konteynerler arası kaynak izolasyonunu sağlar. Kubernetes'te bir pod veya konteyner için CPU ve bellek `requests` ve `limits` tanımladığınızda, bu değerler Cgroups v2 tarafından yorumlanır ve ilgili kontrolcü dosyalarına yazılır.

Senaryo: Çoklu Kiracılı Kubernetes Kümesinde Noisy Neighbor Sorunu

Bir geliştirme veya test Kubernetes kümesinde, farklı ekiplerin podları aynı worker node'lar üzerinde çalışıyor olabilir. Bir ekibin kötü yazılmış veya kaynak tüketen bir uygulaması (noisy neighbor), aynı node üzerindeki diğer ekiplerin kritik servislerinin performansını düşürebilir. Kubernetes'teki `resource.limits` tanımı, bu tür senaryoları engellemek için doğrudan Cgroups v2'den faydalanır.

apiVersion: v1kind: Podmetadata:  name: bellek-limitli-uygulamaspec:  containers:  - name: my-container    image: my-image:latest    resources:      limits:        memory: "512Mi"        cpu: "500m"      requests:        memory: "256Mi"        cpu: "250m"

Burada `limits.memory` ve `limits.cpu`, podun Cgroups v2'deki `memory.max` ve `cpu.max` değerlerini belirleyerek, o podun kaynak kullanımını garanti altına alır ve aynı zamanda diğer podlar için kaynakların korunmasını sağlar.

Servis Stabilizasyonu ve Performans İzolasyonu

Bir sunucu üzerinde çalışan kritik bir veritabanı (PostgreSQL) servisi ile bir yedekleme ajanı arasında kaynak çekişmesini düşünelim. Veritabanı, düşük gecikmeli I/O ve tutarlı CPU gerektirirken, yedekleme ajanı burstable CPU ve I/O kullanabilir.

Veritabanı servisi için daha yüksek öncelik ve garantili kaynaklar tanımlayarak, yedekleme işlemi sırasında bile veritabanı performansının korunmasını sağlayabiliriz. Systemd'nin `CPUWeight`, `IOWeight`, `MemoryMax` gibi direktifleri bu izolasyonu kolaylaştırır.

İzleme ve Metrikler

Cgroups v2, kaynak kullanımını izlemek için zengin metrikler sunar. Her cgroup dizininde `cpu.stat`, `memory.stat`, `io.stat` gibi dosyalar bulunur. Bu dosyaları okuyarak bir cgroup'un CPU kullanımı, bellek tüketimi (kullanılan RAM, önbellek vb.), I/O operasyonları ve bant genişliği hakkında detaylı bilgilere ulaşılabilir.

cat /sys/fs/cgroup/system.slice/nginx.service/cpu.stat

Çıktı örnek olarak şuna benzer:

usage_usec 1234567890user_usec 987654321system_usec 246913569nr_periods 123nr_throttled 12throttled_usec 5000000

Burada `usage_usec` toplam CPU kullanımını mikrosaniye cinsinden gösterir, `nr_throttled` ise CPU limitine ulaşıldığı için kaç kez sürecin kısıtlandığını belirtir. Bu metrikler, Prometheus gibi izleme sistemleri tarafından toplanarak görselleştirilebilir ve olası performans darboğazlarını veya kaynak çekişmelerini tespit etmek için kullanılabilir.

Linux Cgroups v2, modern sistem yönetimi ve konteynerizasyon için vazgeçilmez bir temel katman sunar. Doğru yapılandırma ve izleme ile sistem kaynaklarının verimli, adil ve öngörülebilir bir şekilde dağıtılmasını sağlayarak, karmaşık üretim ortamlarında dahi yüksek performans ve stabilite elde etmek mümkündür.

← Blog Listesine Dön