Virtualisation KVM

Objectifs des certification

RHCSA EX200

  • 2.Utiliser des systèmes en cours d'exécution
    • 2.6. Accéder à la console d'une machine virtuelle
    • 2.7. Démarrer et arrêter des machines virtuelles
  • 5.Déployer, configurer et gérer des systèmes
    • 5.5.Installer Red Hat Enterprise Linux automatiquement à l'aide de Kickstart
    • 5.6. Configurer une machine physique pour héberger des invités virtuels
    • 5.7. Installer des systèmes Red Hat Enterprise Linux en tant qu'invités virtuels
    • 5.8. Configurer des systèmes pour lancer des machines virtuelles au démarrage

Introduction

Références à lire

Scripts de préparation et d'automation

On trouvera sur le dépot GIT https://github.com/goffinet/virt-scripts des scripts utiles à ce chapitre.

Objectifs

  1. Concepts virtualisation KVM
  2. Installer KVM et ses outils de gestion
  3. Créer une VM avec virt-manager
  4. Administration avec virsh
  5. Créer un dépôt local HTTP
  6. Créer des VMs avec virt-install
  7. Automatiser une l'installation avec kickstart
  8. Accéder à la console (graphique te texte) et la dépanner

Selon Gartner en 2014, seulement 45% des systèmes Linux sont virtualisés (contre 70% sur un OS concurrent). Par ailleurs, toujours selon la même source, la majorité des systèmes RHEL virtualisés fonctionnaient encore sous VMWare ! La raison principale tiendrait à la difficulté de migrer les machines virtuelles vers un autre hyperviseur ...

Toujours selon Gartner en 2015, la majorité des instances RHEL virtualisées sont exécutées sur VMware et VMware semblerait toujours aussi difficile à déplacer. Red Hat qui conduit le projet Open Source KVM dispose d'une véritable opportunité avec le développement de nouvelles infrastructures de type Cloud Privé avec Openstack malgré actuellement une forte préférence pour Ubuntu.

1. Concepts

1.1. Typologie des architectures de virtualisation

  • Isolateur : Docker, LXC, OpenVZ, BSD Jails
  • Noyau en espace utilisateur
  • Hyperviseur de type 2 / type 1
    • Virtualisation totale (Full virtualization) : qemu
    • Virtualisation Hardware-Assisted : qemu+KVM
    • Paravirtualisation : qemu+KVM+virtio, Xen

KVM est un hyperviseur de type 1 qui s'utilise aussi bien dans :

  • des environnements de développement, de test, d'apprentissage
  • la virtualisation de centres de données (data center)
  • la mise en place d'infrastructures en nuage (cloud)

1.2. Machine virtuelle

Sur le plan technique, en général et particulièrement avec KVM, une machine virtuelle (VM) est représentée par :

  1. un fichier de définition qui reprend les caractéristiques de la machine, par défaut situé (en format XML) dans /etc/libvirt/qemu/.
  2. un ou des fichier(s) qui représentent les disques par défaut placés dans /var/lib/libvirt/images/.

Les principales ressources de virtualisation sont :

  • La puissance (CPU/RAM)
  • Le stockage (disques)
  • Le réseau

Mais pour fonctionner, une VM a aussi besoin de bien d'autres interfaces matérielles qui peuvent être émulées ou para-virtualisées.

1.3. KVM

KVM Kernel-based Virtual Machine :

  • KVM est le module qui transforme le noyau Linux en Hyperviseur type 1 (HVM et PV avec virtio). Ce module traduit rapidement les instructions des vCPU via les intructions VT AMD et Intel. Il prend aussi en charge des aspects de bas niveau de l'architecture x86.
  • KVM est aussi un émulateur de matériel qui utilise qemu et les pilotes virtio.

Vue du noyau :

  • Chaque VM est un processus
  • Chaque vCPU est un thread de processeur.

Features :

  • CPU and memory overcommit
  • High performance paravirtual I/O
  • Hotplug (cpu, block, nic)
  • SMP guests
  • Live Migration Power management
  • PCI Device Assignment and SR-IOV
  • KSM (Kernel Samepage Merging)
  • SPICE, VNC, text
  • NUMA

1.4. Qemu

Qemu est un émulateur de diverses architectures dont x86 (Hyperviseur de type 2). Combiné au pilote KVM, il permet de réaliser de l'accélération Hardware (HVM).

L'outil de base qemu-img permet de créer et de gérer des images disque.

En format local les images disques peuvent se trouver en formats :

  • raw
  • qcow2

Par ailleurs, on peut utiliser directement des volumes logiques LVM.

1.5. Libvirt

libvirt un API de virtualisation Open Source qui s'interface avec un hyperviseur pour administrer les VMs.

libvirt

1.6. Outils de base

  • virsh : cli pour libvirt
  • qemu-img : permet de gérer les images des disques
  • virt-manager : client graphique
  • virt-install : commande pour la création des machines virtuelles
  • virt-viewer : client console graphique (spice)
  • virt-clone : outil de clonage
  • virt-top : top de VM libvirt
  • Autres outils

1.7. Outils libguestfs

libguestfs est un ensemble d'outils qui permettent d'accéder aux disques des machines virtuelles et de les modifier.

Ces outils permettent de :

  • d'accéder et de modifier un système de fichier invité à partir de l'hôte
  • virt-builder permet de créer des VM à partir d'un dépôt d'images
  • virt-syspreppermet de "préparer" une VM à cloner
  • d'obtenir des informations complètes dur l'usage des disques
  • de convertir des machines en P2V ou V2V
  • ...

1.8. Pilotes et périphériques PV virtio

1.9. Interface graphiques

  • Kimchi est un outil de gestion en HTLM5 pour KVM basé sur libvirt. Il s'agit d'une solution à hôte unique.
  • oVirt est aussi une plateforme Web de gestion de virtualisation multi-hôtes supportant d'autres hyperviseur, des volumes NFS, iSCSI ou FC (Fiber Channel), surveillance, fine tuning des ressources.

2. Installer KVM et ses outils de gestion

Les instructions VT doivent être activées dans le Bios (Netsted Virtualization) :

grep -E 'svm|vmx' /proc/cpuinfo
  • vmx : processeurs Intel
  • svm : processeurs AMD

ou encore

lscpu | grep Virtualisation

Mise à jour du sytème :

yum update

Installation des paquets KVM :

yum group install "Virtualization Host" "Virtualization Client"

yum -y install \
qemu-kvm \
dejavu-lgc-sans-fonts \
libguestfs-tools

Démarrer le service libvirtd :

systemctl enable libvirtd && systemctl start libvirtd

Démarrer le service chronyd :

# systemctl enable chronyd && systemctl start chronyd

Vérification du chargement du module kvm :

lsmod | grep kvm

Libvirt propose un outil de vérification de l'hôte :

# virt-host-validate 
  QEMU: Vérification for hardware virtualization                                 : PASS
  QEMU: Vérification for device /dev/kvm                                         : PASS
  QEMU: Vérification for device /dev/vhost-net                                   : PASS
  QEMU: Vérification for device /dev/net/tun                                     : PASS
   LXC: Vérification pour Linux >= 2.6.26                                        : PASS
`

Vérification du démarrage de libvirt :

systemctl status libvirtd

Configuration du réseau par défaut :

Une interface bridge virbr0 192.168.122.1 est natée à l'interface physqiue. dnsmasqfourni le service DNS/DHCP.

ip add sh virbr0
ip route
iptables -t nat -L -n -v
cat /proc/sys/net/ipv4/ip_forward

L'emplacement par défaut de l'espace de stockage des disques est /var/lib/libvirt/images/. La définition des machines virtuelles est située dans /etc/libvirt/qemu/.

Il est peut-être plus aisé de désactiver pour l'instant firewalld (systemctl stop firewalld).

3. Création de VMs et administration de base

3.1. Créer une machine virtuelle avec virt-manager

Virt-manager est un outil graphique de gestion des hyperviseurs connecté via libvirt.

Dans une session X Window, suivre Quick Start with virt-manager ou encore KVM, Qemu, libvirt en images.

3.2. Administration de base avec virsh

Avec libvirt et KVM, une "Machine Virtuelle (VM)" est appelée un "Domaine".

Démarrage d'un VM :

virsh start vm1

Arrêt d'une VM :

virsh shutdown vm1

Extinction d'une VM (comme on retire une prise de courant, il ne s'agit pas d'effacer le domaine) :

virsh destroy vm1

Pour retirer une VM (le ou les disques associés persistent) :

virsh undefine vm1

Pour retirer une VM (et en effaçant ses disques) :

virsh undefine vm1 --remove-all-storage

Redémarrage d'un VM :

virsh reboot vm1

Informations détaillées :

virsh dominfo vm1

Liste des VM :

virsh list --all

Démarrage de la VM au démarrage de l'hôte :

virsh autostart vm1

Désactiver l'activation au démarrage :

virsh autostart vm1 --disable

4. Scripts d'installation

La commande qui permet de créer une machine virtuelle et de la lancer (pour y installer un système d'exploitation) est virt-install. Cette commande peut comporter un certain nombre de paramètres. Il est plus intéressant de travailler avec des scripts.

Dans le but de cloner un domaine existant, on s'intéressa à ce qui constitue la machine virtuelle : un fichier de définition de VM écrit en XML et un disque virtuel.

Les procédures de création ou de mise à jour d'objet (réseau, volume, domaine) avec la commande virsh consiste à manipuler des définitions XML :

  • define / undefine
  • destroy /start /autostart

4.1. Un premier script virt-install

On peut créer une machine virtuelle lancer une installation à partir du shell avec virt-install et des options.

Création et lancement d'une VM :

  • RAM 1024/1 vCPU
  • HD 8Go (raw)
  • ttyS0
  • console vnc
  • Installation CD-ROM
#/bin/bash
# vm-install.sh

# local path to the iso
iso=/var/CentOS-7-x86_64-DVD-1503-01.iso

# Stop and undefine the VM
/bin/virsh destroy $1; /bin/virsh undefine $1 --remove-all-storage

# graphical console
# via local ISO 
virt-install \
--virt-type kvm \
--name=$1 \
--disk path=/var/lib/libvirt/images/$1.img,size=8 \
--ram=1024 \
--vcpus=1 \
--os-variant=rhel7 \
--graphics vnc \
--console pty,target_type=serial \
--cdrom $iso

4.2. Export manuel d'une VM

Avant de procéder à un export, il est préférable de suspendre la VM d'origine :

virsh suspend vm1

On peut redigirer un "dump" de la VM d'origine dans un fichier xml.

virsh dumpxml vm1 > vm2.xml

Ensuite, il faut adapter ce fichier en retirant la valeur id et le champ uuid en modifiant le champ name, la balise source file qui désigne l'emplacement du nouveau disque, le champ mac address et en supprimant des balises entre </devices> et </domain>.

vi vm2.xml

Le second élément nécessaire à l'exécution de la VM est un disque dédié, soit la copie du disque de la machine originale :

cp /var/lib/libvirt/images/vm1.img /var/lib/libvirt/images/vm2.img

Enfin, on peut intégrer la machine à libvirtet la démarrer :

virsh define vm2.xml

virsh start vm2

A lire attentivement, voici le fichier vm2.xml adapté (uuid, devices, disks, mac):

<domain type='kvm'>
  <name>vm2</name>
  <memory unit='KiB'>1048576</memory>
  <currentMemory unit='KiB'>1048576</currentMemory>
  <vcpu placement='static'>1</vcpu>
  <resource>
    <partition>/machine</partition>
  </resource>
  <os>
    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <cpu mode='custom' match='exact'>
    <model fallback='allow'>Westmere</model>
  </cpu>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/vm2.img'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </disk>
    <controller type='usb' index='0' model='ich9-ehci1'>
      <alias name='usb0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <alias name='usb0'/>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <alias name='usb0'/>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <alias name='usb0'/>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pci-root'>
      <alias name='pci.0'/>
    </controller>
    <interface type='bridge'>
      <mac address='52:54:00:8a:c3:2a'/>
      <source bridge='virbr0'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
      <alias name='net0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <source path='/dev/pts/0'/>
      <target type='isa-serial' port='0'/>
      <alias name='serial0'/>
    </serial>
    <console type='pty' tty='/dev/pts/0'>
      <source path='/dev/pts/0'/>
      <target type='serial' port='0'/>
      <alias name='serial0'/>
    </console>
    <input type='tablet' bus='usb'>
      <alias name='input0'/>
    </input>
    <memballoon model='virtio'>
      <alias name='balloon0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </memballoon>
  </devices>
</domain>

4.3. Clonage avec virt-clone

L'utilitaire virt-clone permet de cloner (à l'identique) une VM. virt-cloneprend la peine de générer une nouvelle adresse MAC et un nouvel uuid pour le domaine. Il s'occupe également de dupliquer le ou les disques attachés au domaine.

Imaginons que l'on veuille cloner proprement la machine vm1 en machine vm2 dans le but de :

  • générer une copie de sauvegarde de toute la machine
  • générer une copie de sauvegarde de base de donnée afin de travailler sur une base de donnée hébergée. Dans ce cas, il est peut être intéressant de connecter le clone sur un réseau isolé du réseau de production.
  • dupliquer un même modèle

Attention, il faudra malgré tout modifier le fichier de configuration du réseau en retirant l'adresse mac et l'uuid dans le système d'exploitation invité. (/etc/sysconfig/network-scripts/ifcfg-*) si on désire exécuter le domaine original et son clone sur le même réseau ou si l'adresse IP est fixe.

Avant tout, vérifions l'état de la machine. Mettons-la en suspension pour assurer une copie correcte des disques :

virsh list
 ID    Nom                            État
----------------------------------------------------
 73    vm1                            en cours d'exécution
virsh suspend vm1
Domaine vm1 suspendu
virsh list
 ID    Nom                            État
----------------------------------------------------
 73    vm1                            mis en pause

Procédons au clonage :

virt-clone \
--original vm1 \
--name vm2 \
--file /var/lib/libvirt/images/vm2.img
virsh list --all
 ID    Nom                            État
----------------------------------------------------
 73    vm1                            mis en pause
 -     vm2                            fermé

Reprise de la machine :

virsh resume vm1
Domaine vm1 réactivé

4.4 Sysprep Linux

Pour la transformation d'une machine virtuelle en modèle (template), on peut utiliser virt-sysprep qui vient avec libguestfs, avant le clonage pour remettre à zéro ses propriétés.

5. Miroir d'installation HTTP

5.1. Miroir local

Les sources d'installation doivent contenir au minimum ceci :

{product path}
   |
   +--base
   |
   +--RPMS

product path :

  • RedHat
  • Fedora
  • Centos

base : metadonnées

RPMS : Fichiers Red Hat Package Manager

Repo HTTP

Installer Apache :

yum -y install httpd
systemctl enable httpd.service && systemctl start httpd.service

Télécharger une image

wget http://ftp.belnet.be/ftp.centos.org/7/isos/x86_64/CentOS-7-x86_64-DVD-1503-01.iso

Monter l'ISO :

mount -o loop,ro CentOS*.iso /mnt

Copier les fichiers

mkdir /var/www/html/repo/

cp -rp /mnt/* /var/www/html/repo/

chcon -R -t httpd_sys_content_t /var/www/html

Monter l'ISO directement dans /var/www/html/repo/ est une alternative.

Miroirs publics externes

5.2. Support d'installation HTTP

Création et lancement d'une VM :

  • RAM 1024/1 vCPU
  • HD 8Go (raw)
  • ttyS0
  • console vnc
  • Installation repo HTTP local ou distant
#/bin/bash
# vm-install2.sh

# KVM Host IP
bridge=192.168.122.1

# Repo URL
mirror=http://$bridge/repo
#mirror=http://centos.mirrors.ovh.net/ftp.centos.org/7/os/x86_64
#mirror=http://ftp.belnet.be/ftp.centos.org/7/os/x86_64
#mirror=http://mirror.i3d.net/pub/centos/7/os/x86_64

# Stop and undefine the VM
/bin/virsh destroy $1; /bin/virsh undefine $1 --remove-all-storage

# graphical console, bridged
# via http repo
virt-install \
--virt-type kvm \
--name=$1 \
--disk path=/var/lib/libvirt/images/$1.img,size=8 \
--ram=1024 \
--vcpus=1 \
--os-variant=rhel7 \
--network bridge=virbr0 \
--graphics vnc \
--console pty,target_type=serial \
--location $mirror

6. Installation automatique

6.1. Installation Kickstart

Kickstart permet d'automatiser les installations RHEL/Fedora/Centos (et d'autres) en indiquant un fichier de configuration qui est lu avant le logiciel d'installation Anaconda.

Documentation Kickstart

  • On rend le fichier kickstart disponible via HTTP (local, NFS, FTP) dans un dans dossier conf
mkdir /var/www/html/conf/

touch vm.ks /var/www/html/conf/

chcon -R -t httpd_sys_content_t /var/www/html
  • Il est appelé par virt-install (directement au lancement du noyau)

Ce fichier de configuration est rédigé :

  • Automatiquement par Anaconda sur toute installation RHEL/Centos/Fedora :
less /root/anaconda-ks.cfg
  • On peut le générer en l'éditant via le programme :
yum install system-config-kickstart

system-config-kickstart

6.2. Installation automatique en console graphique

Voici la configuration d'une installation simple avec un fichier /var/www/html/conf/vm.ks :

  • Clavier local, horodatage, réseau dhcp, nom, mot de passe, Swap, /boot, LVM, @core, chrony
# File /var/www/html/conf/vm.ks

keyboard --vckeymap=be-oss --xlayouts='be (oss)'
lang fr_BE.UTF-8
network --onboot=on --bootproto=dhcp --device=link --hostname=localhost.localdomain
rootpw testtest
services --enabled="chronyd"
timezone Europe/Paris --isUtc
bootloader --location=mbr --boot-drive=vda
clearpart --all --initlabel --drives=vda
ignoredisk --only-use=vda
part pv.9 --fstype="lvmpv" --ondisk=vda --size=5000
part /boot --fstype="ext4" --ondisk=vda --size=500
volgroup rhel --pesize=4096 pv.9
logvol swap  --fstype="swap" --size=500 --name=swap --vgname=rhel
logvol /  --fstype="ext4" --size=3072 --name=root --vgname=rhel

%packages --ignoremissing
@core
chrony
%end
reboot

Avec la machine virtuelle :

  • RAM 1024/1 vCPU
  • HD 8Go (qcow2)
  • ttyS0
  • console vnc
  • Installation repo HTTP local ou distant
#/bin/bash
# vm-install3.sh

bridge=192.168.122.1
mirror=http://$bridge/repo
#mirror=http://centos.mirrors.ovh.net/ftp.centos.org/7/os/x86_64
#mirror=http://ftp.belnet.be/ftp.centos.org/7/os/x86_64
#mirror=http://mirror.i3d.net/pub/centos/7/os/x86_64

#Stop and undefine the VM
/bin/virsh destroy $1; /bin/virsh undefine $1 --remove-all-storage

# Graphical console, bridged, HD qcow2
# HTTP + Kickstart 
virt-install \
--virt-type kvm \
--name=$1 \
--disk path=/var/lib/libvirt/images/$1.qcow2,size=16,format=qcow2 \
--ram=1024 \
--vcpus=1 \
--os-variant=rhel7 \
--network bridge=virbr0 \
--graphics vnc \
--console pty,target_type=serial \
--location $mirror \
-x ks=http://$bridge/conf/vm.ks

6.3. Installation automatique en console texte

Voici la configuration d'une installation simple en console texte avec un fichier /var/www/html/conf/vm2.ksrevu par system-config-kickstart :

  • Clavier local, horodatage, réseau dhcp, nom, firewall désactivé, selinux désactivé, pas de serveur X, console texte, mot de passe, Swap, /boot, LVM, @core, chrony
# File /var/www/html/conf/vm2.ks
#platform=x86, AMD64, ou Intel EM64T
#version=DEVEL
# Install OS instead of upgrade
install
# Keyboard layouts
# old format: keyboard be-latin1
# new format:
keyboard --vckeymap=be-oss --xlayouts='be (oss)'
# Reboot after installation
reboot
# Root password
rootpw --plaintext testtest
# System timezone
timezone Europe/Paris
# System language
lang fr_BE
# Firewall configuration
firewall --disabled
# Network information
network  --bootproto=dhcp --device=link
# System authorization information
auth  --useshadow  --passalgo=sha512
# Use text mode install
text
# SELinux configuration
selinux --disabled
# Do not configure the X Window System
skipx

# System services
services --enabled="chronyd"

bootloader --location=mbr --boot-drive=vda
clearpart --all --initlabel --drives=vda
ignoredisk --only-use=vda
part pv.9 --fstype="lvmpv" --ondisk=vda --size=5000
part /boot --fstype="ext4" --ondisk=vda --size=500
volgroup rhel --pesize=4096 pv.9
logvol swap  --fstype="swap" --size=500 --name=swap --vgname=rhel
logvol /  --fstype="ext4" --size=3072 --name=root --vgname=rhel

%packages --ignoremissing
@core
chrony

%end

Avec la machine virtuelle :

  • RAM 1024/1 vCPU
  • HD 8Go (qcow2)
  • ttyS0
  • console texte
  • Installation repo HTTP local ou distant
#/bin/bash
# vm-install4.sh

bridge=192.168.122.1
mirror=http://$bridge/repo
#mirror=http://centos.mirrors.ovh.net/ftp.centos.org/7/os/x86_64
#mirror=http://ftp.belnet.be/ftp.centos.org/7/os/x86_64
#mirror=http://mirror.i3d.net/pub/centos/7/os/x86_64

#Stop and undefine the VM
/bin/virsh destroy $1; /bin/virsh undefine $1 --remove-all-storage

# Text console, bridged, HD qcow2
# HTTP + Kickstart 
virt-install \
--virt-type kvm \
--name=$1 \
--disk path=/var/lib/libvirt/images/$1.qcow2,size=16,format=qcow2 \
--ram=1024 \
--vcpus=1 \
--os-variant=rhel7 \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location $mirror \
-x "ks=http://$bridge/conf/vm2.ks console=ttyS0,115200n8 serial"

Pour échapper à la console texte :

CTRL+] (Linux)
CTRL+ALT+* (Mac OS X)

7. Accéder à la console

7.1. Accéder à la console graphique

Via une session Xwindows :

# virt-manager

ou

virsh vncdisplay vm1

ou

netstat -tln|grep :59

vncviewer x.x.x.x:5900

7.2. Activer ttyS0 dans grub

Il faut nécessairement que la machine virtuelle dispose d'une console ttyS0 émulée !

Si la machine n'a pas été configurée avec ce paramètre grub, il faut editer le fichier /etc/default/grub en ajoutant console=ttyS0 ) la variable GRUB_CMDLINE_LINUX Exécuter :

grub2-mkconfig -o /boot/grub2/grub.cfg
reboot

7.3. Accès à la console texte

# virsh console vm1
Connected to domain vm1
Escape character is ^]

CentOS Linux 7 (Core)
Kernel 3.10.0-229.el7.x86_64 on an x86_64

localhost login:

8. Installation d'un invité MS-Windows

osinfo-query os | grep Microsoft

A condition de disposer d'un ISO de Windows 7, voici un script de configuration d'une VM Windows en mode HVM :

#/bin/bash
# File vm-install5.sh

#Stop and undefine the VM
/bin/virsh destroy $1; /bin/virsh undefine $1 --remove-all-storage

# Graphical console, bridged, cd-rom 
virt-install \
--virt-type kvm \
--name=$1 \
--disk path=/var/lib/libvirt/images/$1.qcow2,size=16,format=qcow2 \
--cdrom /var/win7.iso \
--ram=2048 \
--vcpus=2 \
--arch=x86_64
--os-type=windows \
--os-variant=win7 \
--hvm \
--network bridge=virbr0 \
--keymap=fr \
--sound \
--vnc

On a aussi besoin des pilotes virtio si on utilise la paravirtualisation :

  • Pilote de disque bus=virtio,cache=none; d'autres bus disponibles tels que 'ide', 'sata', 'scsi', 'usb'.
  • Pilote de carte réseau model=virtio; d'autres options de modèle sont 'e1000' ou 'rtl8139'.
#!/bin/bash
# File vm-install6.sh
...

Voir Wiki sur les pilotes virtio :

wget https://fedorapeople.org/groups/virt/virtio-win/virtio-win.repo -O /etc/yum.repos.d/virtio-win.repo

yum install virtio-win

/usr/share/virtio-win/*.iso contient tous les pilotes virtio.

Après l'installation insérer l'iso virtio-tools, mais avant trouver le lecteur cd :

virsh domblklist vm3
virsh change-media vm3 hdb /usr/share/virtio-win/virtio-win.iso

9. Manipulation de disques

9.1 Conversion de disques

raw vers qcow2

Pour convertir un disque raw vers qcow2 :

#!/bin/bash

# File raw2qcow2.sh

path=/var/lib/libvirt/images/$1

virsh list 
virsh suspend $1
ls -lh $path.img
echo "Conversion du disque"
qemu-img convert -c -O qcow2 $path.img $path.qcow2
mv $path.img $path.old
mv $path.qcow2 $path.img
virsh resume $1
ls -lh $path.*

vdi vers raw

Pour convertir un disque VB vdi vers raw :

$ VBoxManage clonehd --format RAW WindowsXP.vdi WindowsXP.raw
0%...10%...20%...30%...50%...70%...80%...90%...100%
Clone hard disk created in format 'RAW'. UUID: cfe44508-d957-4c8c-b5c5-2b4f266830d8

9.2. Redimensionnement de disques

...

9.3 Import d'une VM via son disque

Import d'une VM via son disque (converti d'une autre solution par exemple) avec virt-install...

9.4. Migration V2V

9.5. Manipulation de disques

  • Manipulation de disques avec kpartx

10. Storage Pools / Storage Volumes

Ajouter un pool pour stocker les disques des domaines

virsh pool-define-as Images dir - - - - /home/so/Documents/kvm/images
virsh pool-list --all
virsh pool-build Images
virsh pool-start Images
virsh pool-autostart Images
virsh pool-list
virsh pool-info Images

Storage Pools

  • LVM2
  • iSCSI

11. Live Migration

12. Réseau

Lister les réseaux virtuels disponibles :

virsh net-list

Obtenir la base d'une définition de réseau virtuel (ici default) dans un fichier lab.xml :

virsh net-dumpxml default > lab.xml

La commande uuidgen permet de générer un uuid :

uuidgen
vim lab.xml

Si on défini un nouveau réseau "lab" utilisant l'interface virbr1 pour laquelle le NAT est activé, voici à quoi se fichier devrait ressembler :

<network>
  <name>lab</name>
  <uuid>8293bf7a-ccf6-461b-8466-a058e7346d79</uuid>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr1' stp='on' delay='0'/>
  <mac address='52:54:00:63:e8:10'/>
  <ip address='192.168.22.254' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.22.100' end='192.168.22.150'/>
    </dhcp>
  </ip>
</network>

La balise forward mode peut prendre des valeurs comme nat, route, bridge, etc. En son absence le réseau est isolé.

Installation du nouveau réseau lab :

virsh net-define lab.xml

Démarrage du réseau :

virsh net-start lab

Ensuite, faire en sorte qu'il démarre automatiquement :

virsh net-autostart lab

Pour attacher un domaine existant au réseau lab, il faut créer un fichier qui reprend les paramètres d'une interface :

vim virbr1.xml
<interface type='bridge'>
      <mac address='52:54:00:f7:e3:53'/>
      <source bridge='virbr1'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
      <alias name='net0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

Pour mettre à jour l'attachement de la carte réseau :

virsh update-device vm-test virbr1.xml

Ajout d'une seconde interface

On peut prendre une définition d'interface comme suit. Il s'agit de modifier balise "alias name" en mettant une nouvelle valeur net1 par exemple et en modifiant l'adresse MAC pour la rendre originale :

<interface type='bridge'>
      <mac address='52:54:00:aa:bb:cc'/>
      <source bridge='virbr1'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
      <alias name='net0'/>
</interface>

On peut alors attacher la carte au domaine en "live" :

virsh attach-device nom_de_domaine fichier.xml

Réseau isolé

fichier xml

Réseau bridge

virsh ...

Exercice

  • créer un routeur virtuel Linux

13. Exemples de scripts automatiques

13.1. virt-builder

Le logiciel virt-builder permet de construire rapidement une VM à partir d'une image disponible sur le site de libguestfs. Il est paramétrable : voir http://libguestfs.org/virt-builder.1.html.

virt-builder --list

On citera aussi le projet OZ : https://github.com/clalancette/oz.

13.2. Exemples de code de déploiement

14. Automation des installations

14.1. Améliorations des scripts précédents

On peut tenter d'améliorer les scripts des exercices précédents et se poser quelques questions

Configuration profils de VM

Configuration Kickstart

  • adresse IP statique ou dhcp gérée ?
  • IPv6
  • partitionnement automatique / personnalisé LVM2
  • hostname
  • clé SSH
  • paquets nécessaires
  • commandes post install (service, hostname, fichiers, etc.)

14.2. Projet

Déploiement silencieux selon un profil de VM et d'installation.

Etude de cas :

  • déploiement et gestion de VPS

Résumé

  • profils de VM (Centos 7)
    • small, medium, large
    • modèle à cloner : small + virt-sysprep + sparsify + virt-clone
  • profils d'installation
    • core + bootproto dhcp
    • docker-engine, httpd, mariadb, ... + bootproto static
  • Déploiement de services
    • Traditionnel : scripts et fichier Kickstart
    • Ansible : playbooks (modules rpm, ...)
    • Docker
    • Une combinaison
  • Surveillance / rapports
    • scripts
    • solutions commerciales / WebUI

Pré-requis

Cet exercice est réalisé sous Centos 7.

Un serveur Web sur l'hyperviseur, httpdpar exemple, ou situé ailleurs rend disponible deux dossiers dans /var/www/html :

  • /var/www/html/repo : contient la copie d'un CD d'installation
  • /var/www/html/conf : contient le script de création, les fichiers Kickstart générés et une clé publique SSH

Deux sources sont à définir :

  • Sources d'installation : HTTP ou local
  • Fichier Kickstart : HTTP ou local

Profil de machine virtuelle "small"

Un script de création VM "small"

  • 1 vCPU
  • 1 Go RAM
  • 16 Go qcow2
  • NIC : virb1 (192.168.22.0)

profil d'installation "core"

Configuration du système prédéfini dans un fichier Kickstart auquel correspond un profil d'installation Centos 7 avec un minimum de paquets, authentification à clé SSH et partionnement LVM2.

Il est nécessaire copier la clé publique de l'administrateur afin d'assurer

14.3. Première procédure

Firewalld désactivé

Pour les besoins de l'exercice, on désactivera le pare-feu.

systemctl stop firewalld

Création d'un réseau NAT dénommé lab

  • NAT
  • 192.168.22.254/24
  • DHCP .100-.150
  • virb1

Script virt-install "autovm.sh"

#/bin/bash

## usage : autovm.sh [type] [nom domaine]
##         autovm.sh $1 $2
## types (appel d'un fichier kickstarts): 
##         core

## Variables
## 1. $type : Fichier Kickstart
type=$1
## 2. $name : Nom du domaine
name=$2
## 3. $vol : Emplacement des disques
vol=/var/lib/libvirt/images
## 4. $conf : Emplacement HTTP des fichiers Kickstart
conf=http://192.168.122.1/conf
## 5. $mirror : Sources d'installation HTTP
mirror=http://192.168.122.1/repo
## Miroirs publics
#mirror=http://centos.mirrors.ovh.net/ftp.centos.org/7/os/x86_64
#mirror=http://ftp.belnet.be/ftp.centos.org/7/os/x86_64
#mirror=http://mirror.i3d.net/pub/centos/7/os/x86_64
## 6. $temp : nom temporaire pour le fichier Kickstart
temp="$name-$(uuidgen | cut -d - -f 1)"
## 7. $www : emplacement physique des fichiers de configuration
www=/var/www/html/conf

gest_dom ()
{
## Gestion des noms utilisés, ici pour un lab (à améliorer)
## Arrêt et retrait de la VM
echo "Arrêt et retrait de la VM $name" 
/bin/virsh destroy $name; /bin/virsh undefine $name --remove-all-storage
}


prep_ks ()
{
## Préparation du fichier Kickstart
echo "Préparation du fichier Kickstart"
cp $www/$type.ks $www/$temp.ks
chown apache:apache $www/$temp.ks
## Report du hostname 
sed -i "s/network --hostname=.*/network --hostname=$name/g" $www/$temp.ks
## 
}

virt_install ()
{
## Démarrage de l'installation du domaine
echo "Démarrage de l'installation du domaine $name"
## Installation et lancement silencieux en mode texte
## selon la baseline définie Centos 7 1GB/1vCPU/HD8GB/1NIC/ttyS0
nohup \
virt-install \
--virt-type kvm \
--name=$name \
--disk path=/var/lib/libvirt/images/$name.qcow2,size=8,format=qcow2 \
--ram=1024 \
--vcpus=1 \
--os-variant=rhel7 \
--network bridge=virbr0 \
--graphics none \
--noreboot \
--console pty,target_type=serial \
--location $mirror \
-x "ks=$conf/$temp.ks console=ttyS0,115200n8 serial" \
> /dev/null 2>&1 &


## choix installation cdrom avec Kickstart local
#ks=/var/www/html/conf
#iso=path/to/iso
#--cdrom $iso \
#--initrd-inject=/$temp.ks -x "ks=file:/$temp.ks console=ttyS0,115200n8 serial" \
}

gest_dom
prep_ks
virt_install

# rm -f $www/$temp.ks

Fichier kickstart core.ks

## hostname
## bootproto dhcp ou static
##NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
## vda             252:0    0    8G  0 disk 
## ├─vda1          252:1    0  500M  0 part /boot
## ├─vda2          252:2    0  6,7G  0 part        (auto-grow)
## │ └─local0-root 253:0    0  3,9G  0 lvm  / 
## └─vda3          252:3    0  820M  0 part [SWAP] (auto-grow)
## install @core (minimum de paquets)
## post-install : update
## post-configuration ssh 
install
keyboard --vckeymap=be-oss --xlayouts='be (oss)'
reboot
rootpw --plaintext testtest
timezone Europe/Brussels
url --url="http://192.168.122.1/repo"
lang fr_BE
firewall --disabled
network --bootproto=dhcp --device=eth0
network --hostname=template
# network --device=eth0 --bootproto=static --ip=192.168.22.10 --netmask 255.255.255.0 --gateway 192.168.22.254 --nameserver=192.168.22.11 --ipv6 auto
auth  --useshadow  --passalgo=sha512
text
firstboot --enable
skipx
ignoredisk --only-use=vda
bootloader --location=mbr --boot-drive=vda
zerombr
clearpart --all --initlabel
part /boot --fstype="xfs" --ondisk=vda --size=500
part swap --recommended
part pv.00 --fstype="lvmpv" --ondisk=vda --size=500 --grow
volgroup local0 --pesize=4096 pv.00
logvol /  --fstype="xfs"  --size=4000 --name=root --vgname=local0
%packages
@core
%end
%post
#yum -y update
mkdir /root/.ssh
curl http://192.168.122.1/conf/id_rsa.pub > /root/.ssh/authorized_keys
sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
%end

14.4. Automation Ansible

Pré-requis

Seul pré-requis : Sytème Linux (Centos 7) avec un accès ssh avec authentification avec clé et Python installé.

Une résolution de nom robuste est conseillée.

Concepts

  • Inventaire (fichier hosts)
  • Modules
  • Playbooks

Installation

yum install ansible
echo "nameserver 192.168.122.1" >> /etc/resolv.conf
mv /etc/ansible/hosts /etc/ansible/hosts.old
echo -e "[lab]\nvm0[1:4]" > /etc/ansible/hosts
cat /etc/ansible/hosts

Modules

ansible all -m ping
ansible vm01 -m ping
ansible all -m setup
ansible lab -m yum -a "name=openssh-server state=present"

Playbooks

14.5. Seconde procédure

Dans cette seconde procédure, on pourra choisir le profil de la machine virtuelle à partir d'un seul script.

Ce script vise à créer une machine virtuelle KVM d'une certaine capacité (small, medium, large) de manière automatique.

L'installation est minimale mais suffisante (core) pour assurer la gestion par Ansible et déployer des containers en tant que services.

On peut l'améliorer dans le profilage des installations (pré-installation, services, fichiers de configuration mais aussi dans la maintenance de la machine virtuelle (fin de l'installation, suppression du fichier Kickstart, --> via boucle while/surveillance du processus lancé, génération de rapports, logs) ou encore la gestion des erreurs.

Une option "gold image" ou modèle qui permettrait de préparer une VM et de cloner une telle installation fraîche serait un must, car elle répondrait à autre approche d'une solution de déploiement automatique de machines virtuelles.

Pour comprendre ce script, on le lira en trois temps :

  1. variables générales au début
  2. et leur corps principal (tout à la fin)
  3. qui appelle trois fonctions :
    • gest_dom : qui efface le domaine invoqué (niveau de sévérité : lab)
    • prep_ks : qui prépare le fichier d'installation Kickstart
    • virt_install : qui crée la machine, la lance et démarre l'installation automatique.
#/bin/bash
# fichier autovm.sh
## usage : autovm.sh [type] [nom domaine]
##         autovm.sh $1 $2
## Création et installation automatisée Fedora/Centos 7
## types (profils, baselines): 
##         small, medium ou large
##
## Variables générales
## 1. $name : Nom du domaine
name=$2
## 2. $type : type d'installation
type=$1
## 3. $vol : Emplacement des disques
vol=/var/lib/libvirt/images
## 4. $conf : Emplacement HTTP des fichiers Kickstart
## Serveur Web sur l'hyperviseur (adresse du réseau "Default")
conf=http://192.168.122.1/conf
## 5. $mirror : Sources d'installation HTTP
mirror=http://192.168.122.1/repo
## Miroirs publics
#mirror=http://centos.mirrors.ovh.net/ftp.centos.org/7/os/x86_64
#mirror=http://ftp.belnet.be/ftp.centos.org/7/os/x86_64
#mirror=http://mirror.i3d.net/pub/centos/7/os/x86_64
## 6. $temp : nom temporaire pour le fichier Kickstart
temp="$name-$(uuidgen | cut -d - -f 1)"
## 7. $www : emplacement physique des fichiers de configuration
www=/var/www/html/conf

gest_dom ()
{
## Gestion des noms utilisés, ici pour un lab (à améliorer)
## Arrêt et retrait de la VM
echo "Arrêt et retrait de la VM $name" 
/bin/virsh destroy $name; /bin/virsh undefine $name
#Erase the VM disk
rm -f $vol/$name.*
}


prep_ks ()
{
## Préparation du fichier Kickstart
echo "Préparation du fichier Kickstart"

##
touch $www/$temp.ks
cat << EOF > $www/$temp.ks 
install
keyboard --vckeymap=be-oss --xlayouts='be (oss)'
reboot
rootpw --plaintext testtest
timezone Europe/Brussels
url --url="$mirror"
lang fr_BE
firewall --disabled
network --bootproto=dhcp --device=eth0
network --hostname=$name
# network --device=eth0 --bootproto=static --ip=192.168.22.10 --netmask 255.255.255.0 --gateway 192.168.22.254 --nameserver=192.168.22.11 --ipv6 auto
auth  --useshadow  --passalgo=sha512
text
firstboot --enable
skipx
ignoredisk --only-use=vda
bootloader --location=mbr --boot-drive=vda
zerombr
clearpart --all --initlabel
part /boot --fstype="xfs" --ondisk=vda --size=500
part swap --recommended
part pv.00 --fstype="lvmpv" --ondisk=vda --size=500 --grow
volgroup local0 --pesize=4096 pv.00
logvol /  --fstype="xfs"  --size=4000 --name=root --vgname=local0
%packages
@core
%end
%post
#yum -y update
mkdir /root/.ssh
curl $conf/id_rsa.pub > /root/.ssh/authorized_keys
sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
%end
EOF

chown apache:apache $www/$temp.ks
}

virt_install ()
{

installation ()
{
## Démarrage de l'installation du domaine
echo "Démarrage de l'installation du domaine $name"
## Installation et lancement silencieux en mode texte
## selon le profil (baseline) défini dans la variable $type
nohup \
/bin/virt-install \
--virt-type kvm \
--name=$name \
--disk path=$vol/$name.$format,size=$size,format=$format \
--ram=$ram \
--vcpus=$vcpus \
--os-variant=rhel7 \
--network bridge=$bridge \
--graphics none \
--noreboot \
--console pty,target_type=serial \
--location $mirror \
-x "ks=$conf/$temp.ks console=ttyS0,115200n8 serial" \
> /dev/null 2>&1 &

## choix installation cdrom avec Kickstart local
#ks=/var/www/html/conf
#iso=path/to/iso
#--cdrom $iso \
#--initrd-inject=/$temp.ks -x "ks=file:/$temp.ks console=ttyS0,115200n8 serial" \
}

if [ $type = small ] ; then
        size=8
        format=qcow2
        ram=1024
        vcpus=1
        bridge=virbr0
    installation
elif [ $type = medium ] ; then
        size=16
        format=qcow2
        ram=2048
        vcpus=2
        bridge=virbr0
    installation
elif [ $type = large ] ; then
        size=32
        format=qcow2
        ram=4096
        vcpus=4
        bridge=virbr0
    installation
else
        exit
fi
}

gest_dom
prep_ks
virt_install

# rm -f $www/$temp.ks

15. Surveillance

...

results matching ""

    No results matching ""