Hier nous avons ajouté de la mémoire sur 5 hyperviseurs de la plateforme Galactica. Cette opération n'est pas exceptionnelle en soi ; ce qui est plus original c'est que cette manipulation s'est déroulée sans interruption de service. Ce post explique (succintement) comment cela est possible.
Comment avons-nous procédé ? La procédure est assez simple : nous avons migré toutes les VM d'un hyperviseur afin de le vider complètement, éteint la machine, sorti le serveur de la baie,
afin de remplacer ses barettes mémoire :
Petit rappel
Nous utilisons OpenStack pour gérer cet ensemble d'hyperviseurs, qui lui même se base sur le couple qemu-kvm et libvirt pour la gestion de la virtualisation. Le stockage est quant à lui géré par Ceph.
Le point important ici est que physiquement, les hyperviseurs ne portent pas les disques virtuels des instances, le kernel des hyperviseurs monte les disques via la librairie RBD et présente à kvm de manière (presque) transparente un disque distant. Voici le schéma du principe :
Lors d'une migration il n'y a donc aucun déplacement du disque de la VM au sein du stockage. Mais si la VM est en cours de fonctionnement, il faut pouvoir assurer la cohérence du processeur et de la mémoire qui est en cours d'utilisation entre les deux hyperviseurs. C'est là que réside le principal challenge.
Etapes de migration
Voici les principales étapes [1] :
- Réservations des ressources
L'hyperviseur B réserve les ressources de la VM : quantité de mémoire nécessaire, fichier libvirt.xml etc.
- Pre-copy
Et c'est là qu'intervient libvirt. Le démon libvirt de l'hyperviseur A ouvre une connection TCP vers le démon libvirt de l'hyperviseur B, et lui transmet le contenu de la mémoire utilisée par la VM.
- Stop and copy
La VM d'origine est mise en pause, les pages mémoires qui ont été modifiées depuis la première copie sont transmises ainsi que l'état courant du processeur (avec le contenu des registres...etc). La pause dure au maximum 500ms, si le temps imparti est dépassé alors le processus s'interrompt, la VM est réactivée et la migration est déclarée échouée.
- Commitment
La VM destination est désormais en cours de fonctionnement, le composant réseau d'OpenStack met à jour la topologie réseau afin de finaliser le déménagement. En effet l'adresse MAC relative à la VM est désormais annoncée à partir de l'hyperviseur B à la fin du processus.
- Clean up
La VM d'origine est supprimée.
Conclusion
Voilà comment les VM peuvent se déplacer dans un cluster d'hyperviseur. Les mécanismes mis en jeu sont intéressants et permettent une grande souplesse d'exploitation.
D'ailleurs, fort heureusement, toutes ces étapes sont réalisées automatiquement par OpenStack. Avec un simple clic de souris :)
Référence
[1] Live Migration of Virtual Machines, Christopher Clark, Keir Fraser, Steven Hand, Jacob Gorm Hansen†, Eric Jul†, Christian Limpach, Ian Pratt, Andrew Warfield http://www.cl.cam.ac.uk/research/srg/netos/papers/2005-migration-nsdi-pre.pdf