Catégories
Uncategorized

Docker – VM modèle ou installation automatique

Je voulais initialement mettre au point une VM modèle que je pourrais cloner pour servir de base à une machine paramétrable avec Ansible. La mise au point de la VM passse par l’installation de l’OS et cette phase vait aussi pour une machine physique. Comme l’informatique est la science de ceux qui n’aiment pas se répéter, je me lance donc sur le sujet d’automatisation d’une installation.

Preseed

Le processus d’installation d’un système Debian peut peut-être automatisé par un fichier preseed.cfg qui contient les réponses aux questions de l’installateur. La mise au point de ce fichier merite l’utilisation de l’intégration continue qui consistera à :

  1. rappatrier une ISO de debian en version stable
  2. extraire l’ISO
  3. ajouter le preseed
  4. recréer l’ISO
  5. demarrer une VM sur l’ISO
  6. vérifier que le système installé répond à l’attente
  7. déployer l’ISO pour utilisation future.

Gitlab-runner et libvirt

Le principe est séduisant mais il faut que je trouve comment depuis un gitlab-runner lancer une VM. Cette VM devra être créée from scrach pour bien reproduire le cas d’utilisation de l’ISO custom. J’entrevois déjà des questions nouvelles dans la coneption de la solution: idealement le test devrait se faire dans un conteneur mais la mise sous docker sera impossible car le conteneur partage les librairies systèmes (noyau) de l’hôte. Donc le seul moyen d’isoler le test création/installation de VM serait de le faire sur un hôte dédié: une VM avec gitlab-runner et libvirt afin de créer des VM !

Affaire à suivre….

Catégories
Application Paramétrage

kvm – ajouter de l’espace disque à chaud

En train d’importer un blog avec 36000 entrées à partir d’un fichier de WRX de 54 Mo, je voyais l’espace disque se remplir à vue d’oeil ! à 92% munin commençait à m’envoyer des mails d’alerte.

Pas de panique, comme j’utilise kvm et lvm, l’ajout d’espace disque peut se faire à chaud. La difficulté était que je devais tout faire en shell distant.

J’ai ainsi réussi à sauver mon processus d’import en ajoutant un disque et augmenter le volume logique mais le disque virtuelle était au mauvais format: 20 Go virtuel et 20 Go sur l’hôte même si il était vide.

Finalement voici la méthode pour ajouter à chaud de l’espace sur une VM en train de saturer.

Créer un nouveau disque

Se mettre sur l’hôte et en tant que root en remplaçant staging-2.qcow par ce que vous voulez:

qemu-img create -f qcow2 /var/lib/libvirt/images/staging-2.qcow2 20G

Ne pas utiliser les option de preallocation

Attacher le disque à la VM

C’est là que réside la subtilité pour que la VM croire avoir à faire à un disque de 20G même si le fichier ne fait que quelques centaines de kilos. La commande qemu-img info permet de voir les propriétés du disque virtuel.

/var/lib/libvirt/images# qemu-img info staging-2.qcow2
image: test.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 196K
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false



On va attacher le disque à la VM en précisant bien le driver qcow2

# virsh attach-disk staging /var/lib/libvirt/images/staging-2.qcow2 vdb --driver qemu --subdriver qcow2 --targetbus virtio --persistent --config --live

Remplacer vdb par un identifiant de device disponible dans la VM qui s’appelle ici staging.

En tant que root sur le VM, vérifier la présence du disque et qu’il a la bonne taille

# fdisk -l

Disque /dev/vdb : 20 GiB, 21474836480 octets, 41943040 secteurs
Unités : secteur de 1 × 512 = 512 octets
Taille de secteur (logique / physique) : 512 octets / 512 octets
taille d'E/S (minimale / optimale) : 512 octets / 512 octets

Ajouter le disque /dev/vdb dans le volume group à étendre., ici staging-vg

# vgextend staging-vg /dev/vdb

Ajouter tout l’espace au volume logique, ici /dev/staging-vg/root

# lvm lvextend -l +100%FREE /dev/staging-vg/root

Redimensionner le système de fichier qui se trouve ici dans /dev/mapper/staging--vg-root

resize2fs -p /dev/mapper/staging--vg-root

Catégories
Uncategorized

Sauvegarde à chaud de VM

Avoir du RAID redondé c’est bien pour éviter la coupure de service en cas de panne matériel mais cela ne protège pas des effacements par erreur. Il faut des sauvegardes.

Comme ce que je recherche c’est de pouvoir revenir à  un l’état de mes données dans le passé, je laissz dz côté la sauvegarde de la définition des VM.

Un script glané sur le site de Debian me sert de base https://wiki.debian.org/fr/RsyncSnapshots. Il utilise rsync avec des liaison dur avec la précédente sauvegarde. Un peu inutile quand les VM sont allumée en permanence mais trouve son intérêt quand les fichiers ne changent pas d’une sauvegarde à l’autre.

Voici le script:

#!/bin/sh
##==========================================================================
## Auteur      : Thierry BRESSURE
## Licence     : GNU GPL v3 – http://www.gnu.org/licenses/gpl.html
## Description : Script de sauvegarde disques des VM
##============================================================================
## Parametres d’entree : liste des profils a sauvegarder.
## Exemple d’appel     : rsync.sh blog kitejust4fun
## Code de retour      :
##  0 – La sauvegarde des disques s’est correctement terminee.
##============================================================================

ROOT_BACKUP=/media/backup
DEVICE_BACKUP=/dev/sdc1

#####################################
# GESTION DE L’APPEL DE LA COMMANDE #
#####################################

# Recuperation des profils passes en parametre.
if [ $# -ne 0 ]
then
    while [ $# -ne 0 ]
    do
        domains= »$domains $1  »
        shift
    done
# Aucun domain n’est passe en parametre, on fait donc la sauvegarde pour tout
# le monde.
else
    # lister les vm
    domains=`virsh list | sed 1,2d | awk ‘{print $2}’`   
fi

###################################
# MONTAGE DU DISQUE DE SAUVEGARDE #
###################################

if [ ! -d $ROOT_BACKUP ]
then
   rm -rf $ROOT_BACKUP
   mkdir $ROOT_BACKUP
fi

montage=0

mount | grep « $ROOT_BACKUP » 2>/dev/null
if [ $? -ne 0 ]
then
mount -t ext4 $DEVICE_BACKUP $ROOT_BACKUP && montage=1

fi

####################################
# BOUCLE DE SAUVEGARDE DES PROFILS #
####################################

for un_domain in $domains
do

date_sauvegarde=$(date « +%Y%m%d_%H%M%S »)

echo
echo « ${date_sauvegarde} – sauvegarde de la VM ${un_domain} »
        echo « —————————————– »
     

nombre_de_sauvegardes=2
# Creation d’un fichier temporaire pour y ecrire les fichiers et
# repertoires a ne pas sauvegarder (pour ne mettre que le fichier
# temporaire en parametre de la commande rsync)
ce_quil_ne_faut_pas_sauvegarder=$(tempfile)
:>$ce_quil_ne_faut_pas_sauvegarder
# Exclusions generales
echo « *~ » >> $ce_quil_ne_faut_pas_sauvegarder

## DECOUVRIR LES DISQUES DE LA VM

        les_disques=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $3}’`
        les_images_disques=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $4}’`
               
       

## CREER UN SNAPSHOT
    virsh snapshot-create-as –domain ${un_domain} « ${date_sauvegarde} » –atomic –disk-only

        ## garder en memoire les disques temporaires de la VM

        les_disques_temp=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $3}’`
        les_images_disques_temp=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $4}’`

## SAUVEGARDE

  # Si le repertoire de sauvegarde n’existe pas, je le cree.
    if [ ! -d $ROOT_BACKUP/vm_ »${un_domain} » ]
    then
        echo « L’emplacement de la sauvegarde n’existait pas. »
        mkdir $ROOT_BACKUP/vm_ »${un_domain} »
    fi

    ##############
    # SAUVEGARDE #
    ##############
   
    #il peut avoir plus d’un disque à sauvegarder
    for ce_quil_faut_sauvegarder in ${les_images_disques}
    do
    if [ -L $ROOT_BACKUP/vm_ »${un_domain} »/current ] \
        && [ -d $ROOT_BACKUP/vm_ »${un_domain} »/current ]
   then
        # Si une precedente sauvegarde existe, on la lie en dur.
        rsync  –delete-excluded –partial \
       –skip-compress=gz/jpg/mp[34]/7z/bz2 –stats -rlpthz \
       –link-dest=$ROOT_BACKUP/vm_ »${un_domain} »/current \
–exclude-from « ${ce_quil_ne_faut_pas_sauvegarder} » \
« ${ce_quil_faut_sauvegarder} » \
      $ROOT_BACKUP/vm_ »${un_domain} »/ »${date_sauvegarde} »/
else
        # Sinon, on en cree une toute neuve !
      rsync –delete-excluded –partial \
      –skip-compress=gz/jpg/mp[34]/7z/bz2 –stats -rlpthz \
–exclude-from « ${ce_quil_ne_faut_pas_sauvegarder} » \
       « ${ce_quil_faut_sauvegarder} » \
       $ROOT_BACKUP/vm_ »${un_domain} »/ »${date_sauvegarde} »/
    fi

    retour_rsync=$?
if [ $retour_rsync -ne 0 ]
then
echo « le disque ${ce_quil_faut_sauvegarder} n’a pas pu etre sauvegarder, on annule le reste »
break
fi      
echo # Pour passer une ligne 🙂

    done

    # Suppression du fichier temporaire qui stocke les repertoires a exclure
    rm $ce_quil_ne_faut_pas_sauvegarder

    #######################
    # GESTION DES ERREURS #
    #######################

    # Pas d’erreur
    if [ $retour_rsync -eq 0 ]
    then
        # La sauvegarde a reussit, on cree un lien « current » pour retenir la
        # derniere.
        rm -f $ROOT_BACKUP/vm_ »${un_domain} »/current 2>/dev/null
        ln -s $ROOT_BACKUP/vm_ »${un_domain} »/ »${date_sauvegarde} »/ \
            $ROOT_BACKUP/vm_ »${un_domain} »/current

        # Si le nombre de snapshots depasse nombre_de_sauvegardes, je purge.
        nombre_snapshots=$((`ls $ROOT_BACKUP/vm_ »${un_domain} » | wc -l` – 1))
        if [ ${nombre_snapshots} -gt $nombre_de_sauvegardes ]
        then
            # On supprime la plus vieille des sauvegardes
            plus_ancienne= »$(ls $ROOT_BACKUP/vm_ »${un_domain} » | head -n 1) »
            rm -rf $ROOT_BACKUP/vm_ »${un_domain} »/ »${plus_ancienne} »
            echo « Purge de la plus ancienne sauvegarde : ${plus_ancienne}. »
        else
            echo « Aucune sauvegarde anterieure ne doit etre supprimee. »
        fi
    # Probleme lors de la sauvegarde rsync
    else
        # La sauvegarde a echouee, on affiche une erreur et on supprime la
        # tentative.
        echo « La commande rsync a echouee pour l’utilisateur ${un_domain}. »
        echo « Suppression de la sauvegarde en erreur : ${date_sauvegarde}. »
        rm -rf $ROOT_BACKUP/vm_ »${un_domain} »/ »${date_sauvegarde} »/
    fi
   

## REBASCULER LA VM VERS CHAQUE DISQUE ORIGINAL
    for un_disque in $les_disques
do
    virsh blockcommit ${un_domain} ${un_disque} –active –verbose –pivot
done
   
## SUPPRIMER LE SNAPSHOT DEVENU INUTILE
        virsh snapshot-delete –domain ${un_domain} –metadata ${date_sauvegarde}

## supprimer les disques temporaires qui ne sont hélas pas supprimés par la commande précédente
for image_temp in $les_images_disques_temp
do
echo « suppression du disque temporaire ${image_temp}… »
rm -rf « ${image_temp} » && echo « $image_temp supprimé »
done
done

###########################
# démontage si nécessaire #
###########################

if [ $montage -eq 1 ]
then
    umount $ROOT_BACKUP
fi

exit 0

Juste pour le plaisir… CC-BY-SA