Product SiteDocumentation Site

Capitolo 12. Amministrazione avanzata

12.1. RAID e LVM
12.1.1. RAID software
12.1.2. LVM
12.1.3. RAID o LVM?
12.2. Virtualizzazione
12.2.1. Xen
12.2.2. LXC
12.2.3. Virtualizzazione con KVM
12.3. Installazione automatica
12.3.1. Fully Automatic Installer (FAI)
12.3.2. Preimpostare Debian-Installer
12.3.3. Simple-CDD: la soluzione completa
12.4. Monitoraggio
12.4.1. Impostazione di Munin
12.4.2. Impostazione di Nagios
Questo capitolo rivede alcuni aspetti già descritti in precedenza, ma da una diversa prospettiva: invece di installare una singola macchina, si studiano sistemi di allestimento più vasti; invece di creare volumi RAID o LVM durante l'installazione, si descrive la procedura per farlo a mano in modo da poter rivedere in seguito le scelte iniziali. Infine, si discutono strumenti di monitoraggio e tecniche di virtualizzazione. Di conseguenza, questo capitolo è più orientato agli amministratori professionisti e meno ai singoli individui responsabili della rete di casa propria.

12.1. RAID e LVM

Capitolo 4, Installazione ha presentato queste tecnologie dal punto di vista dell'installatore e di come questi li integrava per rendere il loro allestimento facile fin dall'inizio. Dopo l'installazione iniziale, un amministratore deve poter far fronte alle mutevoli necessità di spazio disco senza dover ricorrere a una reinstallazione costosa. Deve pertanto padroneggiare gli strumenti richiesti per manipolare volumi RAID e LVM.
RAID e LVM sono entrambi tecniche per astrarre i volumi montati dalle loro controparti fisiche (gli effettivi dischi fissi o le loro partizioni); il primo rende sicuri i dati introducendo una ridondanza, l'ultimo rende la gestione dei dati più flessibile e indipendente dall'effettiva dimensione dei dischi sottostanti. In entrambi i casi, il sistema acquisisce nuovi device a blocchi, che possono essere usati per creare file system o spazio di swap, senza necessariamente essere mappati su un unico disco fisico. RAID e LVM vengono da storie molto diverse, ma le loro funzionalità spesso si possono sovrapporre, che è il motivo per cui spesso vengono menzionati insieme.
Sia nel RAID che nell'LVM, il kernel fornisce un file di device a blocchi, simile a quelli corrispondenti a un disco fisso o a una partizione. Quando un'applicazione o un'altra parte del kernel richiede l'accesso a un blocco di questo device, il sottosistema appropriato dirige il blocco allo strato fisico di competenza. A seconda della configurazione, questo blocco può essere memorizzato su uno o più dischi fisici e la sua posizione fisica potrebbe non essere direttamente correlata alla posizione del blocco nel device logico.

12.1.1. RAID software

RAID significa Redundant Array of Independent Disks (array ridondante di dischi indipendenti). Lo scopo di questo sistema è di impedire la perdita di dati in caso di guasto di un disco fisso. Il principio generale è molto semplice: i dati sono memorizzati su diversi dischi fisici piuttosto che su uno solo, con un livello di ridondanza configurabile. A seconda della quantità di ridondanza e anche in caso di guasto inatteso di un disco, i dati possono essere ricostruiti dai dischi rimanenti, senza alcuna perdita.
Il RAID può essere implementato sia tramite hardware dedicato (moduli RAID integrati in schede con controllori SCSI o SATA) sia tramite astrazione software (il kernel). Che sia hardware o software, un sistema RAID con sufficiente ridondanza può rimanere operativo in modo trasparente quando un disco si guasta; gli strati superiori della pila (applicazioni) possono perfino continuare ad accedere ai dati nonostante il guasto. Ovviamente questa «modalità degradata» può avere un impatto sulle prestazioni e inoltre viene ridotta la ridondanza, quindi un ulteriore guasto di un disco può provocare perdita di dati. In pratica, perciò, si cerca di rimanere in questa modalità degradata solo per il tempo necessario a sostituire il disco guasto. Una volta che il nuovo disco è al suo posto, il sistema RAID può ricostruire i dati richiesti e così tornare in modalità sicura. Le applicazioni non si accorgeranno di alcunché, a parte per la velocità di accesso potenzialmente ridotta, mentre l'array è in modalità degradata o durante la fase di ricostruzione.

12.1.1.1. Diversi livelli di RAID

Il RAID ha in realtà diversi livelli, che si distinguono per la loro disposizione e la quantità di ridondanza che forniscono. Più è ridondante, più è a prova di guasti, dal momento che il sistema sarà in grado di continuare a funzionare con più dischi rotti. Il difetto è che lo spazio utilizzabile diminuisce; visto in un altro modo, servono più dischi per memorizzare la stessa quantità di dati.
RAID lineare
Anche se il sottosistema del kernel permette di creare un «RAID lineare», questo non è un RAID vero e proprio, poiché questa configurazione non prevede alcuna ridondanza. Il kernel semplicemente aggrega diversi dischi in fila e mette a disposizione il volume aggregato che ne risulta come un unico disco virtuale (un unico device a blocchi). Questa è praticamente la sua unica funzione. Questa configurazione è raramente usata da sola (vedere più avanti per le eccezioni), soprattutto in quanto la mancanza di ridondanza implica che basta un guasto a un singolo disco per rendere l'intero aggregato, e dunque tutti i dati, indisponibile.
RAID-0
Anche questo livello non fornisce alcuna ridondanza, ma i dischi non sono semplicemente messi in fila uno dietro l'altro: sono divisi in strisce e i blocchi sul device virtuale sono memorizzati su strisce su dischi fisici alternati. In un'impostazione RAID-0 a due dischi, per esempio, i blocchi di numero pari del device virtuale saranno memorizzati sul primo disco fisico, mentre i blocchi di numero dispari finiranno sul secondo disco fisico.
Questo sistema non mira ad aumentare l'affidabilità, in quanto (come nel caso lineare) la disponibilità di tutti i dati è a rischio non appena un disco si guasta, ma ad aumentare le prestazioni: durante l'accesso sequenziale a grandi quantità di dati contigui, il kernel potrà leggere da entrambi i dischi (o scrivere su di essi) in parallelo, il che aumenta la velocità di trasferimento dei dati. Tuttavia l'uso del RAID-0 sta diminuendo, in quanto LVM sta prendendo il suo posto (vedere più avanti).
RAID-1
Questo livello, noto anche come «RAID mirroring», è la configurazione più semplice e più usata. Nella sua forma standard, usa due dischi fisici della stessa grandezza e fornisce un volume logico anch'esso della stessa grandezza. I dati sono memorizzati in modo identico su entrambi i dischi, da cui il soprannome «mirror». Quando un disco si guasta, i dati sono ancora disponibili sull'altro. Per dati veramente critici, il RAID-1 può ovviamente essere impostato su più di due dischi, il che ha delle conseguenze sul rapporto fra costo dell'hardware e spazio disponibile.
Questo livello di RAID, sebbene costoso (dal momento che al massimo è disponibile metà dello spazio fisico dei dischi), è ampiamente usato in pratica. È semplice da capire e permette di fare dei backup in modo molto semplice: dal momento che entrambi i dischi hanno gli stessi contenuti, uno di essi può essere temporaneamente estratto senza conseguenze sul sistema in funzione. Inoltre, spesso le prestazioni in lettura aumentano in quanto il kernel può leggere metà dati da ciascun disco in parallelo, mentre le prestazioni in scrittura non ne risentono troppo. Nel caso di un array RAID-1 di N dischi, i dati restano disponibili anche in caso si guastino N-1 dischi.
RAID-4
Questo livello di RAID, non molto usato, usa N dischi per memorizzare dati utili e un disco in più per memorizzare le informazioni di ridondanza. Se quel disco si guasta, il sistema può ricostruire i suoi contenuti a partire dagli altri N. Se uno degli N dischi con i dati si guasta, i rimanenti N-1 insieme al disco di «parità» contengono abbastanza informazioni per ricostruire i dati richiesti.
Il RAID-4 non è eccessivamente costoso, dal momento che richiede un aumento dei costi di appena uno-su-N e non ha un impatto notevole sulle prestazioni in lettura, ma le scritture ne risultano rallentate. Inoltre, dal momento che la scrittura su uno qualunque degli N dischi richiede anche una scrittura sul disco di parità, quest'ultimo riceve molte più scritture del primo e di conseguenza la sua vita può ridursi notevolmente. I dati su un array RAID-4 sono sicuri solo fino alla rottura di un solo disco (degli N+1).
RAID-5
Il RAID-5 risolve il problema di asimmetria del RAID-4: i blocchi di parità sono distribuiti su tutti gli N+1 dischi, senza che un unico disco abbia un ruolo particolare.
Le prestazioni in lettura e scrittura sono identiche al RAID-4. Anche qui il sistema rimane in funzione fino al guasto di un unico disco (degli N+1).
RAID-6
Il RAID-6 si può considerare un'estensione del RAID-5, in cui ciascuna serie di N blocchi richiede due blocchi di ridondanza e ciascuna di queste serie di N+2 blocchi viene distribuita su N+2 dischi.
Questo livello di RAID è leggermente più costoso dei due precedenti, ma fornisce un po' di sicurezza in più, dal momento che possono guastarsi fino a due dischi (degli N+2) senza compromettere la disponibilità dei dati. Il difetto è che le operazioni di scrittura ora richiedono la scrittura di un blocco di dati e due blocchi di ridondanza, il che le rende ancora più lente.
RAID-1+0
Strettamente parlando, questo non è un livello di RAID, ma un modo di impilare due gruppi di RAID. Partendo da 2×n dischi, prima si impostano a coppie in N volumi RAID-1; questi N volumi vengono quindi aggregati in uno solo, tramite «RAID lineare» o (sempre più spesso) tramite LVM. In quest'ultimo caso si va oltre il semplice RAID, ma questo non è un problema.
Il RAID-1+0 può sopravvivere al guasto di più dischi: fino a N nell'array 2×n descritto sopra, a condizione che almeno un disco continui a funzionare in ciascuna coppia RAID-1.
Ovviamente, il livello di RAID verrà scelto a seconda dei vincoli e dei requisiti di ciascuna applicazione. Notare che un solo computer può avere diversi array RAID distinti con diverse configurazioni.

12.1.1.2. Impostazione di un RAID

L'impostazione di volumi RAID richiede il pacchetto mdadm ; fornisce il comando mdadm, che permette di creare e manipolare array RAID, oltre che script e strumenti per integrarlo al resto del sistema, compreso il sistema di monitoraggio.
Questo esempio mostrerà un server con un certo numero di dischi, alcuni dei quali sono già usati e i rimanenti sono disponibili per impostare il RAID. All'inizio si hanno i seguenti dischi e partizioni:
  • il disco sda, 4 GB, è interamente disponibile;
  • il disco sde, 4 GB, è anch'esso interamente disponibile;
  • sul disco sdg, solo la partizione sdg2 (circa 4 GB) è disponibile;
  • infine, un disco sdh, di nuovo 4 GB, interamente disponibile.
Questi elementi fisici verranno usati per costruire due volumi, un RAID-0 e un mirror (RAID-1). Si inizia col volume RAID-0:
# mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/sda /dev/sde
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
# mdadm --query /dev/md0
/dev/md0: 8.00GiB raid0 2 devices, 0 spares. Use mdadm --detail for more detail.
# mdadm --detail /dev/md0
/dev/md0:
        Version : 1.2
  Creation Time : Thu Sep 30 15:21:15 2010
     Raid Level : raid0
     Array Size : 8388480 (8.00 GiB 8.59 GB)
   Raid Devices : 2
  Total Devices : 2
    Persistence : Superblock is persistent

    Update Time : Thu Sep 30 15:21:15 2010
          State : active
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

     Chunk Size : 512K

           Name : squeeze:0  (local to host squeeze)
           UUID : 0012a273:cbdb8b83:0ee15f7f:aec5e3c3
         Events : 0

    Number   Major   Minor   RaidDevice State
       0       8        0        0      active sync   /dev/sda
       1       8       64        1      active sync   /dev/sde
# mkfs.ext4 /dev/md0

mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
524288 inodes, 2097152 blocks
104857 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2147483648
55 block groups
32768 blocks per group, 32768 fragments per group
8160 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 26 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
# mkdir /srv/raid-0
# mount /dev/md0 /srv/raid-0
# df -h /srv/raid-0
Filesystem            Size  Used Avail Use% Mounted on
/dev/md0              8.0G  249M  7.4G   4% /srv/raid-0
Il comando mdadm --create richiede diversi parametri: il nome del volume da creare (/dev/md*, dove MD sta per Multiple Device), il livello di RAID, il numero di dischi (obbligatorio nonostante abbia significato perlopiù solo con RAID-1 e superiori) e i dischi fisici da usare. Una volta che il device è creato, lo si può usare come una partizione normale: ci si crea sopra un file system, lo si monta e così via. Notare che la creazione di un volume RAID-0 su md0 è solo una coincidenza: non è necessario che la numerazione dell'array sia legata alla quantità di ridondanza scelta.
La creazione di un RAID-1 segue un percorso simile, la differenza si nota solo dopo la creazione:
# mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sdg2 /dev/sdh
mdadm: largest drive (/dev/sdg2) exceed size (4194240K) by more than 1%
Continue creating array? y
mdadm: array /dev/md1 started.
# mdadm --query /dev/md1
/dev/md1: 4.00GiB raid1 2 devices, 0 spares. Use mdadm --detail for more detail.
# mdadm --detail /dev/md1
/dev/md1:
        Version : 1.2
  Creation Time : Thu Sep 30 15:39:13 2010
     Raid Level : raid1
     Array Size : 4194240 (4.00 GiB 4.29 GB)
  Used Dev Size : 4194240 (4.00 GiB 4.29 GB)
   Raid Devices : 2
  Total Devices : 2
    Persistence : Superblock is persistent

    Update Time : Thu Sep 30 15:39:26 2010
          State : active, resyncing
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

 Rebuild Status : 10% complete

           Name : squeeze:1  (local to host squeeze)
           UUID : 20a8419b:41612750:b9171cfe:00d9a432
         Events : 27

    Number   Major   Minor   RaidDevice State
       0       8       98        0      active sync   /dev/sdg2
       1       8      112        1      active sync   /dev/sdh
# mdadm --detail /dev/md1
/dev/md1:
[...]
          State : active
[...]
Bisogna fare alcune osservazioni. Prima di tutto, mdadm si accorge che gli elementi fisici hanno dimensioni diverse; poiché ciò implica che verrà perso dello spazio sull'elemento più grande, è richiesta una conferma.
Cosa ancora più importante, notare lo stato del mirror. Lo stato normale di un mirror RAID è che entrambi i dischi abbiano esattamente gli stessi contenuti. Tuttavia, nulla garantisce che ciò sia vero al momento della creazione del volume. Il sottosistema RAID perciò fornirà esso stesso questa garanzia e appena dopo la creazione del device RAID ci sarà una fase di sincronizzazione. Dopo un certo tempo (l'esatta durata dipenderà dall'effettiva dimensione dei dischi…) l'array RAID passa allo stato «attivo». Notare che durante questa fase di ricostruzione il mirror è in modalità degradata e la ridondanza non è assicurata. Durante questa fase di ricostruzione, il guasto di un disco può comportare la perdita di tutti i dati. Ad ogni modo, è raro che grandi quantità di dati critici vengano memorizzati su un array RAID appena creato prima della sincronizzazione iniziale. Notare che, anche in modalità degradata, /dev/md1 è usabile e vi si può creare sopra un file system, oltre a copiarvi sopra dei dati.
Ora si mostrerà cosa succede quando uno degli elementi dell'array RAID 1 si guasta. mdadm, in particolare la sua opzione --fail, permette di simulare uno guasto:
# mdadm /dev/md1 --fail /dev/sdh
mdadm: set /dev/sdh faulty in /dev/md1
# mdadm --detail /dev/md1
/dev/md1:
[...]
    Update Time : Thu Sep 30 15:45:50 2010
          State : active, degraded
 Active Devices : 1
Working Devices : 1
 Failed Devices : 1
  Spare Devices : 0

           Name : squeeze:1  (local to host squeeze)
           UUID : 20a8419b:41612750:b9171cfe:00d9a432
         Events : 35

    Number   Major   Minor   RaidDevice State
       0       8       98        0      active sync   /dev/sdg2
       1       0        0        1      removed

       2       8      112        -      faulty spare  /dev/sdh
I contenuti del volume sono ancora accessibili (e, se montato, le applicazioni non si accorgono di alcunché), ma la sicurezza dei dati non è più assicurata; se il disco sdg dovesse guastarsi a sua volta, i dati sarebbero persi. Poiché è meglio evitare questo rischio, si va a sostituire il disco guasto con uno nuovo, sdi:
# mdadm /dev/md1 --add /dev/sdi
mdadm: added /dev/sdi
# mdadm --detail /dev/md1
/dev/md1:
[...]
   Raid Devices : 2
  Total Devices : 3
    Persistence : Superblock is persistent

    Update Time : Thu Sep 30 15:52:29 2010
          State : active, degraded, recovering
 Active Devices : 1
Working Devices : 2
 Failed Devices : 1
  Spare Devices : 1

 Rebuild Status : 45% complete

           Name : squeeze:1  (local to host squeeze)
           UUID : 20a8419b:41612750:b9171cfe:00d9a432
         Events : 53

    Number   Major   Minor   RaidDevice State
       0       8       98        0      active sync   /dev/sdg2
       3       8      128        1      spare rebuilding   /dev/sdi

       2       8      112        -      faulty spare   /dev/sdh
# [...]
[...]
# mdadm --detail /dev/md1
/dev/md1:
[...]
    Update Time : Thu Sep 30 15:52:35 2010
          State : active
 Active Devices : 2
Working Devices : 2
 Failed Devices : 1
  Spare Devices : 0

           Name : squeeze:1  (local to host squeeze)
           UUID : 20a8419b:41612750:b9171cfe:00d9a432
         Events : 71

    Number   Major   Minor   RaidDevice State
       0       8       98        0      active sync   /dev/sdg2
       1       8      128        1      active sync   /dev/sdi

       2       8      112        -      faulty spare   /dev/sdh
Anche qui il kernel attiva automaticamente una fase di ricostruzione durante la quale il volume, sebbene ancora accessibile, è in modalità degradata. Una volta finita la ricostruzione, l'array RAID torna a uno stato normale. A questo punto si può dire al sistema che il disco sdh sta per essere rimosso dall'array, così da arrivare a un classico mirror RAID su due dischi:
# mdadm /dev/md1 --remove /dev/sdh
mdadm: hot removed /dev/sdh from /dev/md1
# mdadm --detail /dev/md1
/dev/md1:
[...]
    Number   Major   Minor   RaidDevice State
       0       8       98        0      active sync   /dev/sdg2
       1       8      128        1      active sync   /dev/sdi
Da questo punto il drive può essere rimosso fisicamente al prossimo spegnimento del server, o anche rimosso a caldo quando la configurazione hardware permette l'hot-swap. Tali configurazioni includono alcuni controller SCSI, la maggior parte dei dischi SATA e i dischi esterni che operano su USB o Firewire.

12.1.1.3. Fare il backup della configurazione

La maggior parte dei meta-dati riguardanti i volumi RAID sono salvati direttamente sui dischi che compongono questi array, cosicché il kernel può rilevare gli array e i loro componenti e assemblarli automaticamente all'avvio del sistema. Tuttavia, è consigliabile fare copie di riserva di questa configurazione, perché questo rilevamento non è infallibile ed è ovvio che fallisca proprio in circostanze delicate. Nell'esempio in questione, se il guasto al disco sdh fosse stato reale (invece di essere solo una simulazione) e il sistema si fosse riavviato senza rimuovere questo disco sdh, questo disco si sarebbe attivato di nuovo, essendo stato riconosciuto durante il riavvio. A quel punto il kernel avrebbe tre elementi fisici, ciascuno dei quali direbbe di contenere metà dello stesso volume RAID. Un'altra fonte di confusione può sorgere quando volumi RAID di due server vengono consolidati su un solo server. Se questi array stavano funzionando normalmente prima che i dischi fossero spostati, il kernel potrebbe rilevare e riassemblare le coppie correttamente; ma se i dischi spostati sono stati aggregati in un md1 sul vecchio server e il nuovo server ha già un md1, uno dei mirror verrebbe rinominato.
È quindi importante fare il backup della configurazione, se non altro per avere un riferimento. Il modo standard di farlo è modificare il file /etc/mdadm/mdadm.conf, un esempio del quale è mostrato qui:

Esempio 12.1. File di configurazione di mdadm

# mdadm.conf
#
# Please refer to mdadm.conf(5) for information about this file.
#

# by default, scan all partitions (/proc/partitions) for MD superblocks.
# alternatively, specify devices to scan, using wildcards if desired.
DEVICE /dev/sd*

# auto-create devices with Debian standard permissions
CREATE owner=root group=disk mode=0660 auto=yes

# automatically tag new arrays as belonging to the local system
HOMEHOST <system>

# instruct the monitoring daemon where to send mail alerts
MAILADDR root

ARRAY /dev/md0 metadata=1.2 name=squeeze:0 UUID=6194b63f:69a40eb5:a79b7ad3:c91f20ee
ARRAY /dev/md1 metadata=1.2 name=squeeze:1 UUID=20a8419b:41612750:b9171cfe:00d9a432

Uno dei dettagli più utili è l'opzione DEVICE, che elenca i device in cui il sistema cercherà automaticamente le componenti dei volumi RAID all'avvio. Nell'esempio, in questione, il valore predefinito, partitions, è stato sostituito con una lista esplicita dei file di device, poiché si è scelto di usare dei dischi interi e non solo delle partizioni, per alcuni volumi.
Le ultime due righe nell'esempio sono quelle che permettono al kernel di scegliere in sicurezza quale numero di volume assegnare a ciascun array. I metadati memorizzati sui dischi stessi sono sufficienti a riassemblare i volumi ma non a determinare i numeri di volume (e il corrispondente nome di device /dev/md*).
Per fortuna, queste righe si possono generare automaticamente:
# mdadm --misc --detail --brief /dev/md?
ARRAY /dev/md0 metadata=1.2 name=squeeze:0 UUID=6194b63f:69a40eb5:a79b7ad3:c91f20ee
ARRAY /dev/md1 metadata=1.2 name=squeeze:1 UUID=20a8419b:41612750:b9171cfe:00d9a432
I contenuti di queste ultime due righe non dipendono dall'elenco dei dischi inclusi nel volume. Pertanto non è necessario rigenerare queste righe quando si sostituisce un disco guasto con uno nuovo. D'altro canto, bisogna avere cura di aggiornare il file quando si crea o si elimina un array RAID.

12.1.2. LVM

LVM, il Logical Volume Manager (gestore di volumi logici), è un altro approccio all'astrazione di volumi logici dai loro supporti fisici, che si focalizza sull'aumento di flessibilità piuttosto che sull'aumento di affidabilità. LVM permette di cambiare un volume logico in modo trasparente dal punto di vista delle applicazioni; per esempio, è possibile aggiungere nuovi dischi, migrare i dati in essi e rimuovere i vecchi dischi, senza smontare il volume.

12.1.2.1. Concetti relativi a LVM

Questa flessibilità si raggiunge tramite un livello di astrazione che riguarda tre concetti.
Primo, il PV (Physical Volume, volume fisico) è l'entità più vicina all'hardware: possono essere partizioni su un disco o un disco completo o anche qualunque altro dispositivo a blocchi. Notare che quando un elemento fisico viene configurato come PV per LVM vi si deve accedere solo via LVM, altrimenti il sistema si confonderà.
Un certo numero di PV può essere raggruppato in un VG (Volume Group, gruppo di volume), che è paragonabile a dei dischi che siano sia virtuali che estendibili. I VG sono astratti e non compaiono in un file di device nella gerarchia /dev, quindi non c'è rischio di usarli direttamente.
Il terzo tipo di oggetto è il LV (Logical Volume, volume logico), che è una parte di un VG; proseguendo con l'analogia fra VG e dischi, il LV è simile a una partizione. Il LV appare come device a blocchi con una voce in /dev e può essere usato come ogni altra partizione fisica (più di frequente per ospitare un filesystem o spazio di swap).
La cosa importante è che la divisione di un VG in LV è completamente indipendente dai suoi componenti fisici (i PV). Un VG con un solo componente fisico (per esempio un disco) può essere diviso in una dozzina di volumi logici; allo stesso modo, un VG può usare diversi dischi fisici e apparire come un unico grande volume logico. L'unico vincoli è che ovviamente la dimensione totale allocata ai LV non può superare la capacità totale dei PV nel gruppo di volume.
Spesso comunque ha un senso avere una certa omogeneità fra le componenti fisiche di un VG, e suddividere i VG in volumi logici che avranno modelli d'uso simili. Per esempio, se l'hardware disponibile include dischi rapidi e dischi più lenti, quelli rapidi possono essere raggruppati in un VG e quelli più lenti in un altro; blocchi del primo possono quindi essere assegnati ad applicazioni che richiedono un accesso rapido ai dati, mentre il secondo sarà tenuto per compiti meno impegnativi.
In ogni caso, è bene tenere a mente che un LV non è particolarmente legato a un singolo PV. È possibile indicare dove sono fisicamente memorizzati i dati di un LV, ma questa possibilità non è richiesta per un uso quotidiano. Al contrario: quando l'insieme dei componenti fisici di un VG evolve, il luogo fisico di stoccaggio che corrisponde a un particolare LV può essere migrato da un disco a un altro (ovviamente rimanendo all'interno dei PV assegnati ai VG).

12.1.2.2. Impostazione di un LVM

Si seguirà ora, passo per passo, il processo di impostazione di un LVM per un tipico caso d'uso: semplificare una situazione complessa di memorizzazione dati. Una tale situazione di solito si ha dopo una lunga e intricata storia fatta di misure temporanee accumulatesi nel tempo. A scopo illustrativo, si considererà un server in cui le necessità di memorizzazione sono cambiate nel tempo, arrivando ad avere alla fine un labirinto di partizioni disponibili sparse fra diversi dischi usati parzialmente. In termini più concreti, sono disponibili le seguenti partizioni:
  • sul disco sdb, una partizione sdb2, 4 GB;
  • sul disco sdc, una partizione sdc3, 3 GB;
  • il disco sdd, 4 GB, completamente disponibile;
  • sul disco sdf, una partizione sdf1, 4 GB e una partizione sdf2, 5 GB.
Inoltre, si suppone che i dischi sdb e sdf siano più veloci degli altri due.
Lo scopo è di impostare tre volumi logici per tre diverse applicazioni: un file server che richiede 5 GB di spazio disco, un database (1 GB) e un po' di spazio per i backup (12 GB). I primi due hanno bisogno di buone prestazioni, ma i backup sono meno critici in termini di velocità di accesso. Tutti questi vincoli impediscono di usare le partizioni così come sono; l'uso di LVM permette di astrarre dalla dimensione fisica dei dispositivi, cosicché l'unico limite è lo spazio totale disponibile.
Gli strumenti richiesti sono nel pacchetto lvm2 e nelle sue dipendenze. Una volta installati, impostare un LVM richiede tre passi, che corrispondono ai tre livelli di concetti.
Prima di tutto si preparano i volumi fisici usando pvcreate:
# pvdisplay
# pvcreate /dev/sdb2
  Physical volume "/dev/sdb2" successfully created
# pvdisplay

  "/dev/sdb2" is a new physical volume of "4,00 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/sdb2
  VG Name
  PV Size               4.00 GiB
  Allocatable           NO
  PE Size (KByte)       0
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               9JuaGR-W7jc-pNgj-NU4l-2IX1-kUJ7-m8cRim

# for i in sdc3 sdd sdf1 sdf2 ; do pvcreate /dev/$i ; done
  Physical volume "/dev/sdc3" successfully created
  Physical volume "/dev/sdd" successfully created
  Physical volume "/dev/sdf1" successfully created
  Physical volume "/dev/sdf2" successfully created
# pvdisplay -C
  PV         VG   Fmt  Attr PSize PFree
  /dev/sdb2       lvm2 a-   4.00g 4.00g
  /dev/sdc3       lvm2 a-   3.09g 3.09g
  /dev/sdd        lvm2 a-   4.00g 4.00g
  /dev/sdf1       lvm2 a-   4.10g 4.10g
  /dev/sdf2       lvm2 a-   5.22g 5.22g
Finora tutto bene: notare che un PV può essere impostato su tutto un disco così come su singole partizioni. Come mostrato sopra, il comando pvdisplay elenca le PV esistenti, con due possibili formati di output.
Ora si assemblano questi elementi fisici in VG usando vgcreate. Solo le PV dei dischi più veloci saranno riunite in un VG vg_critical; l'altro VG, vg_normal, includerà anche gli elementi più lenti.
# vgdisplay
# vgcreate vg_critical /dev/sdb2 /dev/sdf1
  Volume group "vg_critical" successfully created
# vgdisplay
  --- Volume group ---
  VG Name               vg_critical
  System ID
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               8.14 GB
  PE Size               4.00 MB
  Total PE              2084
  Alloc PE / Size       0 / 0
  Free  PE / Size       2084 / 8.14 GB
  VG UUID               6eG6BW-MmJE-KB0J-dsB2-52iL-N6eD-1paeo8

# vgcreate vg_normal /dev/sdc3 /dev/sdd /dev/sdf2
  Volume group "vg_normal" successfully created
# vgdisplay -C
  VG          #PV #LV #SN Attr   VSize  VFree
  vg_critical   2   0   0 wz--n-  8.14g  8.14g
  vg_normal     3   0   0 wz--n- 12.30g 12.30g
Anche qui i comandi sono immediati (e vgdisplay propone due formati di output). Notare che è possibile usare due partizioni dello stesso disco fisico in due diversi VG. Notare inoltre che si è usato un prefisso vg_ per nominare i VG, ma non è altro che una convenzione.
Adesso ci sono due «dischi virtuali», della dimensione di circa 8 GB e 12 GB rispettivamente. Ora vengono modellati in «partizioni virtuali» (LV). Ciò richiede l'uso del comando lvcreate e una sintassi leggermente più complessa:
# lvdisplay
# lvcreate -n lv_files -L 5G vg_critical
  Logical volume "lv_files" created
# lvdisplay
  --- Logical volume ---
  LV Name                /dev/vg_critical/lv_files
  VG Name                vg_critical
  LV UUID                4QLhl3-2cON-jRgQ-X4eT-93J4-6Ox9-GyRx3M
  LV Write Access        read/write
  LV Status              available
  # open                 0
  LV Size                5.00 GB
  Current LE             1280
  Segments               2
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:0

# lvcreate -n lv_base -L 1G vg_critical
  Logical volume "lv_base" created
# lvcreate -n lv_backups -L 12G vg_normal
  Logical volume "lv_backups" created
# lvdisplay -C
  LV         VG          Attr   LSize  Origin Snap%  Move Log Copy%  Convert
  lv_base    vg_critical -wi-a-  1.00G
  lv_files   vg_critical -wi-a-  5.00G
  lv_backups vg_normal   -wi-a- 12.00G
La creazione di volumi logici richiede due parametri che devono essere passati come opzioni al comando lvcreate. Il nome dei LV da creare viene specificato con l'opzione -n e la sua dimensione viene generalmente data usando l'opzione -L. Ovviamente bisogna anche dire al comando su quale VG operare, da cui l'ultimo parametro sulla riga di comando.
Una volta creati, i volumi logici si trovano come file di device a blocchi in /dev/mapper/:
# ls -l /dev/mapper
total 0
crw-rw---- 1 root root  10, 59  5 oct.  17:40 control
lrwxrwxrwx 1 root root       7  5 oct.  18:14 vg_critical-lv_base -> ../dm-1
lrwxrwxrwx 1 root root       7  5 oct.  18:14 vg_critical-lv_files -> ../dm-0
lrwxrwxrwx 1 root root       7  5 oct.  18:14 vg_normal-lv_backups -> ../dm-2
# ls -l /dev/dm-*
brw-rw---- 1 root disk 253,  0  5 oct.  18:14 /dev/dm-0
brw-rw---- 1 root disk 253,  1  5 oct.  18:14 /dev/dm-1
brw-rw---- 1 root disk 253,  2  5 oct.  18:14 /dev/dm-2
Per facilitare le cose, vengono inoltre creati dei comodi collegamenti simbolici in directory corrispondenti ai VG:
# ls -l /dev/vg_critical
total 0
lrwxrwxrwx 1 root root 7  5 oct.  18:14 lv_base -> ../dm-1
lrwxrwxrwx 1 root root 7  5 oct.  18:14 lv_files -> ../dm-0
# ls -l /dev/vg_normal
total 0
lrwxrwxrwx 1 root root 7  5 oct.  18:14 lv_backups -> ../dm-2
I LV possono quindi essere usati esattamente come normali partizioni:
# mkfs.ext4 /dev/vg_normal/lv_backups
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
[...]
This filesystem will be automatically checked every 34 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
# mkdir /srv/backups
# mount /dev/vg_normal/lv_backups /srv/backups
# df -h /srv/backups
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg_normal-lv_backups
                       12G  159M   12G   2% /srv/backups
# [...]
[...]
# cat /etc/fstab
[...]
/dev/vg_critical/lv_base    /srv/base       ext4
/dev/vg_critical/lv_files   /srv/files      ext4
/dev/vg_normal/lv_backups   /srv/backups    ext4
Dal punto di vista delle applicazioni, la miriade di piccole partizioni è stata ora astratta in un grande volume di 12 GB con un nome più familiare.

12.1.2.3. LVM nel tempo

Anche se la capacità di aggregare partizioni o dischi fisici è comoda, questo non è il vantaggio principale di LVM. La sua flessibilità si nota soprattutto col passare del tempo, quando le necessità evolvono. Nell'esempio, si supponga di dover memorizzare dei nuovi grandi file e che il LV dedicato al file server sia troppo piccolo per contenerli. Poiché non si è usato tutto lo spazio disponibile in vg_critical, si può espandere lv_files. A questo scopo, si usa il comando lvresize, quindi resize2fs per adattare il file system di conseguenza:
# df -h /srv/files/
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_files
                      5.0G  4.6G  142M  98% /srv/files
# lvdisplay -C vg_critical/lv_files
  LV       VG          Attr   LSize Origin Snap%  Move Log Copy%  Convert
  lv_files vg_critical -wi-ao 5.00g
# vgdisplay -C vg_critical
  VG          #PV #LV #SN Attr   VSize VFree
  vg_critical   2   2   0 wz--n- 8.14g 2.14g
# lvresize -L 7G vg_critical/lv_files
  Extending logical volume lv_files to 7.00 GB
  Logical volume lv_files successfully resized
# lvdisplay -C vg_critical/lv_files
  LV       VG          Attr   LSize Origin Snap%  Move Log Copy%  Convert
  lv_files vg_critique -wi-ao 7.00g
# resize2fs /dev/vg_critical/lv_files
resize2fs 1.41.12 (17-May-2010)
Filesystem at /dev/vg_critical/lv_files is mounted on /srv/files; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 1
Performing an on-line resize of /dev/vg_critical/lv_files to 1835008 (4k) blocks.
The filesystem on /dev/vg_critical/lv_files is now 1835008 blocks long.

# df -h /srv/files/
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_files
                      6.9G  4.6G  2.1G  70% /srv/files
Si potrebbe procedere in modo simile per estendere il volume che ospita il database, ma è stato raggiunto il limite di spazio disponibile del VG:
# df -h /srv/base/
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_base
                     1008M  835M  123M  88% /srv/base
# vgdisplay -C vg_critical
  VG          #PV #LV #SN Attr   VSize VFree
  vg_critical   2   2   0 wz--n- 8.14g 144.00m
Questo non è un problema, dal momento che LVM permette di aggiungere volumi fisici a gruppi di volume esistenti. Per esempio, si può notare che la partizione sdb1, che finora era stata usata al di fuori di LVM, conteneva solo archivi che potrebbero essere spostati su lv_backups. La si può quindi riciclare e integrare nel gruppo di volume, liberando così dello spazio utilizzabile. Questo è lo scopo del comando vgextend. Ovviamente la partizione deve essere preparata in precedenza come volume fisico. Una volta che il VG è stato esteso, possiamo usare comandi simili ai precedenti per espandere il volume logico e poi il file system:
# pvcreate /dev/sdb1
  Physical volume "/dev/sdb1" successfully created
# vgextend vg_critical /dev/sdb1
  Volume group "vg_critical" successfully extended
# vgdisplay -C vg_critical
  VG          #PV #LV #SN Attr   VSize VFree
  vg_critical   3   2   0 wz--n- 9.09g 1.09g
# [...]
[...]
# df -h /srv/base/
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg_critical-lv_base
                      2.0G  835M  1.1G  44% /srv/base

12.1.3. RAID o LVM?

RAID e LVM portano entrambi indiscutibili vantaggi quando si abbandona il caso semplice di un computer desktop con un solo disco fisso in cui il modello d'uso non cambia nel tempo. Tuttavia, RAID e LVM vanno in due direzioni differenti, con scopi distinti ed è giusto chiedersi quale dei due adottare. La risposta più appropriata ovviamente dipenderà dai requisiti attuali e da quelli prevedibili in futuro.
Ci sono alcuni casi semplici in cui il problema non si pone. Se il requisito è di salvaguardare i dati da guasti hardware, allora ovviamente si configurerà RAID su un array ridondante di dischi, in quanto LVM non risolve questo problema. Se, d'altro canto, c'è bisogno di uno schema flessibile per memorizzare dati dove i volumi siano indipendenti dalla disposizione fisica dei dischi, RAID non è molto d'aiuto e LVM è la scelta naturale.
Il terzo importante caso d'uso è quando si vuole semplicemente aggregare due dischi in un unico volume, per motivi di prestazioni o per avere un unico file system più grande di qualunque disco disponibile. Questo caso può essere affrontato sia tramite un RAID-0 (o addirittura un linear-RAID) sia tramite un volume LVM. In questa situazione, senza considerare ulteriori vincoli (come dover mantenere la coerenza con altre macchine se queste usano solo RAID), la configurazione preferita di solito sarà LVM. L'impostazione iniziale è di poco più complessa, ma questo leggero aumento di complessità è più che compensato dall'aumentata flessibilità di LVM nel caso i requisiti cambiassero o si dovessero aggiungere nuovi dischi.
Poi, ovviamente, c'è il caso d'uso veramente interessante, in cui il sistema di memorizzazione deve essere reso sia resistente ai guasti hardware sia flessibile in termini di allocazione di volumi. Né RAID né LVM possono di per sé soddisfare entrambi i requisiti; ciò non è un problema, perché qui si possono usare entrambi contemporaneamente, o piuttosto, uno sopra l'altro. Lo schema che è diventato lo standard da quando RAID e LVM hanno raggiunto la maturità è di assicurare prima di tutto la ridondanza dei dati raggruppando i dischi in un piccolo numero di array RAID e usare questi array RAID come volumi fisici LVM; a questo punto si creano i file system tramite partizioni logiche all'interno di questi LV. Il punto di forza di questa impostazione è che quando un disco si guasta si deve ricostruire solo un piccolo numero di array RAID, limitando così il tempo speso dall'amministratore per il ripristino.
Si faccia un esempio concreto: il dipartimento di pubbliche relazioni alla Falcot Corp ha bisogno di una postazione di lavoro per l'editing video, ma il bilancio del dipartimento non permette di investire in hardware di fascia alta per tutti i componenti. Si prende la decisione di favorire l'hardware specifico per la natura grafica del lavoro (monitor e scheda video) e di rimanere con hardware generico per quanto riguarda la memorizzazione dei dati. Tuttavia, come è ben noto, il video digitale ha dei requisiti particolari per la memorizzazione dei suoi dati: la quantità di dati da memorizzare è grande e il tasso di throughput per leggere e scrivere questi dati è importante per le prestazioni globali del sistema (più del tipico tempo di accesso, per esempio). Questi vincoli devono essere soddisfatti con hardware generico, in questo caso due dischi SATA da 300 GB; i dati del sistema devono inoltre essere resi resistenti ai guasti hardware, così come parte dei dati degli utenti. I video elaborati devono infatti essere al sicuro, ma i provini durante le modifiche sono meno critici, in quanto sono ancora sui nastri.
RAID-1 e LVM vengono combinati per soddisfare questi vincoli. I dischi sono collegati a due controller SATA diversi per ottimizzare l'accesso in parallelo e ridurre i rischi di guasto simultaneo e quindi appaiono come sda e sdc. Vengono partizionati in modo identico secondo il seguente schema:
# fdisk -l /dev/sda

Disk /dev/hda: 300.0 GB, 300090728448 bytes
255 heads, 63 sectors/track, 36483 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00039a9f

   Device Boot      Start      End      Blocks   Id  System
/dev/sda1   *           1      124      995998+  fd  Linux raid autodetect
/dev/sda2             125      248      996030   82  Linux swap / Solaris
/dev/sda3             249    36483   291057637+   5  Extended
/dev/sda5             249    12697    99996561   fd  Linux raid autodetect
/dev/sda6           12698    25146    99996561   fd  Linux raid autodetect
/dev/sda7           25147    36483    91064421   8e  Linux LVM
  • Le prime partizioni di entrambi i dischi (circa 1 GB) sono assemblate in un volume RAID-1, md0. Questo mirror è usato direttamente per contenere il file system di root.
  • Le partizioni sda2 e sdc2 sono usate come partizioni di swap, dando un totale di 2 GB di spazio di swap. Con 1 GB di RAM, la postazione di lavoro ha una quantità sufficiente di memoria disponibile.
  • Le partizioni sda5 e sdc5, così come sda6 e sdc6, sono assemblate in due nuovi volumi RAID-1 di circa 100 GB l'uno, md1 e md2. Entrambi questi mirror sono inizializzati come volumi fisici per LVM e assegnati al gruppo di volume vg_raid. Questo VG contiene circa 200 GB di spazio sicuro.
  • Le rimanenti partizioni, sda7 e sdc7, sono usate direttamente come volumi fisici e assegnate a un altro VG chiamato vg_bulk, che quindi ha all'incirca 200 GB di spazio.
Una volta creati i VG, possono essere partizionati in modo molto flessibile. Bisogna ricordarsi che i LV creati in vg_raid saranno preservati anche in caso di guasto di uno dei dischi, cosa che non succede per i LV creati in vg_bulk; d'altro canto, quest'ultimo sarà allocato in parallelo su entrambi i dischi, il che consente velocità di lettura o scrittura maggiori per file grandi.
Si creeranno quindi i LV lv_usr, lv_var e lv_home su vg_raid, per ospitare i corrispondenti file system; un altro grande LV, lv_movies, verrà usato per ospitare le versioni definitive dei filmati dopo l'elaborazione. L'altro VG verrà suddiviso in un grande lv_rushes, per ospitare i dati che provengono direttamente dalle videocamere digitali e un lv_tmp per i file temporanei. La posizione dell'area di lavoro è meno ovvia: pur essendo necessarie delle buone prestazioni per quel volume, vale la pena rischiare di perdere il lavoro se un disco si guasta durante una sessione di elaborazione? A seconda della risposta a quella domanda, il relativo LV sarà creato su uno dei due VG.
Adesso è presente un certo livello di ridondanza per i dati importanti e molta flessibilità su come viene diviso lo spazio disponibile fra le applicazioni. Se in seguito si dovesse installare nuovo software (ad esempio per elaborare degli spezzoni audio), il LV che ospita /usr/ può essere allargato senza fatica.