00 LVM mimarisi — PV, VG, LV, thin pool
LVM (Logical Volume Manager), blok cihaz yönetiminde esneklik katmanı sağlar. Thin provisioning, fiziksel disk alanı talep esasına (on-demand) tahsis ederek aşırı commit sağlar.
Fiziksel Disk (HDD/SSD/NVMe)
│
▼
PV (Physical Volume) — pvcreate ile işaretlenir
│ (/dev/sda2, /dev/nvme0n1p3 ...)
▼
VG (Volume Group) — bir veya birden fazla PV'yi birleştirir
│
├── Thick LV — klasik, alan hemen tahsis edilir
│
└── Thin Pool LV — havuz (metadata LV + data LV)
│
├── Thin LV 1 — sanal boyut ≥ gerçek kullanım
├── Thin LV 2
└── Thin LV N (snapshot dahil)
01 Thin pool oluşturma ve yapılandırma
Thin pool'u doğru boyutlandırmak kritiktir: metadata LV'si toplam thin LV boyutuna göre hesaplanmalıdır. Aşırı tahsis (overcommit) dikkatli izleme gerektirir.
## 1. Physical Volume oluştur
pvcreate /dev/sdb
# Physical volume "/dev/sdb" successfully created.
## 2. Volume Group oluştur
vgcreate vg_data /dev/sdb
# Volume group "vg_data" successfully created
## 3. Thin pool LV oluştur
# Toplam 100 GB pool, metadata için %1 = 1 GB
lvcreate --type thin-pool \
--size 100G \
--poolmetadatasize 1G \
--name pool0 \
vg_data
# Veya tek komutla (lvm2 >= 2.02.112)
lvcreate -L 100G --thinpool vg_data/pool0
## 4. Chunk size ve zero mode ayarla
lvchange --zero n vg_data/pool0 # yeni yazımda sıfırlama yapma
lvchange --discards passdown vg_data/pool0 # TRIM/DISCARD SSD'ye ilet
Pool metadata boyutlandırma formülü
Metadata boyutu = (2 × chunk_count × 64 byte) + 128 MB
Chunk size varsayılan: 64 KB
100 GB pool için chunk sayısı = 100 × 1024 × 1024 KB / 64 KB = 1.638.400
Metadata = (2 × 1.638.400 × 64 byte) + 128 MB
= 200 MB + 128 MB = 328 MB → 512 MB tahsis etmek güvenli
# Metadata kullanımını kontrol et:
lvs -o+metadata_percent vg_data/pool0
/etc/lvm/lvm.conf — otomatik genişleme
activation {
thin_pool_autoextend_threshold = 80 # %80 dolunca tetikle
thin_pool_autoextend_percent = 20 # %20 büyüt
}
02 Thin LV oluşturma ve kullanım
Thin LV, pool'dan sanal alan tahsis eder. Fiziksel boyutu başlangıçta 0'dır; yazıldıkça chunk'lar tahsis edilir. Bu davranış SSD ve flash tabanlı depolamada avantajlıdır.
## Thin LV oluştur (sanal boyut: 50 GB, gerçek tahsis: 0)
lvcreate --thin --name lv_app \
--virtualsize 50G \
vg_data/pool0
## Dosya sistemi oluştur
mkfs.ext4 /dev/vg_data/lv_app
## Mount et
mkdir -p /mnt/app
mount /dev/vg_data/lv_app /mnt/app
## /etc/fstab kaydı
echo "/dev/vg_data/lv_app /mnt/app ext4 defaults,discard 0 2" \
>> /etc/fstab
## Gerçek kullanımı göster
lvs -o name,vg_name,lv_size,data_percent,pool_lv vg_data
# LV VG LSize Data% Pool
# lv_app vg_data 50.00g 8.00 pool0
# pool0 vg_data 100.00g 12.00
Aşırı tahsis (overcommit) senaryosu
## 100 GB fiziksel pool, toplam 300 GB sanal tahsis
lvcreate --thin -n lv_prod -V 100G vg_data/pool0
lvcreate --thin -n lv_test -V 100G vg_data/pool0
lvcreate --thin -n lv_backup -V 100G vg_data/pool0
## Gerçek yazım yapılmadıkça fiziksel yer tüketilmez
lvs -o name,lv_size,data_percent vg_data
# lv_prod 100.00g 0.00
# lv_test 100.00g 0.00
# lv_backup 100.00g 0.00
# pool0 100.00g 0.00
03 Snapshot — anlık görüntü alma ve geri yükleme
LVM thin snapshot'ları, kaynak LV ile aynı veri bloklarını paylaşır (Copy-on-Write). Alınması neredeyse anlık olup disk alanı yalnızca değişen bloklar için tüketilir.
## Snapshot al (kaynak: lv_app)
lvcreate --snapshot --name lv_app_snap1 \
/dev/vg_data/lv_app
# Thin snapshot: ek alan gerekmez, anında oluşur
## Snapshot listesi
lvs -o name,origin,lv_size,data_percent vg_data | grep snap
## Snapshot'ı mount et (salt okunur veya yazılabilir)
mkdir -p /mnt/snap1
mount -o ro /dev/vg_data/lv_app_snap1 /mnt/snap1
## Snapshot'ı birleştir (geri yükle) — kaynak mount'u çıkar
umount /mnt/app
lvconvert --merge /dev/vg_data/lv_app_snap1
# Eğer LV kullanımdaysa birleştirme sonraki mount'ta otomatik gerçekleşir
## Anlık görüntü kaldır
lvremove /dev/vg_data/lv_app_snap1
Otomatik düzenli snapshot (systemd timer)
[Unit]
Description=LVM Thin Snapshot — lv_app
After=local-fs.target
[Service]
Type=oneshot
ExecStart=/bin/bash -c '\
SNAP="lv_app_$(date +%%Y%%m%%d_%%H%%M)"; \
lvcreate --snapshot --name "$SNAP" /dev/vg_data/lv_app; \
echo "Snapshot alındı: $SNAP"; \
# 7 günden eski snapshot'ları sil: \
lvs --noheadings -o lv_name vg_data | \
grep lv_app_snap | sort | head -n -7 | \
xargs -r -I {} lvremove -f /dev/vg_data/{}'
[Unit]
Description=Günlük LVM snapshot
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
systemctl enable --now lvm-snapshot.timer
04 Thin LV ve pool yeniden boyutlandırma
Thin LV boyutu çevrimiçi (online) olarak artırılabilir. Pool kapasitesi dolmaya yaklaştığında yeni PV ekleyerek genişletme yapılır.
## Thin LV sanal boyutunu artır (çevrimiçi)
lvextend -L +20G /dev/vg_data/lv_app
resize2fs /dev/vg_data/lv_app # ext4 için
# veya: xfs_growfs /mnt/app # XFS için
## Pool'a fiziksel disk ekle
pvcreate /dev/sdc
vgextend vg_data /dev/sdc
lvextend -L +50G vg_data/pool0 # pool'u genişlet
## Thin LV küçültme (dikkat: çevrimdışı gerektirebilir)
umount /mnt/app
e2fsck -f /dev/vg_data/lv_app
resize2fs /dev/vg_data/lv_app 30G
lvreduce -L 30G /dev/vg_data/lv_app
Otomatik genişleme izleme script'i
#!/bin/bash
POOL="vg_data/pool0"
THRESHOLD=85 # %85 eşiği
EXTEND_GB=20
while true; do
DATA_PCT=$(lvs --noheadings -o data_percent "$POOL" | tr -d ' ')
DATA_PCT=${DATA_PCT%.*} # ondalık kısım at
if [ "${DATA_PCT:-0}" -ge "$THRESHOLD" ]; then
echo "UYARI: Pool doluluk $DATA_PCT% — genişletiliyor"
lvextend -L "+${EXTEND_GB}G" /dev/vg_data/pool0
logger -t lvm-monitor "Pool genişletildi +${EXTEND_GB}GB (was ${DATA_PCT}%)"
fi
sleep 60
done
05 Docker storage driver olarak LVM thin
Docker'ın devicemapper sürücüsü, LVM thin provisioning üzerine inşa edilmiştir. Her container ve image, ayrı thin LV olarak depolanır. Özellikle RHEL/CentOS tabanlı sistemlerde tercih edilir.
## Docker için ayrı VG
pvcreate /dev/sdd
vgcreate docker_vg /dev/sdd
## /etc/docker/daemon.json
cat > /etc/docker/daemon.json <<'EOF'
{
"storage-driver": "devicemapper",
"storage-opts": [
"dm.thinpooldev=/dev/mapper/docker_vg-thinpool",
"dm.use_deferred_removal=true",
"dm.use_deferred_deletion=true",
"dm.fs=ext4",
"dm.basesize=20G"
]
}
EOF
## Thin pool oluştur (Docker için)
lvcreate --type thin-pool \
--size 80G \
--poolmetadatasize 512M \
--zero n \
-n thinpool docker_vg
systemctl restart docker
docker info | grep -A5 "Storage Driver"
devicemapper performans notları
06 dm-verity — blok cihaz bütünlük doğrulama
dm-verity, bir blok cihazın her bloğunu okuma sırasında hash ile doğrular. Android, Chrome OS ve gömülü Linux'ta rootfs değişmezliği garantisi için kullanılır. Merkle ağacı (hash tree) yapısı üzerine kuruludur.
Veri Bloğu 0 Veri Bloğu 1 ... Veri Bloğu N
│ │ │
▼ ▼ ▼
Hash(0) Hash(1) ... Hash(N) — Level 0
│ │ │
└───────┬────────────────────────────┘
▼
Hash(Hash(0..K)) ... Hash(Hash(...)) — Level 1
│
└─── ... ─── Root Hash (32 byte, SHA-256)
Root hash → kernel komut satırında veya bootloader'da sabit tutulur
Her okumada: veri hash == beklenen hash → ERR veya panic
veritysetup ile dm-verity hash ağacı oluşturma
## veritysetup kurulum
sudo apt install cryptsetup-bin
## 1. Salt okunur dosya sistemi görüntüsü oluştur
# (önceden ext4/squashfs ile doldurulmuş)
dd if=/dev/zero of=rootfs.img bs=1M count=512
mkfs.ext4 rootfs.img
# ... rootfs içeriğini kopyala ...
## 2. Hash ağacını oluştur
veritysetup format rootfs.img verity_hash.img
# VERITY header information for rootfs.img
# UUID: a1b2c3d4-...
# Hash type: 1
# Data block size: 4096
# Hash block size: 4096
# Data blocks: 131072
# Salt: aabbccdd...
# Root hash: 7f3e2a1b... ← bu hash kritik
ROOT_HASH=$(veritysetup format rootfs.img verity_hash.img | \
grep "Root hash:" | awk '{print $3}')
echo "Root hash: $ROOT_HASH"
dm-verity cihazını aktifleştir
## dm-verity cihazını oluştur
veritysetup open rootfs.img verity_root \
verity_hash.img "$ROOT_HASH"
# /dev/mapper/verity_root oluştu
## Salt okunur mount et
mount -o ro /dev/mapper/verity_root /mnt/rootfs
## Bütünlük doğrulama (manuel)
veritysetup verify rootfs.img verity_hash.img "$ROOT_HASH"
# Verification is successful.
07 dm-verity ile salt okunur rootfs
Gömülü sistemlerde rootfs'i dm-verity ile korumak, fiziksel erişim olan saldırganların bile dosya sistemi değiştirmesini imkansız kılar. Kernel panigi yerine yazılabilir overlay ile üretim esnekliği sağlanabilir.
Kernel komut satırı ile dm-verity
LABEL linux
KERNEL /boot/Image
FDT /boot/imx8qm.dtb
APPEND console=ttyLP0,115200 \
root=/dev/mapper/verity_rootfs ro \
rootfstype=ext4 \
dm-mod.create="verity_rootfs,,,ro,\
0 1048576 verity \
1 /dev/mmcblk0p2 /dev/mmcblk0p3 \
4096 4096 131072 131072 sha256 \
7f3e2a1b4c5d6e7f8a9b0c1d2e3f4a5b \
aabbccdd1122334455667788"
Overlay ile yazılabilir katman
## tmpfs veya ayrı bölümde üst katman
mount -t tmpfs tmpfs /overlay
mkdir -p /overlay/upper /overlay/work
## overlayfs: dm-verity (salt okunur) + tmpfs (yazılabilir)
mount -t overlay overlay \
-o lowerdir=/mnt/verity_root,\
upperdir=/overlay/upper,\
workdir=/overlay/work \
/newroot
## /tmp, /var, /etc gibi yazılabilir alanlar upperdir'de saklanır
## Yeniden başlatmada upperdir temizlenir → deterministik durum
08 LVM metadata yönetimi ve izleme
LVM thin pool'da metadata LV dolması, data LV dolmasından daha kritiktir. Metadata dolduğunda tüm I/O durdurulur; proaktif izleme zorunludur.
İzleme komutları
## Detaylı LV durumu
lvs -o name,lv_size,data_percent,metadata_percent,\
pool_lv,origin,lv_attr vg_data
## Pool ve thin LV özeti
lvdisplay /dev/vg_data/pool0
# --- Logical volume ---
# LV Size 100.00 GiB
# Allocated pool data 45.23%
# Allocated metadata 12.07%
## Sürekli izleme (her 5 saniyede)
watch -n5 "lvs -o name,data_percent,metadata_percent vg_data"
## dmeventd ile otomatik izleme aktif et
lvchange --monitor y vg_data/pool0
Prometheus ile LVM metrik toplama
#!/bin/bash
# /etc/prometheus/node_exporter_textfile/lvm.prom
OUTPUT="/var/lib/node_exporter/textfile_collector/lvm.prom"
TMPFILE=$(mktemp)
echo "# HELP lvm_thin_data_percent LVM thin pool data percent" > "$TMPFILE"
echo "# TYPE lvm_thin_data_percent gauge" >> "$TMPFILE"
lvs --noheadings -o vg_name,lv_name,data_percent \
--select 'lv_is_thin_pool=1' | while read vg lv pct; do
pct=${pct:-0}
echo "lvm_thin_data_percent{vg=\"$vg\",lv=\"$lv\"} $pct" >> "$TMPFILE"
done
mv "$TMPFILE" "$OUTPUT"
09 Üretim en iyi pratikleri ve sorun giderme
LVM thin provisioning güçlü bir araçtır; yanlış yapılandırılmış pool'lar veri kaybına yol açabilir. Aşağıdaki pratikler üretim ortamı için temel rehberdir.
Üretim kontrol listesi
Yaygın sorunlar ve çözümler
## Sorun: "No space left" hatası (pool doldu)
# Hızlı çözüm: yeni PV ekle
pvcreate /dev/sde
vgextend vg_data /dev/sde
lvextend -l +100%FREE vg_data/pool0
## Sorun: Metadata %100 (KRİTİK)
# Cihazlar askıya alınır. Acil genişletme:
lvextend --poolmetadatasize +512M vg_data/pool0
## Sorun: Thin LV "error" durumunda
lvs -o name,lv_health_status vg_data
# eğer "partial" → bazı PE'ler kayıp
# Yedekten geri yükleme gerekebilir
## Pool sağlık kontrolü
lvdisplay vg_data/pool0 | grep -E "health|active|status"
## Metadata dump (teşhis amaçlı)
dmsetup status vg_data-pool0
# 0 204800000 thin-pool 0/20480 408/4096 - rw no_discard_passdown queue_if_no_space