Migrer un serveur dédié OVH vers une machine virtuelle Hyper-V

Nous avons un serveur dédié chez OVH depuis quelques années, dont le rapport configuration/prix n’est plus très intéressant si on compare aux serveurs actuellement disponible chez OVH.
Un problème qu’on n’a pas vu arriver est la migration des données d’une machine physique dédiée, à laquelle on n’a accès que par SSH, sur une autre machine.
Pour pallier à ce problème, nous avons choisi de convertir la machine en question en machine virtuelle qui sera donc indépendante du matos.

Pour commencer, nous avons configuré le serveur dédié d’origine pour effectuer des sauvegardes sous forme de tar.gz, via l’utilisation du soft « backup-manager ».

Nous nous sommes basé sur cet article pour la configuration de « backup-manager ».

Ci-dessous le fichier de configuration que nous avons fait :

# Backup Manager Configuration File
#
# * This configuration file is divided into sections.
# The 'global' section is mandatory, every keys defined in
# this section are inherited in the other sections.
# * There is one section per "backup method", you have to
# fill the section of the chosen method.
#
##############################################################

##############################################################
# Repository - everything about where archives are
#############################################################

# Where to store the archives
export BM_REPOSITORY_ROOT="/home/backup"

# Where to place temporary files
export BM_TEMP_DIR="/tmp"

# For security reasons, the archive repository and the generated
# archives will be readable/writable by a given user/group.
# This is recommended to set this to true.
export BM_REPOSITORY_SECURE="true"

# The repository will be readable/writable only by a specific
# user:group pair if BM_REPOSITORY_SECURE is set to true.
export BM_REPOSITORY_USER="root"
export BM_REPOSITORY_GROUP="root"
# You can also choose the permission to set the repository, default
# is 770, pay attention to what you do there!
export BM_REPOSITORY_CHMOD="770"

##############################################################
# Archives - let's focus on the precious tarballs...
##############################################################

# Each archive generated will be chmoded for security reasons
# (BM_REPOSITORY_SECURE should be enabled for this).
export BM_ARCHIVE_CHMOD="660"

# Number of days we have to keep an archive (Time To Live)
export BM_ARCHIVE_TTL="5"

# Do you want to purge only the top-level directory or all
# directories under BM_REPOSITORY_ROOT?
export BM_REPOSITORY_RECURSIVEPURGE="false"

# Do you want to replace duplicates by symlinks?
# (archive-DAY is a duplicate of archive-(DAY - 1) if they
# are both the same according to MD5 hashes).
export BM_ARCHIVE_PURGEDUPS="true"

# Prefix of every archive on that box (default is HOSTNAME)
export BM_ARCHIVE_PREFIX="$HOSTNAME"

# Should we purge only archives built with $BM_ARCHIVE_PREFIX
export BM_ARCHIVE_STRICTPURGE="true"

# You may want to nice the commands run for archive-creation
# (Recommanded for desktop users.)
# Choose a nice level from -20 (most favorable scheduling) to 19 (least favorable).
export BM_ARCHIVE_NICE_LEVEL="10"

# The backup method to use.
# Available methods are:
# - tarball
# - tarball-incremental
# - mysql
# - svn
# - pipe
# - none
# If you don't want to use any backup method (you don't want to
# build archives) then choose "none"
export BM_ARCHIVE_METHOD="tarball mysql"

##############################################################
# Encryption - because you cannot trust the place your
# archives are
##############################################################

# If you want to encrypt your archives locally, Backup Manager
# can use GPG while building the archive (so the archive is never
# written to the disk without being encrypted.

# Note: this feature is only possible with the following archive types:
# tar, tar.gz, tar.bz2

# Uncomment the following line if you want to enable encryption
# available method: gpg
export BM_ENCRYPTION_METHOD="false"

# The encryption will be made using a GPG ID
# Examples:
# export BM_ENCRYPTION_RECIPIENT=""
# export BM_ENCRYPTION_RECIPIENT=""
export BM_ENCRYPTION_RECIPIENT=""

##############################################################
# Section "TARBALL"
# - Backup method: tarball
#############################################################

# Archive filename format
# long : host-full-path-to-folder.tar.gz
# short : parentfolder.tar.gz
export BM_TARBALL_NAMEFORMAT="long"

# Type of archives
# Available types are:
# tar, tar.gz, tar.bz2, tar.lz, dar, zip.
# Make sure to satisfy the appropriate dependencies
# (bzip2, dar, lzma, ...).
export BM_TARBALL_FILETYPE="tar.gz"

# You can choose to build archives remotely over SSH.
# You will then need to fill the BM_UPLOAD_SSH variables
# (BM_UPLOAD_SSH_HOSTS, BM_UPLOAD_SSH_USER, BM_UPLOAD_SSH_KEY).
# If this boolean is set to true, archive will be saved locally (in
# BM_REPOSITORY_ROOT but will be built by the remote host).
# Thus, BM_TARBALL_DIRECTORIES will be used to backup remote directories.
# Those archive will be prefixed with the remote host name.
export BM_TARBALL_OVER_SSH="false"

# Do you want to dereference the files pointed by symlinks ?
# enter true or false (true can lead to huge archives, be careful).
export BM_TARBALL_DUMPSYMLINKS="false"

# Targets to backup

# You can use two different variables for defining the targets of
# your backups, either a simple space-separated list (BM_TARBALL_DIRECTORIES)
# or an array (BM_TARBALL_TARGETS[]).
# Use the first one for simple path that doesn't contain spaces in their name.
# Use the former if you want to specify paths to backups with spaces.

# It's recommanded to use BM_TARBALL_TARGETS[] though.
# Warning! You *must not* use both variables at the same time.
# NOTE: The Debian package will only update BM_TARBALL_DIRECTORIES

# Paths without spaces in their name:
export BM_TARBALL_DIRECTORIES="/bin /boot /build /etc /home /lib /lib32 /lib64 /libnss3.so /media /mnt /opt /root /sbin /selinux /srv /usr /var"

# If one or more of the targets contain a space, use the array:
# declare -a BM_TARBALL_TARGETS
# BM_TARBALL_TARGETS[0]="/etc"
# BM_TARBALL_TARGETS[1]="/boot"
# export BM_TARBALL_TARGETS

# Files to exclude when generating tarballs, you can put absolute
# or relative paths, Bash wildcards are possible.
export BM_TARBALL_BLACKLIST="/home/backup"

# With the "dar" filetype, you can choose a maximum slice limit.
export BM_TARBALL_SLICESIZE="1000M"

# Extra options to append to the tarball generation
# (take care to what you do; this will be silently added to the
# command line.)
export BM_TARBALL_EXTRA_OPTIONS=""

##############################################################
# The tarball-incremental method uses the same keys as the
# tarball method, plus two others.
#############################################################

# Which frequency to use for the master tarball?
# possible values: weekly, monthly
export BM_TARBALLINC_MASTERDATETYPE="weekly"

# Number of the day, in the BM_TARBALLINC_MASTERDATETYPE frequency
# when master tarballs should be made
export BM_TARBALLINC_MASTERDATEVALUE="1"

# Examples: you want to make master tarballs every friday:
# BM_TARBALLINC_MASTERDATETYPE="weekly"
# BM_TARBALLINC_MASTERDATEVALUE="5"
#
# Or every first day of the month:
# BM_TARBALLINC_MASTERDATETYPE="monthly"
# BM_TARBALLINC_MASTERDATEVALUE="1"

##############################################################
# Backup method: MYSQl
#############################################################

# This method is dedicated to MySQL databases.
# You should not use the tarball method for backing up database
# directories or you may have corrupted archives.
# Enter here the list of databases to backup.
# Wildcard: __ALL__ (will dump all the databases in one archive)
export BM_MYSQL_DATABASES="__ALL__"

# The best way to produce MySQL dump is done by using the "--opt" switch
# of mysqldump. This make the dump directly usable with mysql (add the drop table
# statements), lock the tables during the dump and other things.
# This is recommended for full-clean-safe backups, but needs a
# privileged user (for the lock permissions).
export BM_MYSQL_SAFEDUMPS="true"

# The user who is allowed to read every databases filled in BM_MYSQL_DATABASES
export BM_MYSQL_ADMINLOGIN="root"

# its password
export BM_MYSQL_ADMINPASS="[password]"

# the host where the database is
export BM_MYSQL_HOST="localhost"

# the port where MySQL listen to on the host
export BM_MYSQL_PORT="3306"

# which compression format to use? (gzip or bzip2)
export BM_MYSQL_FILETYPE="bzip2"

##############################################################
# Backup method: svn
#############################################################

# Absolute paths to the svn repositories to archive
export BM_SVN_REPOSITORIES=""

# You can compress the resulting XML files
# Supported compressor are: bzip2 and gzip
export BM_SVN_COMPRESSWITH="bzip2"

##############################################################
# Backup method: pipe
#############################################################

# The "pipe" method is a generic way of making archive.
# Its concept is simple, for every kind of archive you want
# to make, you give: a command which will send output on stdout,
# a name, a file type and optionnaly, a compressor.

# Be careful, this feature uses arrays!
declare -a BM_PIPE_COMMAND
declare -a BM_PIPE_NAME
declare -a BM_PIPE_FILETYPE
declare -a BM_PIPE_COMPRESS

# You can virtually implement whatever backup scenario you like
# with this method.
#
# The resulting archives will be named like this:
# $BM_ARCHIVE_PREFIX-$BM_PIPE_NAME.$DATE.$BM_PIPE_FILETYPE
# If you specified a BM_PIPE_COMPRESS option, the resulting filename
# will change as expected (eg, .gz if "gzip").
#
# Here are a couple of examples for using this method:

# Archive a remote MySQL database through SSH:
# BM_PIPE_COMMAND[0]="ssh host -c \"mysqldump -ufoo -pbar base\""
# BM_PIPE_NAME[0]="base"
# BM_PIPE_FILETYPE[0]="sql"
# BM_PIPE_COMPRESS[0]="gzip"
# This will make somthing like: localhost-base.20050421.sql.gz

# Archive a specific directory, on a remote server through SSH:
# BM_PIPE_COMMAND[0]="ssh host -c \"tar -c -z /home/user\""
# BM_PIPE_NAME[0]="host.home.user"
# BM_PIPE_FILETYPE[0]="tar.gz"
# BM_PIPE_COMPRESS[0]=""
# This will make somthing like: localhost-host.home.user.20050421.tar.gz

export BM_PIPE_COMMAND
export BM_PIPE_NAME
export BM_PIPE_FILETYPE
export BM_PIPE_COMPRESS

##############################################################
# Section "UPLOAD"
# You can upload archives to remote hosts with different
# methods.
#############################################################

# Which method to use for uploading archives, you can put
# multiple methods here.
# Available methods:
# - scp
# - ssh-gpg
# - ftp
# - rsync
# - s3
# - none

# If you don't want to use any upload method (you don't want to
# upload files to remote hosts) then choose "none"
export BM_UPLOAD_METHOD=""

# where to upload (global to all methods. Not required to be set for S3)
export BM_UPLOAD_HOSTS=""

# Where to put archives on the remote hosts (global)
export BM_UPLOAD_DESTINATION=""

##############################################################
# The SSH method
#############################################################

# the user to use for the SSH connections/transfers
export BM_UPLOAD_SSH_USER=""

# The private key to use for opening the connection
export BM_UPLOAD_SSH_KEY=""

# specific ssh hosts
export BM_UPLOAD_SSH_HOSTS=""

# port to use for SSH connections (leave blank for default one)
export BM_UPLOAD_SSH_PORT=""

# destination for ssh uploads (overrides BM_UPLOAD_DESTINATION)
export BM_UPLOAD_SSH_DESTINATION=""

# purge archives on remote hosts before uploading?
export BM_UPLOAD_SSH_PURGE="true"

# If you set BM_UPLOAD_SSH_PURGE, you can specify a time to live
# for archives uploaded with SSH.
# This can let you use different ttl's locally and remotely
# By default, BM_ARCHIVE_TTL will be used.
export BM_UPLOAD_SSH_TTL=""

##############################################################
# The SSH-GPG method
# The ssh-gpg method uses the same configuration keys as the
# ssh method, plus one other
#############################################################

# The gpg public key used for encryption, this can be a short
# or long key id, or a descriptive name. See gpg man page for
# all possibilities how to specify a key.
export BM_UPLOAD_SSHGPG_RECIPIENT=""

##############################################################
# The FTP method
#############################################################

# Use FTP secured transfers (FTP over TLS)
# User, password and data will be uploaded encrypted with SSL.
# Passive mode will be automaticaly activated
export BM_UPLOAD_FTP_SECURE="false"

# Do you want to use FTP passive mode?
# This is mandatory for NATed/firewalled environments
export BM_UPLOAD_FTP_PASSIVE="true"

# the user to use for the FTP connections/transfers
export BM_UPLOAD_FTP_USER=""

# the FTP user's password
export BM_UPLOAD_FTP_PASSWORD=""

# FTP specific remote hosts
export BM_UPLOAD_FTP_HOSTS=""

# purge archives on remote hosts before uploading?
export BM_UPLOAD_FTP_PURGE="true"

# You can specify a time to live for archives uploaded with FTP
# This can let you use different ttl's locally and remotely
# By default, BM_ARCHIVE_TTL will be used.
export BM_UPLOAD_FTP_TTL=""

# destination for FTP uploads (overrides BM_UPLOAD_DESTINATION)
export BM_UPLOAD_FTP_DESTINATION=""

##############################################################
# The S3 method
#############################################################

# The Amazon S3 method requires that you secure an S3
# account. See http://aws.amazon.com

# The bucket to upload to. This bucket must be dedicated to backup-manager
export BM_UPLOAD_S3_DESTINATION=""

# the S3 access key provided to you
export BM_UPLOAD_S3_ACCESS_KEY=""

# the S3 secret key provided to you
export BM_UPLOAD_S3_SECRET_KEY=""

# purge archives on remote hosts before uploading?
export BM_UPLOAD_S3_PURGE="false"

##############################################################
# The RSYNC method
#############################################################

# Which directories should be backuped with rsync
export BM_UPLOAD_RSYNC_DIRECTORIES=""

# Destination for rsync uploads (overrides BM_UPLOAD_DESTINATION)
export BM_UPLOAD_RSYNC_DESTINATION=""

# The list of remote hosts, if you want to enable the upload
# system, just put some remote hosts here (fqdn or IPs)
# Leave it empty if you want to use the hosts that are defined in
# BM_UPLOAD_HOSTS
export BM_UPLOAD_RSYNC_HOSTS=""

# Do you want to dereference the files pointed by symlinks?
# enter true or false (true can lead to huge archives, be careful).
export BM_UPLOAD_RSYNC_DUMPSYMLINKS="false"

##############################################################
# Section "BURNING"
# - Automatic CDR/CDRW/DVDR burning
#############################################################

# the method of burning archives from the list :
# - DVD : burn archives on a DVD medium
# (that doesn't need formatting, like DVD+RW).
#
# - DVD-RW : blank the DVD medium and burn archives
# (recommanded for DVD-RW media).
#
# - CDRW : blank the CDRW and burn the whole
# ARCHIVES_REPOSITORY or only
# the generated archives.
#
# - CDR : burn the whole ARCHIVES_REPOSITORY or
# only the generated archives.
# - none : disable the burning system
#
# Note that if backup-manager is run from interactive prompt you
# will be asked to insert disc(s) when needed

export BM_BURNING_METHOD=""

# When the CD is burnt, it is possible to check every file's
# MD5 checksum to see if the CD is not corrupted.
export BM_BURNING_CHKMD5="false"

# The device to use for mounting the cdrom
export BM_BURNING_DEVICE=""

# You can force cdrecord to use a specific device
# Fill in the full path to the device to use or even
# e.g. BM_BURNING_DEVFORCED="/dev/cdrom"
# If none specified, the default cdrecord device will be used.
export BM_BURNING_DEVFORCED=""

# By default backup-manager will make Joliet media (using the mkisofs switches
# : "-R -J"). You can change these if you want to use non-Joliet disc images.
# Change this only if you know what you're doing. Refer to mkisofs(8) for
# details.
export BM_BURNING_ISO_FLAGS="-R -J"

# enter here the max size of your media
# (usal sizes are 4200 for DVD media and 700 or 800 for CDR media)
export BM_BURNING_MAXSIZE=""

##############################################################
# Advanced settings, use this with care.
#############################################################

# Every output made can be sent to syslog
# set this to "true" or "false"
export BM_LOGGER="true"

# Which level of messages do you want to log to syslog?
# possible values are : debug,info,warning,error
export BM_LOGGER_LEVEL="warning"

# You can choose which facility to use
export BM_LOGGER_FACILITY="user"

# Enter here some shell script.
# It will be executed before the first action of backup-manager.
export BM_PRE_BACKUP_COMMAND=""

# Enter here some shell script.
# It will be executed after the last action of backup-manager.
export BM_POST_BACKUP_COMMAND=""

En résumé, « backup-manager » fait un dump de toutes les partitions utiles dans le / et sauvegarde tout dans /home/backup, vu que sur le serveur d’origine le /home est dans une partition dédiée très grande. Par ailleurs, /home/backup est exclu des sauvegardes, ce qui est assez logique…

Une fois ce backup fait, nous obtenons une liste de fichiers dans /home/backup :

-rw-rw---- 1 root root 4383629 juin 18 12:09 "hostname"-all-mysql-databases.20140618.sql.bz2
-rw-rw---- 1 root root 4105324 juin 18 11:20 "hostname"-bin.20140618.master.tar.gz
-rw-rw---- 1 root root 53366682 juin 18 11:20 "hostname"-boot.20140618.master.tar.gz
-rw-rw---- 1 root root 63565 juin 18 11:20 "hostname"-build.20140618.master.tar.gz
-rw-rw---- 1 root root 19682804 juin 18 11:21 "hostname"-etc.20140618.master.tar.gz
-rw-rw---- 1 root root 31815793490 juin 18 11:48 "hostname"-home.20140618.master.tar.gz
-rw-rw---- 1 root root 42467600 juin 18 11:57 "hostname"-lib.20140618.master.tar.gz
-rw-rw---- 1 root root 1398251 juin 18 11:57 "hostname"-lib32.20140618.master.tar.gz
-rw-rw---- 1 root root 180 juin 18 11:57 "hostname"-lib64.20140618.master.tar.gz
-rw-rw---- 1 root root 138 juin 18 11:57 "hostname"-libnss3.so.20140618.master.tar.gz
-rw-rw---- 1 root root 130 juin 18 11:57 "hostname"-media.20140618.master.tar.gz
-rw-rw---- 1 root root 106 juin 18 11:57 "hostname"-mnt.20140618.master.tar.gz
-rw-rw---- 1 root root 106 juin 18 11:57 "hostname"-opt.20140618.master.tar.gz
-rw-rw---- 1 root root 1716628 juin 18 11:57 "hostname"-root.20140618.master.tar.gz
-rw-rw---- 1 root root 7147463 juin 18 11:57 "hostname"-sbin.20140618.master.tar.gz
-rw-rw---- 1 root root 114 juin 18 11:57 "hostname"-selinux.20140618.master.tar.gz
-rw-rw---- 1 root root 136 juin 18 11:57 "hostname"-srv.20140618.master.tar.gz
-rw-rw---- 1 root root 797271115 juin 18 12:00 "hostname"-usr.20140618.master.tar.gz
-rw-rw---- 1 root root 4550202775 juin 18 12:09 "hostname"-var.20140618.master.tar.gz

Nous récupérons ces fichiers sur l’hôte Hyper-V, via SFTP et Filezilla en l’occurence, puis nous commençons à construire la machine virtuelle.

Nous configurons la carte réseau de cette nouvelle VM pour qu’elle utilise une adresse MAC donnée par OVH, pour lui attribuer une adresse IP publique d’un bloc RIPE.

Pour des raisons de simplification, nous avons installé sur une VM un OS similaire à ce qu’on a sur le serveur dédié, en l’occurrence un Ubuntu 12.04 X64.
Nous l’avons installé avec les options les plus simples, aucun package via tasksel et tout dans une seule partition, par contre géré avec LVM contrairement au serveur dédié. Cette partition est faite pour avoir une taille nécessaire pour tout restaurer, mais est loin d’égaler la partition d’origine (100go vs 2to)…
En parallèle à l’installation de la VM, nous faisons un disque virtuel VHDX permettant de stocker, pour la VM, les fichiers de dump du serveur physique d’origine.
Une fois la VM installée, nous sauvegardons la liste des paquets installés sur cette VM, pour pouvoir les réappliquer une fois la restauration achevée et avoir un système plus propre (surtout pour le kernel installé, pour repartir sur un kernel standard et non plus le kernel OVH).
Pour sauvegarder la liste des applications, nous passons la commande :

dpkg --get-selections > installed-software.log

On met ensuite le fichier généré bien au chaud dans un coin.

Le VHDX contenant les dumps est ensuite attaché à la VM, une fois celle-ci arrêtée.

Nous redémarrons ensuite la VM via un live cd Ubuntu 12.04 Desktop (et non serveur utilisé pour l’installation minimale).
Une fois démarré, nous montons la partition LVM fraichement installée, via le tutoriel disponible ici.
Dans l’ordre, nous passons les commandes suivantes :

sudo -s
apt-get install lvm2
pvscan
vgscan
vgdisplay -v
lvgchange -a y "emplacement de la partition trouvé via le vgdisplay"
mkdir /media/root
mount "emplacement de la partition trouvé via le vgdisplay" /media/root

La partition LVM est alors disponible dans /media/root!

Une fois la partition montée, on peut envisager d’écraser les données dans ces partitions avec celles de la machine d’origine (un peu bourrin, d’où le fait d’installer le moins possible dans la nouvelle machine).

Par contre, il est très important de sauvegarder le fichier /etc/fstab de la VM avant de l’écraser!!! Sans quoi la VM ne sera plus bootable facilement! Après remplacement de la partition /etc, nous pourrons le remettre en place (il contient la configuration des montages LVM, les nouveaux UUID, etc.).

La partition contenant les dumps est montée, par exemple dans /media/dumps (en fait c’est le nom qu’on a donné lors du formattage du VHDX dans lequel on a stocké les dump.
Pour restaurer les dumps, on exécute la commande suivante, pour chacun des fichiers dump, à l’exclusion du fichier contenant le dump de la partition boot! (on garde la partition boot fraîchement installée, nous ne réutilisons pas les kernels custom d’OVH…).

La restauration passe par la commande :

sudo tar -xvpzf /media/dump/"dumps".tar.gz -C /media/root --numeric-owner

Cette commande est donc à faire pour chachun des dump sauf celui du /boot.

Après écrasement depuis les dumps, on remet le fichier /etc/fstab d’origine de la VM, pour qu’elle puisse retrouver ces petits, puis on tente un redémarrage.

Dans notre cas, le redémarrage a été un peu long. C’est normal puisque la partie réseau n’est pas encore correcte. Néanmoins après de longue minutes nous tombons sur l’écran d’ouverture de session! 🙂

Un peu de travail de nettoyage s’impose alors.

Dans un premier temps, nous corrigeons la configuration réseau, en modifiant le fichier /etc/network/interfaces :

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo eth0
iface lo inet loopback

#auto eth0
iface eth0 inet static
address « ip publique pour la vm »
netmask 255.255.255.255
broadcast « ip publique pour la vm »
post-up route add « passerelle de l’hôte Hyper-V » dev eth0
post-up route add default gw « passerelle de l’hôte Hyper-V »
post-down route del « passerelle de l’hôte Hyper-V » dev eth0
post-down route del default gw « passerelle de l’hôte Hyper-V »

pre-up iptables-restore < /etc/iptables.rules

On cherche ensuite toutes les références à l’ancien nom d’hôte de la machine dans /etc :

sudo find /etc -type f -exec fgrep -l "'ancien nom d'hôte>'" {} \;

Pour chacun des fichiers trouvés, si nécessaire, on le modifie pour mettre un nouveau nom d’hôte.

Enfin, on dépose sur la machine le fichier contenant la liste des applications, qu’on avait sauvegardé un peu avant, puis on restaure les paquets via la commande suivante :

sudo aptitude install $(cat installed-software.log | awk '{print $1}')

A ce moment, le dernier kernel standard officiel devrait être configuré, et après un petit

sudo apt-get dist-upgrade

la machine devrait être à jour et propre!

On redémarre la machine après cela. Avec un peu de chance, elle devrait démarrer correctement et ses services devraient être en ligne et disponibles sur la nouvelle adresse IP… 🙂

Sources :
Restauration de la liste des paquets
Montage des partitions LVM depuis un live cd Ubuntu
Restauration de fichiers depuis un tar


Publié

dans

par

Étiquettes :

Commentaires

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.