Mathieu GAILLARD

Performances CPU : Docker contre KVM

Dans la suite, je présente un rapport rédigé pour un projet spécifique de recherche. Les expériences ont été menées avec Luc Forget et encadrées par Mathieu Maranzana de l’équipe DRIM du LIRIS.

Introduction

Dans le cadre d’un projet spécifique de recherche au sein du département informatique de l’INSA de Lyon nous réalisons une comparaison des performances des conteneurs Linux et des machines virtuelles. Nous nous basons principalement sur l’article “An Updated Performance Comparison of Virtual Machines and Linux Containers”, écrit par une équipe d’IBM Research.

Les conteneurs et les machines virtuelles sont intensivement utilisés par les fournisseurs de Cloud. L’intérêt de ces solutions est de faciliter le déploiement d’applications tout en ayant un contrôle sur les ressources allouées à celles-ci. Cependant, le niveau d’abstraction introduit a un coût, et réduit les performances des applications conteneurisées ou virtualisées. Nous aimerions quantifier les pertes induites pour différents types de charges.

Dans la suite, nous comparons les performances de Docker, un gestionnaire de conteneurs, et KVM, un hyperviseur de type 1. Les tests sont principalement axés sur les performances CPU. Pour solliciter le processeur, nous effectuons une compression multi-thread d’un gros fichier à l’aide de PXZ.

L’intérêt de l’étude est de confirmer les résultats obtenus par IBM en 2014 en utilisant des technologies de 2016.

Protocole

Nous utilisons PXZ 4.999.9beta qui permet de compresser, avec plusieurs cœurs, des fichiers en utilisant l’algorithme LZMA. Notre fichier de test, enwik8, est une archive de Wikipédia tronquée pour peser 100 Mo. Ce fichier peut être retrouvé sur le site de Matt Mahoney.

Pour limiter les ralentissements dus aux accès disques, nous plaçons le fichier à compresser en ramdisk et nous redirigeons le résultat vers /dev/null. Nous utilisons le niveau de compression extrême.

Pour mesurer les temps d’exécution, nous utilisons l’outil /usr/bin/time de linux qui nous retourne le temps réel, user et système au centième de seconde.

Nous répétons le test 500 fois consécutives en enregistrant chaque fois les temps dans un fichier CSV.

Installation

Machine de test

Pour réaliser nos tests, la direction des systèmes d’information de l’INSA nous a prêté la machine la plus puissante qu’elle a trouvée. Elle est équipée d’un Core 2 Quad Q8400, comportant quatre cœurs cadencés à 2.66 GHz et une mémoire cache de 4 Mo. Nous avons aussi 8 Go de RAM DDR2 667 MHz. Nous sommes bien en 2016 !

Nous avons choisi d’installer la distribution Arch Linux, qui est très légère, pour avoir un contrôle plus fin sur les processus s’exécutant sur la machine. Nous limitons ainsi les perturbations dues aux programmes inutiles. De plus, Arch Linux est équipé d’un noyau récent : 4.5.1-1-ARCH. Puisque KVM est intégré au noyau, nous avons donc une version récente de cet hyperviseur.

Pour faciliter l’administration, nous installons un serveur SSH et l’environnement graphique LXDE accompagné du gestionnaire de connexion XDM. Evidemment, l’environnement graphique est éteint lors des tests de performance.

Voici les commandes utilisées pour préparer un environnement de test.

#Récupération du fichier enwik8.
wget http://mattmahoney.net/dc/enwik8.zip
unzip enwik8.zip
rm enwik8.zip

#Préparation du ramdisk.
mkdir ramdisk
#Initialisation du ramdisk, à executer en tant que root.
mount -t tmpfs -o size=128M tmpfs ramdisk

#Copie du fichier enwik8 dans le ramdisk.
cp enwik8 ramdisk

#Réalisation d’un test sur 4 threads.
/usr/bin/time -p pxz -zkcef -T 4 ramdisk/enwik8 > /dev/null

Natif

Pour effectuer les tests sur la machine native, nous n’installons rien de plus.

Docker

Pour installer Docker sur notre distribution, nous utilisons le gestionnaire de paquets.

#Installation de Docker
sudo pacman -S docker

#Lancement de Docker
sudo systemctl start docker

KVM

Le module KVM étant une fonctionnalité intégrée au noyau linux, nous n’avons pas besoin de l’installer. Cependant nous devons installer d’autres applications pour le faire fonctionner. Nous utilisons :

QEMU 2.5.0

Un émulateur qui peut être accéléré par KVM.

virt-manager

Un gestionnaire de machines virtuelles qui permet d’installer et d’utiliser facilement des machines virtuelles.

libvirt 1.3.2

Une librairie facilitant la gestion de machines virtuelles.

Comme système invité, nous utilisons une distribution Arch Linux doté du noyau 4.5.1-1-ARCH sans interface graphique à laquelle nous allouons 4 vCPU et 4 Go de RAM. Nous installons aussi un serveur SSH pour pouvoir piloter les tests en ligne de commande à distance. L’image disque est au format raw.

Résultats

Pour chaque configuration, nous mesurons la moyenne et l’écart-type des 500 tests réalisés.

    Natif (Arch kernel 4.5.1) Docker (Arch) KVM (Arch kernel 4.5.1)
Réel Moyenne (s) 31.46 31.54 31.42
  Ecart-type (s) 0.05 0.05 0.10
User Moyenne (s) 124.69 124.88 124.01
  Ecart-type (s) 0.13 0.14 0.31
System Moyenne (s) 0.33 0.35 0.54
  Ecart-type (s) 0.03 0.03 0.11

Pour la comparaison, nous nous baserons sur le temps réel puisqu’il correspond au temps réellement passé par la machine pour effectuer le test.

Les variances étant très petites et le nombre de tests grand, la comparaison directe des moyennes est donc significative.

Pour avoir une idée de la perte de performance quel que soit la taille du fichier, nous calculons le débit de compression du fichier en Mo/s. Donc nous divisons les 100 Mo du fichier par le temps de compression en seconde.

  Moyenne (Mo/s) Ecart au natif Ecart au natif (IBM)
Natif (Arch kernel 4.5.1) 3.18 0.00 % 0 %
Docker (Arch) 3.17 0.23 % 4 %
KVM (Arch kernel 4.5.1) 3.18 -0.15 % 18 %

Ces résultats ne correspondent pas aux chiffres obtenus par l’équipe d’IBM Research. Nous pensons que les nouvelles versions des logiciels permettent d’améliorer les performances des systèmes invités lorsqu’il s’agit d’une charge CPU.

Statistiquement, on peut conclure que la machine native est plus rapide que le conteneur. On pourrait aussi conclure que la machine virtuelle est plus rapide que la machine native. Evidemment ça semble improbable, les mesures doivent être affectées par un facteur que nous ne connaissons pas. Quoi qu’il en soit, pour une différence de quelques centièmes sur un temps total d’environ 31 secondes, on peut en conclure que les trois plateformes sont aussi rapides.

Discussion

Il faudrait réfléchir à un benchmark dont on peut plus facilement isoler les types de charges CPU. Il existe des suites de tests dédiées à cela comme unixbench et sysbench qui permettent de tester spécifiquement les performances des appels systèmes, des calculs en double précisions etc…

Les chercheurs d’IBM pensent que la compression pourrait être plus rapide en utilisant des pages mémoires plus grandes. En effet, le fichier que nous compressons pèse 100 Mo. Etant donné qu’il est caché en ramdisk, il est réparti entre plusieurs pages mémoires. Lors d’un TLB miss de l’hyperviseur, celui-ci devra donc faire une recherche dans la table des pages. Le coût engendré par ces recherches peut expliquer un overhead introduit par l’hyperviseur. Nous devrions mettre en place des pages mémoires plus grandes et reconduire les tests.

L’article d’IBM explique qu’il est possible d’optimiser les performances de KVM sur un système NUMA (Non Uniform Memory Access) en affectant les vCPU à des cœurs physiques. Notre machine n’est pas NUMA puisqu’elle est dotée seulement d’un processeur. Nous obtenons donc des résultats qui se rapportent à la configuration optimisée d’IBM.

Notre plateforme n’est pas récente. Le core 2 quad Q8400 a été lancé en 2009. Il est possible qu’au fil des générations de processeurs le jeu d’instruction VT-x ait été optimisé. Nous n’avons pas non plus l’extension EPT (Extended Page Tables) du jeu d’instruction VT-x qui a une incidence sur les applications virtualisées qui sollicitent fortement la mémoire. Les jeux d’instructions de virtualisation ne sont pas les mêmes chez AMD que chez Intel. Nous devrions tester une plateforme AMD pour comparer les performances. Nous avons testé une architecture x86_64, mais d’autres architectures ont un support matériel de la virtualisation, par exemple POWER8 d’IBM ou bien ARMv7. Pour apporter une réponse plus exhaustive aux tests de performance CPU dans le cas des machines virtuelles nous devrions tester d’autres plateformes.

Conclusion

Sur une distribution Arch Linux dotée du noyau 4.5, avec une installation de base de Docker et de KVM, sans optimisations particulières, lors d’une compression sur plusieurs cœurs, nous n’obtenons pas de différence significative entre les performances de la machine native, Docker et KVM.

Pour en savoir plus