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ı:
Direktif | ulimit Karşılığı | Açıklama | Varsayılan Değer (RHEL 8/9) |
---|---|---|---|
LimitCPU | ulimit -t | CPU süre limiti (saniye) | infinity |
LimitFSIZE | ulimit -f | Maksimum dosya boyutu | infinity |
LimitDATA | ulimit -d | Maksimum veri segment boyutu | infinity |
LimitSTACK | ulimit -s | Stack boyutu | 8MB |
LimitCORE | ulimit -c | Core dump dosya boyutu | 0 (devre dışı) |
LimitRSS | ulimit -m | Maksimum resident set size | infinity |
LimitNOFILE | ulimit -n | Maksimum açık dosya sayısı | 1024 (soft), 4096 (hard) |
LimitAS | ulimit -v | Sanal bellek limiti | infinity |
LimitNPROC | ulimit -u | Maksimum process sayısı | 62735 (RHEL 8), 31367 (RHEL 9) |
LimitMEMLOCK | ulimit -l | Kilitlenebilir bellek | 64KB |
LimitLOCKS | ulimit -x | Dosya kilitleri sayısı | infinity |
LimitSIGPENDING | ulimit -i | Bekleyen sinyal sayısı | 62735 |
LimitMSGQUEUE | ulimit -q | POSIX mesaj kuyruğu boyutu | 819200 |
LimitNICE | ulimit -e | Nice öncelik limiti | 0 |
LimitRTPRIO | ulimit -r | Real-time öncelik limiti | 0 |
LimitRTTIME | Yok | Real-time CPU süresi | infinity |
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
# 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
[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
# 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:
systemctl edit httpd.service # RHEL için Apache
# veya
systemctl edit nginx.service # Nginx için
[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
systemctl edit php-fpm.service
[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ı)
# 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ı)
# 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
# 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
# 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
# SSH daemon için kaynak limitleri
systemctl edit sshd.service
[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
# SSH üzerinden bağlanan TÜM kullanıcılar için toplu limit
systemctl edit user.slice
[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
# Her SSH bağlantısı için ayrı limit
systemctl edit session-*.scope
[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
# developers grubundaki kullanıcılar için
systemctl edit --force user-slice-developers.slice
[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
# guest kullanıcıları için çok sıkı limitler
systemctl edit --force user-$(id -u guest).slice
[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
# Örnek: postgres kullanıcısı için özel limit
systemctl edit --force user-$(id -u postgres).slice
[Slice]
CPUQuota=25%
MemoryMax=8G
TasksMax=1024
Fork Bomb ve Resource Exhaustion Saldırılarına Karşı Koruma
# 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
# /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
#!/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ı
# 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
# 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ı
# 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ı
# 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
#!/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"
# Çözüm
systemctl edit problematic.service
# LimitNOFILE=65535 ekleyin
Hata: "Cannot allocate memory"
# Çö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"
# Çö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.
Hiç yorum yok:
Yorum Gönder