Installazione e configurazione di un cluster KVM
Vediamo come installare e configurare un cluster Red Hat basato su RHEL/CentOS 6 in modo che possa fornire macchine virtuali in alta affidabilità, e possa effettuare la migrazione "live" degli host virtualizzati
Architettura
L'architettura proposta è basata su due macchine fisiche, che nel nostro caso corrispondono a due HP Proliant con scheda iLO2 a bordo, questa indispensabile per effettuare lo stonith/fencing dei nodi fisici appartenenti al cluster e con quattro schede di rete accoppiate a due in bonding.
Per quanto riguarda lo storage, nel nostro caso verranno utilizzate LUN scsi in fiber channel condivise tra i due nodi, però nel caso di budget inferiore potrete utilizzare anche LUN su iSCSI.
Su queste macchine dovrete installare Red Hat Enterprise Linux 6.x oppure CentOS 6.x.
Configurazioni preliminari
Disabilitazione SELinux e Netfilter
Nel nostro caso procederemo semplificando la configurazione e disabilitando sia SELinux che il firewall Netfilter. Ricordatevi che nel caso si voglia abilitare il firewall bisognerà ricordarsi di permettere il forwarding.
# setenforce 0 # service ip6tables stop # service iptables stop # chkconfig ip6tables off # chkconfig iptables off
ed impostare la variabile SELINUX nel file /etc/sysconfig/selinux a disabled oppure a permissive
# egrep '^SELINUX=' /etc/sysconfig/selinux SELINUX=disabled
Configurazione delle due interfacce di bonding
Avendo a disposizione quattro schede di rete, provvederemo ad impostare due schede virtuali di bonding, dove una verrà utilizzata per la cluster interconnect e la seconda verrà utilizzata per l'erogazione dei servizi.
Nel nostro caso verrà utilizzato il seguente schema di assegnazione
| Interfaccia |
Descrizione |
Master (Assegnata a) |
IP |
|---|---|---|---|
| eth1 |
Interfaccia fisica |
bond0 |
- |
| eth3 |
Interfaccia fisica |
bond0 |
- |
| eth2 |
Interfaccia fisica |
bond1 |
- |
| eth4 |
Interfaccia fisica |
bond1 |
- |
| bond0 |
Interfaccia Virtuale di erogazione servizi assegnata al bridge | br0 |
- |
| bond1 |
Interfaccia Virtuale della cluster interconnect |
- |
10.0.0.X/29 |
| br0 |
Interfaccia di bridge utilizzata dalle macchine virtuali |
- | 192.168.10.X/24 |
Dove nel caso specifico utilizzeremo eth2 e eth4 per la cluster interconnect assegnandole al bond1 con gli ip 10.0.0.11/29 al node1 e 10.0.0.12/29 al node2. Mentre utilizzeremo eth1 e eth3, assegnandole a bond0, la quale però a sua volta sarà assegnata all'interfaccia di bridging br0 per poter erogare effettivamente i servizi / macchine virtuali.
Di seguito il contenuto dei file di configurazione ifcg-ethX, ricordatevi di modificare i MAC Address di tutte le schede fisiche corrispondenti:
# cd /etc/sysconfig/network-scripts # cat ifcfg-eth1 DEVICE=eth1 BOOTPROTO=none ONBOOT=yes MASTER=bond0 SLAVE=yes USERCTL=no # IMMETTERE IL PROPRIO MAC ADDRESS HWADDR=00:AB:AB:AB:AB:AB # Se si vuole impostare manualmente la velocita' del link #ETHTOOL_OPTS="speed 100 duplex full autoneg off"
# cat ifcfg-eth3 DEVICE=eth3 BOOTPROTO=none ONBOOT=yes MASTER=bond0 SLAVE=yes USERCTL=no HWADDR=00:AB:AB:AB:AB:AB # Se si vuole impostare manualmente la velocita' del link #ETHTOOL_OPTS="speed 100 duplex full autoneg off"
# cat ifcfg-eth2 DEVICE=eth2 ONBOOT=yes MASTER=bond1 SLAVE=yes USERCTL=no BOOTPROTO=none HWADDR=00:AB:AB:AB:AB:AB # Se si vuole impostare manualmente la velocita' del link #ETHTOOL_OPTS="speed 100 duplex full autoneg off"
# cat ifcfg-eth4 DEVICE=eth4 ONBOOT=yes MASTER=bond1 SLAVE=yes USERCTL=no BOOTPROTO=none HWADDR=00:AB:AB:AB:AB:AB # Se si vuole impostare manualmente la velocita' del link #ETHTOOL_OPTS="speed 100 duplex full autoneg off"
Una volta editati i corrispettivi file ifcfg-ethX bisognerà editare / creare i corrispettivi ifcfg-bond0 e ifcfg-bond1
# cat ifcfg-bond1 DEVICE=bond1 IPADDR=10.0.0.11 NETMASK=255.255.255.248 USERCTL=no BOOTPROTO=none ONBOOT=yes BONDING_OPTS="mode=1 miimon=100"
# cat ifcfg-bond0 DEVICE=bond0 USERCTL=no BOOTPROTO=none ONBOOT=yes BONDING_OPTS="mode=1 primary=eth1 miimon=100" BRIDGE=br0
In questo caso viene visualizzato il contenuto del solo node1 e viene utilizzato un bonding di tipologia Attivo-backup (opzione mode=1), se invece si vuole una configurazione Attivo-Attivo in round robin basterà immettere come opzione mode=0 al posto di mode=1.
Però per poter attivare le due interfacce di bonding bisognerà comunicare al kernel che sia bond0 che bond1 sono alias al modulo bonding, e per fare questo creiamo il file bonding.conf sotto /etc/modprobe.d
# cd /etc/modprobe.d # touch bonding.conf # echo "alias bond0 bonding" > bonding.conf # echo "alias bond1 bonding" >> bonding.conf
A questo punto possiamo configurare la scheda br0 in bridge
# cat ifcfg-br0 DEVICE=br0 TYPE=Bridge BOOTPROTO=static IPADDR=192.168.10.11 NETMASK=255.255.255.0 GATEWAY=192.168.10.1 ONBOOT=yes DELAY=0
Ora, se tutto è stato configurato correttamente, non rimane che riavviare il network, oppure riavviare l'intera macchina, però accertandosi prima che il NetworkManager sia disabilitato (ricordatevi di effettuare le seguenti operazioni dalla console):
# chkconfig NetworkManager off # service NetworkManager stop # service network restart
Installazione e configurazione della Red Hat Cluster Suite
Installazione della Red Hat Cluster Suite
Una volta installato il sistema operativo di base CentOS oppure RHEL 6 (di seguito node1 e node2), bisogna iniziare ad installare la Red Hat Cluster Suite su ambedue le macchine:
# yum groupinstall 'High Availability' # yum groupinstall 'High Availability Management' # yum groupinstall 'Resilient Storage'
Configurazione Iniziale della Red Hat Cluster Suite
Per configurare il nostro cluster per prima cosa imposteremo nel file /etc/hosts tutti i nomi macchina che ci occorreranno per il corretto funzionamento, evitando così che un problema sul DNS server si ripercuota sul funzionamento del nostro cluster. Inseriremo l'indirizzo di erogazione del servizio, l'indirizzo della cluster interconnect e l'indirizzo della iLo2:
# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 10.0.0.11 node1-ci node1-ci.example.com 10.0.0.12 node2-ci node2-ci.example.com 192.168.10.11 node1 node1.example.com 192.168.10.12 node2 node2.example.com 192.168.10.111 node1ilo node1ilo.example.com 192.168.10.112 node2ilo node2ilo.example.com
Ora resettiamo la password dell'utente ricci su entrambi i nodi
# passwd ricci
ed avviamo, o riavviamo il servizio ricci su entrambi i nodi
# service ricci restart
mentre decidiamo un nodo dove avviare il servizio luci per configurare il cluster
# service luci start
una volta avviato luci ad esempio sul node1 ci si potrà collegare tramite browser alla URL: https://node1:8084, da qui potremo creare il cluster da Homebase -> Manage Clusters -> Create; una volta apertasi una nuova finestra di immissione dati riempitela con:
- Cluster Name: LKVM01
- popolare "Node Name" con node1-ci e node2-ci
- popolare "Ricci Hostname" con node1-ci e node2-ci
- selezionare "Use Locally Installed Packages"
- spuntare "Enable Shared Storage Support"
L'operazione richiederà qualche minuto ed una volta effettuata, selezionate il nuovo cluster LKVM01 andate su Configure -> Fence Daemon ed immettete i valori
- Post Fail Delay: 5
- Post Join Delay: 60
Fatto questo bisognerà configurare i dispositivi di fencing, che nel nostro caso corrispondono a HP iLO / HP iLO2, ma questo dipende dall'hardware che avente a disposizione, e si potrà effettuare su LKVM01 -> Fence Devices -> Add, dove immetteremo:
- "Name" node1-fence
- "IP Address or Hostname" node1ilo
- "Login" la login definita sulla iLO2
- "Password" la password definita sulla iLO2
una volta definiti i due device di fence (uno per ogni macchina / scheda iLO2) associeremo ad ogni nodo la sua corrispettiva interfaccia di fencing su LKVM01 -> Nodes -> node1-ci -> Add Fence Method, dargli il nome ilo-fence e selezionare Add Fence Instance e dal menù a tendina che si presenterà selezionare il Fence Device precedentemente creato.
Associazione di un disco di quorum (Opzionale)
Nel caso si voglia creare un disco di quorum per Tie Breaker basterà individuare un disco / LUN shared tra i due nodi ed eseguire su uno soltanto dei nodi:
# mkqdisk -c /dev/sdX -l LKVM01_QDISK
ed una volta creato il disco di quorum si potrà associarlo al nostro cluster sempre sul'interfaccia di gestione di luci LKVM01 -> Configure -> QDisk -> Use a Quorum Disk -> By Device Label immettendo LKVM01_QDISK. Ricordatevi però che per il disco di quorum potete utilizzare un logical volume definito in LVM ma non un volume group di tipo clustered, questo perchè all'avvio del sistema il demone qdisk verrà avviato dal cman, quando comunque il demone clvmd non è ancora attivo.
Installazione e configurazione di KVM (Kernel based Virtual Machine)
Installazione
Per prima cosa bisogna controllare che i processori utilizzati nelle nostre macchine fisiche abbiamo le relative estensioni di virtualizzazione dove basterà eseguire:
# egrep '(vmx|svm)' --color=auto /proc/cpuinfo
e se il processore / core supporta le estensioni di virtualizzazione si potrà procedere con l'installazione, questa bisognerà effettuarla su entrambi i nodi:
# export LANG=C # yum groupinstall Virtualization # yum groupinstall 'Virtualization Client'
Ora riavviamo entrambi i nodi
# shutdown -r now
e verifichiamo che al load dei moduli kvm questi non segnalino che il kvm è disabilitato dal bios, ad esempio su una macchina con il kvm disabilitato dal bios potrete vedere il messaggio del kernel "kvm: disabled by bios"
# dmesg | grep -i kvm kvm: disabled by bios
nel qual caso bisognerà riavviare entrambi i nodi, entrare nel bios ed abilitare le estensioni di virtualizzazione. Fatto questo il kernel segnalerà:
# dmesg | grep -i kvm kvm: Nested Virtualization enabled
Configurazione dello storage condiviso
Una volta installato KVM e con le LUN agganciate ad entrambi i nodi del cluster e corrispondenti ad esempio a /dev/sdb e /dev/sdc sia su node1 che node2 iniziamo a configurare lo storage attivando se non già presente il demone clvmd su entrambi i nodi:
# service clvmd start # chkconfig --level 35 clvmd on
ora diamo tutto in pasto a LVM eseguendo i seguenti comandi soltanto su node1
[root@node1 ~]# pvcreate /dev/sdb [root@node1 ~]# pvcreate /dev/sdc [root@node1 ~]# vgcreate -cy -s 32M VG_VM /dev/sdb [root@node1 ~]# vgextend VG_VM /dev/sdc
creiamo il logical volume che ospiterà la configurazione di libvirt
[root@node1 ~]# lvcreate -L 1G -n LV_etclibvirt VG_VM
questo logical volume lo useremo in seguito, ora creaimo un nuovo logical volume che verrà utilizzato come disco di storage da 25GB dalla nostra macchina virtuale ancora da creare
[root@node1 ~]# lvcreate -L 25G -n LV_l64vm01sys VG_VM
in ultimo configuriamo lo storage pool tramite il virt-manager eseguendolo su una sessione con display attivo connesso in localhost su node1 eseguire:
- avvio del processo "virt-manager";
- Menu Edit -> Connection Details;
- Sulla nuova finestra selezionare Tab Storage -> Pulsante + (Add Pool);
- Sulla nuova finestra "Step 1 of 2" immettere come Name "VM_images" e come Type "logical: LVM Volume Group" e cliccare su Forward;
- Nello "Step 2 of 2" nel menù a tendina "Target Path" selezionare "/dev/VG_VM" e cliccare su Finish.
A questo punto dovreste poter vedere nella Tab Storage i logical volume appena creati e che utilizzeremo durante la creazione della macchina virtuale "l64vm01"
Installazione Macchina Virtuale l64vm01
Eseguite nuovamente il virt-manager con il display attivo ed immettete le seguenti impostazioni:
- avvio del processo "virt-manager";
- "Step 1 of 5" Name: l64vm01;
- Per gli step 2 e 3 immettete le impostazioni confacenti parte della vostra architettura;
- "Step 4 of 5" "Select managed or other existing storage" -> Browse -> VM_images -> LV_l64vm01sys -> Choose Volume;
- "Step 5 of 5" Selezionate finish e inizierà il canonico processo di installazione.
Configurazione del Live Migration
Condivisione dei file di configurazione
Una volta che la macchina virtuale l64vm01 risulta installata e funzionante su node1, bisognerà fare in modo che possa essere migrata anche su node2 e per fare questo creeremo un file system gfs2 montato sotto /etc/libvirt su entrambi i nodi del cluster. Per creare questo nuovo file system basterà eseguire su node1
[root@node1 ~]# mkfs.gfs2 -j 2 -p lock_dlm -t LKVM01:etclibvirt /dev/VG_VM/LV_etclibvirt
Creato il file system gfs2 lo montiamo temporaneamente per effettuare un copia ricorsiva di /etc/libvirt presa da node1 dove abbiamo creato la macchina virtuale l64vm01
[root@node1 ~]# mkdir -p /tmp/etclibvirt [root@node1 ~]# mount -t gfs2 /dev/VG_VM/LV_etclibvirt /tmp/etclibvirt [root@node1 ~]# cp -p -R -x /etc/libvirt/* /tmp/etclibvirt [root@node1 ~]# umount /tmp/etclibvirt
a questo punto fermiamo i servizi di virtualizzazione su entrambi i nodi
# service libvirt-guests stop # service libvirtd stop
ed inseriamo nel file /etc/fstab di entrambi i nodi
... /dev/VG_VM/LV_etclibvirt /etc/libvirt gfs2 defaults 0 0
montiamo il nuovo file system condiviso su entrambi i nodi
# mount /etc/libvirt
riavviamo i servizi di virtualizzazione, sempre su entrambi i nodi
# service libvirtd start # service libvirt-guests start
ed infine startiamo la macchina l64vm01 nuovamente sul node1 (originario)
[root@node1 ~]# virsh start l64vm01
Trust delle chiavi ssh tra i due nodi del cluster
Il demone rgmanager della Red Hat Cluster Suite utilizza l'utente root nell'esecuzione, pertanto se si vuole una migrazione "live" senza tempi di stop e start delle nostre macchine virtuali bisognerà fare in modo che le chiavi ssh dell'utente root siano trustate su ambedue i nodi e siano anche senza password, questo perchè per una migrazione live KVM utilizzeremo un tunnel ssh.
Su node1 creare con l'utente root una chiave ssh senza passphrase
[root@node1 ~]# ssh-keygen -f /root/.ssh/id_rsa_kvm
quando richiederà la passphrase lasciarla vuota in modo tale che non sia richiesta interattività nella migrazione. Fatto questa mettere la chiave pubblica appena creata nel file authorized_keys dell'utente root sempre per la macchina node1
[root@node1 ~]# cat /root/.ssh/id_rsa_kvm.pub >> /root/.ssh/authorized_keys
a questo punto sempre su node1 create il file /root/.ssh/config ed immettete il seguente contenuto
Host node*
IdentityFile /root/.ssh/id_rsa_kvm
adesso non vi resta che copiare il contenuto della directory /root/.ssh da node1 a node2, ad esempio con scp
[root@node1 ~]# scp -r -p node1:/root/.ssh node2:/root/.ssh
in ultimo verificate che effettuando ssh da un nodo all'altro non venga richiesta la password e/o l'inserimento dell'host remoto nel file known_hosts, ovviamente escludendo il primo tentativo dove vi verrà richiesta conferma. Ricordatevi però che questo trust dovrà essere effettuato con il nome host presente nel cluster, ovvero node1-ci e node2-ci
[root@node1 ~]# ssh node2-ci [root@node2 ~]# ssh node1-ci
Test di migrazione live usando le libvirt
Dopo aver configurato e testato le chiavi ssh, proviamo ad effettuare i test di live migration direttamente da libvirt, usando la sua interfaccia virsh. Da node1, che dovrebbe avere in stato running la nostra macchina l64vm01 eseguire
[root@node1 ~]# virsh migrate --live l64vm01 qemu+ssh://node2-ci/system
se tutto andrà a buon fine dovreste vedere alla fine del processo che la macchina virtuale l64vm01 passa in "shut off" su node1-ci ed in running su node2-ci, senza avere tempi di down time. Ora testiamo anche la migrazione inversa dal node2-ci al node1-ci
[root@node2 ~]# virsh migrate --live l64vm01 qemu+ssh://node1-ci/system
e controllate che la macchina virtuale l64vm01 passi in running su node1-ci.
Aggiunta della macchina virtuale nel resorce group del cluster
Ora non ci rimane che definire il nuovo servizio di clusterizzazione nella nostra Red Hat Cluster Suite. Aprite tramite browser l'interfaccia di gestione di luci che dovrebbe essere all'indirizzo https://node1:8084 e seguite i seguenti passi logici:
- Homebase -> LKVM01 -> Service Groups -> Add;
- dalla nuova finestra immettere come "Service Name" l64vm01 che corrisponde al nome della macchina virtuale visualizzabile tramite il comando "virsh list --all", spuntare "Automatically start this service" e come "Recovery Policy" selezionare Relocate e cliccare su "Add Resource";
- in questa nuova finestra selezionare dal menù a tendina "Virtual Machine" e poi mettere come "Migration Type" Live ed inserire nel campo "VM Configuration File Path" /etc/libvirt/qemu;
- cliccate su "Submit".
a questo punto la vostra macchina virtuale dovrebbe essere in alta affidabilità sui vostri due hypervisor KVM, non vi resta che testare la migrazione live comandata dalla cluster suite
# clusvcadm -M vm:l64vm01 -m node2-ci
una volta concluso proviamo a riportarla su node1
# clusvcadm -M vm:l64vm01 -m node1-ci
Conclusioni
Abbiamo visto come configurare la Red Hat Cluster Suite per mettere in alta affidabilità una macchina virtuale basata su KVM. Ovviamente potete abilitare sia SELinux che il Netfilter per rendere più sicuri i vostri hypervisor; in aggiunta potete rendere minimale l'installazione degli hypervisor in modo che sia presente soltanto la cluster suite senza i programmi client come il virt-manager.
