Skip to content

Virtualisation KVM/libvirt

Introduction

KVM (Kernel-based Virtual Machine) est l'hyperviseur utilisé par défaut avec Nova, le service de compute d'OpenStack. Comprendre KVM et libvirt est essentiel pour administrer les nœuds compute et diagnostiquer les problèmes de VMs.

Cette section couvre l'installation, la configuration et l'utilisation de KVM via libvirt.

Prérequis

Points à apprendre

Vérification support matériel

# Vérifier le support CPU
grep -E '(vmx|svm)' /proc/cpuinfo

# vmx = Intel VT-x
# svm = AMD-V

# Vérifier si KVM est chargé
lsmod | grep kvm

# Si non chargé
modprobe kvm
modprobe kvm_intel  # ou kvm_amd

Installation KVM/libvirt

# Ubuntu/Debian
apt update
apt install -y qemu-kvm libvirt-daemon-system libvirt-clients \
    virtinst bridge-utils virt-manager

# RHEL/Rocky/AlmaLinux
dnf install -y qemu-kvm libvirt libvirt-client virt-install \
    virt-manager bridge-utils

# Démarrer et activer libvirtd
systemctl enable --now libvirtd

# Ajouter l'utilisateur au groupe libvirt
usermod -aG libvirt $USER
usermod -aG kvm $USER

Architecture libvirt

graph TB
    subgraph Apps["Applications"]
        virsh["virsh"]
        virt_manager["virt-manager"]
        nova["OpenStack Nova"]
    end

    subgraph API["libvirt API"]
        libvirt_api[" "]
    end

    subgraph Daemon["libvirtd daemon"]
        storage["Storage Pools"]
        network["Network (bridges)"]
        compute["Compute (domains)"]
    end

    subgraph Hypervisor["QEMU/KVM"]
        qemu[" "]
    end

    subgraph Kernel["Linux Kernel"]
        kvm["KVM module"]
    end

    virsh --> libvirt_api
    virt_manager --> libvirt_api
    nova --> libvirt_api
    libvirt_api --> storage
    libvirt_api --> network
    libvirt_api --> compute
    storage --> qemu
    network --> qemu
    compute --> qemu
    qemu --> kvm

Virsh - CLI libvirt

Commandes de base

# Connexion
virsh connect qemu:///system

# Lister les VMs
virsh list --all

# Gestion lifecycle
virsh start nom-vm
virsh shutdown nom-vm       # ACPI shutdown
virsh destroy nom-vm        # Force stop
virsh reboot nom-vm
virsh suspend nom-vm
virsh resume nom-vm

# Informations
virsh dominfo nom-vm
virsh domblklist nom-vm     # Disques attachés
virsh domiflist nom-vm      # Interfaces réseau
virsh vcpuinfo nom-vm

# Console
virsh console nom-vm        # Serial console (Ctrl+] pour quitter)

# Suppression
virsh undefine nom-vm
virsh undefine nom-vm --remove-all-storage  # + supprime disques

Snapshots

# Créer snapshot
virsh snapshot-create-as nom-vm snap1 "Description snapshot"

# Lister snapshots
virsh snapshot-list nom-vm

# Revenir à un snapshot
virsh snapshot-revert nom-vm snap1

# Supprimer snapshot
virsh snapshot-delete nom-vm snap1

Création de VMs avec virt-install

VM basique depuis ISO

virt-install \
  --name ubuntu-test \
  --ram 2048 \
  --vcpus 2 \
  --disk path=/var/lib/libvirt/images/ubuntu-test.qcow2,size=20 \
  --os-variant ubuntu24.04 \
  --network bridge=virbr0 \
  --graphics vnc,listen=0.0.0.0 \
  --cdrom /var/lib/libvirt/images/ubuntu-24.04-live-server.iso \
  --boot cdrom,hd

VM depuis image cloud (cloud-init)

# Télécharger image cloud Ubuntu
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img \
  -O /var/lib/libvirt/images/ubuntu-cloud.img

# Créer disque depuis image
qemu-img create -f qcow2 -F qcow2 \
  -b /var/lib/libvirt/images/ubuntu-cloud.img \
  /var/lib/libvirt/images/vm1.qcow2 20G

# Créer fichier cloud-init
cat > /tmp/user-data << 'EOF'
#cloud-config
hostname: vm1
users:
  - name: ubuntu
    sudo: ALL=(ALL) NOPASSWD:ALL
    shell: /bin/bash
    ssh_authorized_keys:
      - ssh-rsa AAAA... votre-clé-publique
chpasswd:
  list: |
    ubuntu:password123
  expire: False
package_update: true
packages:
  - qemu-guest-agent
EOF

cat > /tmp/meta-data << 'EOF'
instance-id: vm1
local-hostname: vm1
EOF

# Créer ISO cloud-init
genisoimage -output /tmp/cidata.iso -V cidata -r -J \
  /tmp/user-data /tmp/meta-data

# Créer la VM
virt-install \
  --name vm1 \
  --ram 2048 \
  --vcpus 2 \
  --disk /var/lib/libvirt/images/vm1.qcow2 \
  --disk /tmp/cidata.iso,device=cdrom \
  --os-variant ubuntu24.04 \
  --network bridge=virbr0 \
  --graphics none \
  --console pty,target_type=serial \
  --import \
  --noautoconsole

Gestion des disques

Formats d'image

Format Description Avantages
qcow2 QEMU Copy-On-Write Snapshots, thin provisioning
raw Image brute Performance max
vmdk VMware Compatibilité

Commandes qemu-img

# Informations sur image
qemu-img info image.qcow2

# Créer image
qemu-img create -f qcow2 disk.qcow2 50G

# Convertir format
qemu-img convert -f raw -O qcow2 disk.raw disk.qcow2

# Redimensionner
qemu-img resize disk.qcow2 +20G

# Créer image depuis backing file (COW)
qemu-img create -f qcow2 -F qcow2 -b base.qcow2 overlay.qcow2

Storage Pools

# Lister pools
virsh pool-list --all

# Créer un pool directory
virsh pool-define-as mypool dir - - - - /data/libvirt/images
virsh pool-build mypool
virsh pool-start mypool
virsh pool-autostart mypool

# Créer un volume dans le pool
virsh vol-create-as mypool myvol.qcow2 20G --format qcow2

# Lister volumes
virsh vol-list mypool

Réseaux libvirt

Types de réseaux

Type Description Cas d'usage
NAT (virbr0) Réseau NAT par défaut Lab simple
Bridge Bridge vers interface physique Production
Isolated Réseau isolé sans routage Inter-VM uniquement
macvtap Accès direct à l'interface Performance

Réseau bridge (production)

# Créer fichier XML pour réseau bridgé
cat > /tmp/br-net.xml << 'EOF'
<network>
  <name>br-external</name>
  <forward mode="bridge"/>
  <bridge name="br0"/>
</network>
EOF

# Définir et démarrer
virsh net-define /tmp/br-net.xml
virsh net-start br-external
virsh net-autostart br-external

Configuration bridge système (netplan)

# /etc/netplan/00-bridge.yaml
network:
  version: 2
  ethernets:
    enp1s0:
      dhcp4: false
  bridges:
    br0:
      interfaces: [enp1s0]
      addresses: [192.168.1.10/24]
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
      parameters:
        stp: false
        forward-delay: 0
netplan apply

Monitoring et troubleshooting

# Logs libvirt
journalctl -u libvirtd -f

# Logs QEMU par VM
ls /var/log/libvirt/qemu/

# Statistiques VM
virsh domstats nom-vm

# CPU stats
virsh cpu-stats nom-vm

# Block I/O stats
virsh domblkstat nom-vm vda

# Network stats
virsh domifstat nom-vm vnet0

# Top pour VMs
virt-top

Configuration avancée (XML)

# Exporter config XML
virsh dumpxml nom-vm > vm.xml

# Éditer config (ouvre éditeur)
virsh edit nom-vm

# Modifier à chaud (certains paramètres)
virsh setmem nom-vm 4G --live
virsh setvcpus nom-vm 4 --live

# Attacher disque à chaud
virsh attach-disk nom-vm /path/to/disk.qcow2 vdb --driver qemu --subdriver qcow2 --live

Exemples pratiques

Lab 1 : Créer un environnement multi-VM

#!/bin/bash
# Script création lab OpenStack-like

BASE_IMG="/var/lib/libvirt/images/ubuntu-cloud.img"
POOL_PATH="/var/lib/libvirt/images"

# Fonction création VM
create_vm() {
    local name=$1
    local ram=$2
    local vcpus=$3
    local disk_size=$4

    # Créer disque
    qemu-img create -f qcow2 -F qcow2 \
      -b $BASE_IMG \
      $POOL_PATH/${name}.qcow2 ${disk_size}G

    # Cloud-init
    cat > /tmp/${name}-user-data << EOF
#cloud-config
hostname: $name
users:
  - name: ubuntu
    sudo: ALL=(ALL) NOPASSWD:ALL
    ssh_authorized_keys:
      - $(cat ~/.ssh/id_rsa.pub)
EOF

    cat > /tmp/${name}-meta-data << EOF
instance-id: $name
local-hostname: $name
EOF

    genisoimage -output /tmp/${name}-cidata.iso -V cidata -r -J \
      /tmp/${name}-user-data /tmp/${name}-meta-data 2>/dev/null

    # Créer VM
    virt-install \
      --name $name \
      --ram $ram \
      --vcpus $vcpus \
      --disk $POOL_PATH/${name}.qcow2 \
      --disk /tmp/${name}-cidata.iso,device=cdrom \
      --os-variant ubuntu24.04 \
      --network bridge=virbr0 \
      --graphics none \
      --import \
      --noautoconsole
}

# Créer 3 VMs
create_vm "controller-1" 4096 2 30
create_vm "controller-2" 4096 2 30
create_vm "compute-1" 8192 4 50

echo "VMs créées. Attendre démarrage puis récupérer IPs avec:"
echo "virsh net-dhcp-leases default"

Lab 2 : Migration live

# Sur l'hôte source, configurer migration
virsh migrate --live nom-vm qemu+ssh://destination/system

# Avec stockage partagé (NFS/Ceph)
virsh migrate --live --persistent --undefinesource \
  nom-vm qemu+ssh://destination/system

Ressources

Checkpoint

  • Je peux vérifier le support matériel de virtualisation
  • Je sais créer une VM avec virt-install
  • Je maîtrise les commandes virsh essentielles
  • Je comprends les différents types de réseaux libvirt
  • Je peux configurer un bridge réseau pour les VMs
  • Je sais créer et gérer des snapshots de VMs