16 Haziran 2020 Salı

Systemd ile Linux Sistem Kaynak Yönetimi: RHEL 7/8/9/10 Kapsamlı Rehberi

Systemd ile Linux Sistem Kaynak Yönetimi: RHEL 7/8/9/10 Kapsamlı Rehberi

Giriş

Modern Linux dağıtımlarının neredeyse tamamı systemd servis yöneticisini kullanmaktadır. RHEL 7'den itibaren varsayılan olarak gelen systemd, sistem kaynaklarının yönetimi konusunda güçlü özellikler sunar. Bu rehberde, Redis, Apache, Nginx, PHP gibi kritik servislerin kaynak limitlerini nasıl yöneteceğinizi öğreneceksiniz.

Neden Kaynak Limitleri Önemli?

Varsayılan sistem limitleri, yüksek trafikli veya kaynak yoğun uygulamalar için yetersiz kalabilir. Doğru yapılandırılmamış limitler şu sorunlara yol açabilir:

  • Performans Düşüşü: Servisler gerekli kaynaklara erişemediğinde yavaşlar
  • Servis Kesintileri: "Too many open files" gibi hatalarla karşılaşılabilir
  • Sistem Kararsızlığı: Kontrolsüz kaynak tüketimi tüm sistemi etkileyebilir
  • Güvenlik Riskleri: DoS saldırılarına karşı savunmasız kalabilirsiniz

Systemd Kaynak Limit Parametreleri

Temel Limit Direktifleri

Systemd'de kullanabileceğiniz kaynak limit parametreleri ve karşılıkları:

Direktifulimit KarşılığıAçıklamaVarsayılan Değer (RHEL 8/9)
LimitCPUulimit -tCPU süre limiti (saniye)infinity
LimitFSIZEulimit -fMaksimum dosya boyutuinfinity
LimitDATAulimit -dMaksimum veri segment boyutuinfinity
LimitSTACKulimit -sStack boyutu8MB
LimitCOREulimit -cCore dump dosya boyutu0 (devre dışı)
LimitRSSulimit -mMaksimum resident set sizeinfinity
LimitNOFILEulimit -nMaksimum açık dosya sayısı1024 (soft), 4096 (hard)
LimitASulimit -vSanal bellek limitiinfinity
LimitNPROCulimit -uMaksimum process sayısı62735 (RHEL 8), 31367 (RHEL 9)
LimitMEMLOCKulimit -lKilitlenebilir bellek64KB
LimitLOCKSulimit -xDosya kilitleri sayısıinfinity
LimitSIGPENDINGulimit -iBekleyen sinyal sayısı62735
LimitMSGQUEUEulimit -qPOSIX mesaj kuyruğu boyutu819200
LimitNICEulimit -eNice öncelik limiti0
LimitRTPRIOulimit -rReal-time öncelik limiti0
LimitRTTIMEYokReal-time CPU süresiinfinity

Pratik Uygulama Örnekleri

Örnek 1: Redis Servis Limitlerini Ayarlama

Redis gibi yüksek performanslı in-memory veritabanları için limit ayarları kritiktir.

Adım 1: Servisi Düzenleme Modunda Açma

bash
# RHEL 7/8/9/10 için geçerli
systemctl edit redis.service

Not: --force --full parametreleri yerine sadece edit kullanmak, override dosyası oluşturur ve daha güvenlidir.

Adım 2: Limit Parametrelerini Ekleme

ini
[Service]
# Dosya tanımlayıcı limiti (Redis için kritik)
LimitNOFILE=65535

# Process limiti
LimitNPROC=32768

# Bellek kilitleme limiti (persistence için)
LimitMEMLOCK=infinity

# Core dump boyutu (debugging için)
LimitCORE=infinity

Adım 3: Değişiklikleri Uygulama

bash
# Systemd'yi yeniden yükle
systemctl daemon-reload

# Servisi yeniden başlat
systemctl restart redis.service

# Limitleri kontrol et
systemctl show redis.service | grep -i limit

Örnek 2: Apache/Nginx Web Sunucuları için Optimizasyon

Web sunucuları çok sayıda eşzamanlı bağlantı yönetir:

bash
systemctl edit httpd.service  # RHEL için Apache
# veya
systemctl edit nginx.service  # Nginx için
ini
[Service]
# Yüksek trafikli siteler için
LimitNOFILE=131072
LimitNPROC=8192

# Keep-alive bağlantıları için
LimitSIGPENDING=16384

# SSL/TLS işlemleri için
LimitMEMLOCK=infinity

Örnek 3: PHP-FPM için Ayarlar

bash
systemctl edit php-fpm.service
ini
[Service]
# PHP process limitleri
LimitNOFILE=32768
LimitNPROC=4096

# Opcode cache için
LimitMEMLOCK=256M

# Upload işlemleri için
LimitFSIZE=infinity

Gelişmiş Kaynak Yönetimi: CGroup v2 ile CPU ve Bellek Kontrolü

RHEL 8'den itibaren CGroup v2 desteği ile daha hassas kaynak kontrolü mümkündür.

CPU Kullanımını Sınırlandırma

Yöntem 1: CPUQuota (Yüzde Bazlı)

bash
# Servisin maksimum %50 CPU kullanmasını sağla
systemctl set-property redis.service CPUAccounting=yes
systemctl set-property redis.service CPUQuota=50%

# Çoklu çekirdek sistemlerde (örn: 4 çekirdek)
# %200 = 2 çekirdek kullanabilir
systemctl set-property nginx.service CPUQuota=200%

Yöntem 2: CPUShares (Ağırlık Bazlı)

bash
# Varsayılan: 1024 (bir çekirdek)
# Yüksek öncelik: 2048 (iki çekirdek ağırlığı)
systemctl set-property postgresql.service CPUShares=2048

Bellek Kullanımını Sınırlandırma

bash
# Bellek muhasebesi aktifleştir
systemctl set-property mysql.service MemoryAccounting=yes

# Maksimum 4GB bellek kullanımı
systemctl set-property mysql.service MemoryLimit=4G

# RHEL 9/10 için yeni sözdizimi
systemctl set-property mysql.service MemoryMax=4G
systemctl set-property mysql.service MemorySwapMax=1G

Disk I/O Sınırlandırma

bash
# Disk I/O muhasebesi
systemctl set-property elasticsearch.service BlockIOAccounting=yes

# Okuma/yazma hızı limitleri (byte/saniye)
systemctl set-property elasticsearch.service IOReadBandwidthMax="/dev/sda 50M"
                                             
systemctl set-property elasticsearch.service IOWriteBandwidthMax="/dev/sda 30M"

# I/O ağırlığı (10-1000 arası, varsayılan: 100)
systemctl set-property elasticsearch.service BlockIOWeight=200

Kullanıcı Bazlı Kaynak Yönetimi

🔒 SSH ve Konsol Kullanıcıları için Kapsamlı Güvenlik

Kritik Uyarı: SSH veya konsol üzerinden bağlanan kullanıcılar, limit konulmadığında sistemin tüm kaynaklarını tüketebilir. Bu durum sistem çökmelerine, servis kesintilerine ve güvenlik açıklarına yol açabilir.

SSH Servisi için Çok Katmanlı Koruma

Katman 1: SSH Servisinin Kendisi için Limitler

bash
# SSH daemon için kaynak limitleri
systemctl edit sshd.service
ini
[Service]
# CPU limitleri - SSH servisi maksimum %30 CPU kullanabilir
CPUAccounting=yes
CPUQuota=30%

# Bellek limitleri - Brute-force ve bellek saldırılarına karşı
MemoryAccounting=yes
MemoryMax=1G
MemorySwapMax=512M

# Process ve thread limitleri
LimitNPROC=256
TasksMax=256

# Dosya tanımlayıcı limiti
LimitNOFILE=4096

# Core dump'ı devre dışı bırak (güvenlik için)
LimitCORE=0

# Nice değeri (düşük öncelik)
LimitNICE=5

Katman 2: Tüm SSH Oturumları için Genel Limitler

bash
# SSH üzerinden bağlanan TÜM kullanıcılar için toplu limit
systemctl edit user.slice
ini
[Slice]
# Tüm kullanıcı oturumları TOPLAM %70 CPU kullanabilir
CPUAccounting=yes
CPUQuota=70%
CPUWeight=50

# Bellek limitleri (tüm kullanıcılar toplamı)
MemoryAccounting=yes
MemoryMax=8G
MemorySwapMax=2G
MemoryHigh=6G  # Soft limit - bu değere yaklaşınca sistem baskı uygular

# I/O limitleri
IOAccounting=yes
IOWeight=50
IOReadBandwidthMax=/dev/sda 100M
IOWriteBandwidthMax=/dev/sda 50M

# Process limitleri
TasksMax=2048

# Realtime öncelik engelleme (güvenlik için)
RestrictRealtime=yes

Katman 3: SSH Session Başına Limitler

bash
# Her SSH bağlantısı için ayrı limit
systemctl edit session-*.scope
ini
[Scope]
# Her oturum maksimum %10 CPU
CPUQuota=10%

# Oturum başına bellek
MemoryMax=512M

# Oturum başına process limiti
TasksMax=128

Kullanıcı Gruplarına Göre Farklı Limitler

Geliştirici Kullanıcılar için

bash
# developers grubundaki kullanıcılar için
systemctl edit --force user-slice-developers.slice
ini
[Slice]
# Geliştiriciler daha fazla kaynak kullanabilir
CPUQuota=40%
MemoryMax=4G
TasksMax=1024

# Ancak I/O sınırlı
IOWeight=30
IOReadBandwidthMax=/dev/sda 50M

Misafir/Geçici Kullanıcılar için

bash
# guest kullanıcıları için çok sıkı limitler
systemctl edit --force user-$(id -u guest).slice
ini
[Slice]
# Minimal kaynak kullanımı
CPUQuota=5%
CPUWeight=10
MemoryMax=256M
MemorySwapMax=0  # Swap kullanamaz
TasksMax=50

# Çok sıkı I/O limiti
IOWeight=10
IOReadBandwidthMax=/dev/sda 10M
IOWriteBandwidthMax=/dev/sda 5M

# Zaman limiti (30 dakika sonra sonlandır)
RuntimeMaxSec=1800

Belirli Kullanıcı için Özel Limitler

bash
# Örnek: postgres kullanıcısı için özel limit
systemctl edit --force user-$(id -u postgres).slice
ini
[Slice]
CPUQuota=25%
MemoryMax=8G
TasksMax=1024

Fork Bomb ve Resource Exhaustion Saldırılarına Karşı Koruma

bash
# Anti fork-bomb koruması
cat > /etc/systemd/system/user-.slice.d/10-fork-bomb-protection.conf << EOF
[Slice]
# Fork bomb koruması
TasksMax=10000
TasksAccounting=yes

# Hızlı process oluşturma engelleme
StartLimitInterval=2s
StartLimitBurst=5

# CPU ve bellek koruması
CPUQuota=80%
MemoryMax=80%
MemorySwapMax=0

# Agresif OOM killer
OOMPolicy=kill
OOMScoreAdjust=100
EOF

systemctl daemon-reload

PAM Entegrasyonu ile Kullanıcı Limitleri

bash
# /etc/security/limits.d/90-systemd-user.conf
cat > /etc/security/limits.d/90-systemd-user.conf << EOF
# Tüm kullanıcılar için hard limitler
*    hard    nproc     1000
*    hard    nofile    4096
*    hard    memlock   64
*    hard    cpu       60
*    hard    nice      5

# SSH kullanıcıları için özel
@ssh-users    hard    nproc     500
@ssh-users    hard    nofile    2048
@ssh-users    hard    cpu       30
@ssh-users    soft    cpu       20

# Root hariç herkes için
!root    hard    core      0
EOF

Gerçek Zamanlı İzleme ve Alarm

bash
#!/bin/bash
# /usr/local/bin/ssh_resource_monitor.sh

# SSH kullanıcılarının kaynak kullanımını izle
while true; do
    echo "=== SSH Kullanıcı Kaynak Raporu - $(date) ==="
    
    # Aktif SSH oturumları
    ss -tnp | grep :22 | while read line; do
        PID=$(echo $line | grep -oP 'pid=\K[0-9]+')
        if [ ! -z "$PID" ]; then
            USER=$(ps -p $PID -o user= 2>/dev/null)
            
            # CPU ve bellek kullanımı
            CPU=$(ps -p $PID -o %cpu= 2>/dev/null)
            MEM=$(ps -p $PID -o %mem= 2>/dev/null)
            
            echo "Kullanıcı: $USER | PID: $PID | CPU: $CPU% | MEM: $MEM%"
            
            # Eşik kontrolü
            if (( $(echo "$CPU > 50" | bc -l) )); then
                logger -p warning "SSH kullanıcısı $USER yüksek CPU kullanıyor: $CPU%"
                # İsteğe bağlı: kullanıcıyı uyar veya sonlandır
                # systemctl kill --signal=TERM user-$(id -u $USER).slice
            fi
        fi
    done
    
    # Slice kullanımları
    echo -e "\n=== Slice Kaynak Kullanımı ==="
    systemd-cgtop -n 1 | grep -E "user-.*\.slice|session-.*\.scope"
    
    sleep 10
done

Otomatik Temizleme ve Zaman Aşımı

bash
# Idle SSH bağlantılarını otomatik sonlandır
cat > /etc/systemd/system/ssh-idle-cleanup.service << EOF
[Unit]
Description=SSH Idle Session Cleanup
After=sshd.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup-idle-ssh.sh

[Install]
WantedBy=multi-user.target
EOF

cat > /usr/local/bin/cleanup-idle-ssh.sh << EOF
#!/bin/bash
# 30 dakikadan uzun süredir idle olan SSH oturumlarını kapat

IDLE_TIME=1800  # 30 dakika

w -h | while read user tty from login idle rest; do
    if [[ "\$idle" =~ ^[0-9]+:[0-9]+$ ]]; then
        hours=\$(echo \$idle | cut -d: -f1)
        mins=\$(echo \$idle | cut -d: -f2)
        total_mins=\$((hours * 60 + mins))
        
        if [ \$total_mins -gt 30 ]; then
            echo "Kullanıcı \$user idle süresi aşmış, sonlandırılıyor..."
            pkill -u \$user
            logger -p info "SSH kullanıcısı \$user idle timeout nedeniyle sonlandırıldı"
        fi
    fi
done
EOF

chmod +x /usr/local/bin/cleanup-idle-ssh.sh

# Timer ile periyodik çalıştır
cat > /etc/systemd/system/ssh-idle-cleanup.timer << EOF
[Unit]
Description=Run SSH Idle Cleanup every 15 minutes

[Timer]
OnBootSec=15min
OnUnitActiveSec=15min

[Install]
WantedBy=timers.target
EOF

systemctl enable --now ssh-idle-cleanup.timer

Test ve Doğrulama

bash
# 1. Mevcut limitleri kontrol et
systemctl show sshd.service | grep -E "Limit|Memory|CPU|Tasks"
systemctl show user.slice | grep -E "Memory|CPU|Tasks"

# 2. Kullanıcı olarak test et
su - testuser
# Fork bomb testi (DİKKAT: test ortamında yapın!)
:(){ :|:& };:
# Sistem korumalı ise "Resource temporarily unavailable" hatası almalısınız

# 3. Stress test
sysbench cpu --cpu-max-prime=20000 run
sysbench memory --memory-block-size=1M --memory-total-size=10G run
sysbench fileio --file-total-size=10G prepare
sysbench fileio --file-total-size=10G --file-test-mode=rndwrite run

# Limitler çalışıyorsa CPU %10-20'yi geçmemeli

# 4. Gerçek zamanlı izleme
systemd-cgtop
watch -n 1 'systemctl status user.slice | grep -E "Memory|CPU|Tasks"'

İzleme ve Kontrol Araçları

1. Systemd Native Araçları

bash
# Kaynak kullanımını canlı izleme
systemd-cgtop

# CGroup hiyerarşisini görüntüleme
systemd-cgls

# Belirli servisin kaynak kullanımı
systemctl status redis.service --no-pager -l

# Detaylı kaynak istatistikleri
systemd-analyze dump | grep -A10 redis.service

2. CGroup Araçları

bash
# CGroup listesi
lscgroup

# CGroup istatistikleri (RHEL 8+)
cat /sys/fs/cgroup/system.slice/redis.service/memory.current
cat /sys/fs/cgroup/system.slice/redis.service/cpu.stat

3. Monitoring Script Örneği

bash
#!/bin/bash
# kaynak_monitor.sh

SERVICE="redis.service"

echo "=== $SERVICE Kaynak Kullanımı ==="
echo "CPU Kullanımı:"
systemctl show $SERVICE -p CPUUsageNSec --value

echo "Bellek Kullanımı:"
systemctl show $SERVICE -p MemoryCurrent --value | numfmt --to=iec

echo "Açık Dosya Sayısı:"
systemctl show $SERVICE -p LimitNOFILE --value

echo "Process Sayısı:"
systemctl show $SERVICE -p TasksCurrent --value

RHEL Versiyonlarına Göre Önemli Farklar

RHEL 7

  • CGroup v1 kullanır
  • MemoryLimit parametresi kullanılır
  • systemd versiyon 219

RHEL 8

  • CGroup v2 desteği (hybrid mod)
  • MemoryMax parametresi eklenmiş
  • systemd versiyon 239
  • Gelişmiş kaynak muhasebesi

RHEL 9

  • Varsayılan olarak CGroup v2
  • MemorySwapMax desteği
  • systemd versiyon 250
  • Gelişmiş PSI (Pressure Stall Information) desteği

RHEL 10 (Önizleme)

  • Tam CGroup v2 entegrasyonu
  • systemd versiyon 255+
  • Gelişmiş eBPF entegrasyonu
  • Daha hassas kaynak kontrolü

En İyi Uygulamalar ve Öneriler

1. Aşamalı Yaklaşım

  • Önce mevcut kullanımı ölçün
  • Küçük artışlarla limitleri ayarlayın
  • Test ortamında deneyin
  • Production'a kontrollü geçiş yapın

2. Monitoring Entegrasyonu

  • Prometheus + Grafana ile görselleştirme
  • Alerting kuralları tanımlayın
  • Düzenli performans testleri yapın

3. Dokümantasyon

  • Her değişikliği kaydedin
  • Neden-sonuç ilişkilerini belirtin
  • Rollback planı hazırlayın

4. Güvenlik Perspektifi

  • En az yetki prensibi
  • DDoS koruması için limitler
  • Resource exhaustion saldırılarına karşı önlem

Sorun Giderme

Sık Karşılaşılan Hatalar ve Çözümleri

Hata: "Too many open files"

bash
# Çözüm
systemctl edit problematic.service
# LimitNOFILE=65535 ekleyin

Hata: "Cannot allocate memory"

bash
# Çözüm
# Bellek limitini kontrol edin
systemctl show service.name -p MemoryMax
# Gerekirse artırın
systemctl set-property service.name MemoryMax=8G

Hata: "Resource temporarily unavailable"

bash
# Çözüm
# Process limitini artırın
systemctl set-property service.name TasksMax=4096

Özet

Systemd ile kaynak yönetimi, modern Linux sistemlerinde performans ve stabilite için kritiktir. Bu rehberde öğrendikleriniz:

  • Temel limit parametreleri ve kullanımları
  • Servis bazlı kaynak sınırlandırma
  • CPU, bellek ve I/O kontrolü
  • Kullanıcı bazlı limitler
  • İzleme ve sorun giderme teknikleri

Unutmayın: Her sistem farklıdır. Bu değerleri kendi ihtiyaçlarınıza göre ayarlayın ve mutlaka test edin.

Referanslar

Hiç yorum yok:

Yorum Gönder

Büyük hacimli diskleri niye 512 sector ile kullanalım 4096 byte lık sector kullanabilirken !

 Günümüzde güncel linux dağıtımlarının hepsi 4096byte sector ile sorunsuz çalışmaktadır.  Yukarıda görüldüğü gibi diskler 512/4096 byte şekl...