Proxmox VE + Ceph HCI: Swap Sorunu ve Kalıcı Çözüm v9.x

Proxmox + Ceph HCI ortamında swap dolduğunda ne olur, neden tehlikelidir ve nasıl kalıcı olarak çözülür adım adım.

Swap Dolarsa Ne Olur?

Ceph OSD’ler yavaşlar. OSD swap’a düştüğünde RAM↔disk I/O yerine RAM↔swap I/O yapıyor. Heartbeat’e geç cevap verir, cluster HEALTH_WARN alır, uzarsa OSD down olarak işaretlenir ve rebalance başlar.

VM’ler etkilenir. QEMU process’i swap’a düşünce VM içindeki uygulama yavaşlar, “disk yavaş” gibi görünür — asıl sorun host memory’dir.

En kötü senaryo: OOM Killer. Swap tamamen dolarsa kernel en fazla memory kullanan process’i öldürür. Bu ceph-osd veya bir QEMU process olabilir. OSD ölürse HEALTH_ERR, QEMU ölürse VM aniden kapanır.

Neden Oldu?

Linux kernel’inin varsayılan vm.swappiness değeri 60’tır. Bu “RAM dolmasa bile idle sayfaları swap’a at” demek. Proxmox kurulumunda Debian bu değere dokunmaz. Uzun uptime boyunca küçük küçük biriken swap kullanımı %90’ı aşabilir — sistem çalışıyor çünkü RAM hâlâ bol, ama tetikleyici bir olay (backup, recovery, yoğun I/O) gelince patlama noktasına dönüşür.

Proxmox staff’ın HCI ortamları için önerisi: swappiness = 10.

PVE 9 Notu: /etc/sysctl.conf artık yok. Tüm ayarlar /etc/sysctl.d/ altına yazılıyor.
1
Mevcut Durumu Gör

Başlamadan önce ne durumda olduğunu belge altına al.

bash
echo "=== SWAP DURUMU ===" && free -h
echo "=== SWAPPINESS ===" && cat /proc/sys/vm/swappiness
echo "=== EN FAZLA SWAP KULLANANLAR ==="
cat /proc/*/status 2>/dev/null | \
  awk '/^Name/{name=$2} /^VmSwap/{if($2>0) print $2" kB --> "name}' | \
  sort -rn | head -10

Beklenen çıktı:

çıktı
=== SWAP DURUMU ===
Swap:          8.0Gi       7.4Gi     614Mi

=== SWAPPINESS ===
60

=== EN FAZLA SWAP KULLANANLAR ===
2854288 kB --> kvm
808100 kB  --> kvm
254860 kB  --> ceph-mgr
101072 kB  --> ceph-osd
2
Swap’ı Güvenli Temizle

Swap’taki tüm sayfalar RAM’e geri çekilir. Önce yeterli RAM olduğunu doğrula:

bash
awk '/MemAvailable/{avail=$2} /SwapTotal/{total=$2} /SwapFree/{free=$2}
     END{
       used=total-free;
       print "RAM Available : " avail/1024/1024 " GiB";
       print "Swap Used     : " used/1024/1024 " GiB";
       if(avail > used)
         print "SONUC: Guvenli, devam edebilirsin";
       else
         print "SONUC: UYARI - Yeterli RAM yok!";
     }' /proc/meminfo

“Güvenli, devam edebilirsin” yazıyorsa swap’ı temizle:

bash
swapoff -a && swapon -a
⚠️ Birkaç dakika sürebilir, disk IO artar. Mesai saati dışında yap.

Temizlendi mi kontrol et:

bash
free -h
# Swap: used → 0 olmalı
3
Kalıcı Çözüm — swappiness 10 Yap

Swap temizlendi ama swappiness hâlâ 60 ise birkaç ay sonra aynı yere dönersin.

bash
echo "vm.swappiness=10" > /etc/sysctl.d/99-proxmox-hci-tuning.conf
sysctl -p /etc/sysctl.d/99-proxmox-hci-tuning.conf
cat /proc/sys/vm/swappiness
# Çıktı: 10
4
Son Kontrol
bash
echo "=== SWAPPINESS ===" && cat /proc/sys/vm/swappiness
echo "=== SWAP DURUMU ===" && free -h | grep Swap
echo "=== AYAR DOSYASI ===" && cat /etc/sysctl.d/99-proxmox-hci-tuning.conf

Beklenen çıktı:

çıktı
=== SWAPPINESS ===
10

=== SWAP DURUMU ===
Swap:   8.0Gi    0B    8.0Gi

=== AYAR DOSYASI ===
vm.swappiness=10

Tüm Cluster İçin Toplu Script

MacBook veya Linux bir OS üzerinden çalıştırılır. sshpass ile root şifresi kullanır, tüm node’lara sırayla bağlanır.

Gereksinim: brew install sshpass

Script’i oluştur:

bash
cat > ~/swap-fix.sh << 'SCRIPT'
#!/bin/bash
# ============================================================
# Proxmox VE + Ceph HCI — Swap Tuning Script
# Cluster : prx-test (10 node)
# Tarih   : 2026-06-23
# Yazar   : Burak
# ============================================================

ROOT_PASS="buraya_root_sifresini_yaz"

NODES=(
  prx-test-01
  prx-test-02
  prx-test-03
  prx-test-04
  prx-test-05
  prx-test-06
  prx-test-07
  prx-test-08
  prx-test-09
  prx-test-10
)

GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

ok()   { echo -e "${GREEN}[OK]${NC}   $1"; }
err()  { echo -e "${RED}[ERR]${NC}  $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
inf()  { echo -e "${BLUE}[INFO]${NC} $1"; }

apply_node() {
  local NODE=$1
  echo ""
  echo "============================================"
  inf "Node: $NODE"
  echo "============================================"

  sshpass -p "$ROOT_PASS" ssh \
    -o StrictHostKeyChecking=no \
    -o ConnectTimeout=10 \
    root@"$NODE" bash << 'REMOTE'

HOST=$(hostname)
SWAP_TOTAL=$(awk '/SwapTotal/{print $2}' /proc/meminfo)
SWAP_FREE=$(awk '/SwapFree/{print $2}'   /proc/meminfo)
MEM_AVAIL=$(awk '/MemAvailable/{print $2}' /proc/meminfo)
SWAP_USED=$((SWAP_TOTAL - SWAP_FREE))

echo "[$HOST] Mevcut swappiness : $(cat /proc/sys/vm/swappiness)"
echo "[$HOST] Swap used         : $((SWAP_USED/1024)) MiB"
echo "[$HOST] RAM available     : $((MEM_AVAIL/1024)) MiB"

echo "vm.swappiness=10" > /etc/sysctl.d/99-proxmox-hci-tuning.conf
sysctl -p /etc/sysctl.d/99-proxmox-hci-tuning.conf > /dev/null
echo "[$HOST] swappiness -> $(cat /proc/sys/vm/swappiness)"

if [ "$SWAP_USED" -eq 0 ]; then
  echo "[$HOST] Swap zaten temiz, atlanıyor."
elif [ "$MEM_AVAIL" -gt "$SWAP_USED" ]; then
  echo "[$HOST] Swap temizleniyor..."
  swapoff -a && swapon -a
  NEW_USED=$(awk '/SwapFree/{f=$2}/SwapTotal/{t=$2}END{print (t-f)/1024}' /proc/meminfo)
  echo "[$HOST] Swap temizlendi. Kalan: ${NEW_USED} MiB"
else
  echo "[$HOST] UYARI: RAM yetersiz, swap temizlenemedi!"
fi

echo "[$HOST] SONUÇ | swappiness: $(cat /proc/sys/vm/swappiness) | swap used: $(awk '/SwapFree/{f=$2}/SwapTotal/{t=$2}END{print (t-f)/1024}' /proc/meminfo) MiB"
REMOTE

  if [ $? -eq 0 ]; then
    ok "Node $NODE tamamlandı."
  else
    err "Node $NODE — bağlantı hatası!"
  fi

  if [ "$NODE" != "${NODES[-1]}" ]; then
    warn "30 saniye bekleniyor..."
    sleep 30
  fi
}

if ! command -v sshpass &> /dev/null; then
  err "sshpass yok. Kur: brew install sshpass"
  exit 1
fi

echo ""
echo "============================================"
inf "Swap Tuning Script başlıyor"
inf "Toplam node: ${#NODES[@]}"
echo "============================================"

for NODE in "${NODES[@]}"; do
  apply_node "$NODE"
done

echo ""
echo "============================================"
ok "TÜM NODE'LAR TAMAMLANDI"
echo "============================================"
SCRIPT

chmod +x ~/swap-fix.sh

Şifreyi yaz, çalıştır:

bash
nano ~/swap-fix.sh
# ROOT_PASS satırını düzenle

bash ~/swap-fix.sh

Özet

Adım İşlem Kalıcı mı?
1 Mevcut durumu gör
2 swapoff -a && swapon -a ✗ Tek seferlik
3 vm.swappiness=10 yaz ✓ Reboot sonrası da geçerli
4 Son kontrol
Neden swap tamamen kapatılmadı?
Nadir de olsa OSD veya QEMU anlık memory spike yaşayabilir. Swap bu durumda OOM kill yerine zaman kazandırır. HCI ortamında swap’ı tamamen kaldırmak önerilmez.
Neden 10?
Proxmox staff’ın HCI ortamları için önerdiği değer. “Gerçekten mecbur kalmadıkça gitme” anlamına gelir. 0 yapmak modern kernel’de swap’ı tamamen kapatmaz, sadece ağırlığı düşürür.

Bu makale gerçek bir production ortamında uygulanan operasyon adımları esas alınarak hazırlanmıştır.

Bir sonraki yazımızda görüşmek üzere. Faydalı olması dileğiyle.