Implémenter des quotas d’IO disque pour des machines virtuelles

Une des caractéristiques essentielles d’une infrastructure de cloud est, d’un point de vue du fournisseur de service, la mutualisation des ressources matérielles pour servir plusieurs clients. Ces ressources n’étant pas illimitées, il faut s’assurer qu’elles soient correctement partagées pour assurer les différents niveaux de service envisagés.
Les trois grands types de ressources matérielles à partager sont le CPU, la RAM et les IO (disque et réseau). Pour le CPU, la multiplication des cœurs de processeurs ces dernières années a rendu possible l’affectation de manière dédiée d’un ou plusieurs cœurs à une machine virtuelle. Pour la RAM, il est risqué d’affecter aux VM allumées plus de mémoire que la capacité des serveurs physiques sous-jacents, donc il n’est pas recommandé de faire, au-delà de quelques pourcents du « partage de RAM ». Reste les IO, pour lesquels la mise en place de quota est la solution la plus adaptée. La suite de cet article s’intéresse à la mise en place de quota d’IO disque pour des machines virtuelles.

Présentation de 2 solutions pour faire respecter un quota d’IO disques

Il existe 2 solutions possibles qui répondent aux besoins mais avec des cas d’utilisation différents. La première est générique et marche pour la plupart des hyperviseurs du monde libre (Xen, KVM, LXC,…). Elle se base sur une technologie Linux nommé « control groups (cgroups) ». La seconde est spécifique à l’hyperviseur KVM (qemu). A noter qu’avec les 2 solutions, la valeur des quotas peut être fixée ou modifiée à chaud, lorsque la VM est en exécution.

CGroups

Les cgroups est une technologie du noyau Linux qui permet de mesurer, limiter et prioriser l’accès aux ressources système (CPU, RAM, IO disque) d’un groupe de processus. Dans notre cas, l’implémentation d’un quota sur les IO disques d’une VM consiste à :

  1.  Identifier les processus (par leur PID), sur la machine hôte, qui « représentent » l’exécution de la VM (processus dont le nom commence par qemu ou kvm) ou qui sont responsables des IO disques (blktap ou blkback pour Xen)
  2. Identifier le périphérique en mode bloc (« block device »), sur la machine hôte, utilisé par la VM. Si le support du disque virtuel de la VM est un fichier (format « raw », « qcow », « VHD »), les cgroups ne marcheront pas.
  3. Appliquer le quota. Cela consiste à écrire dans un fichier du point de montage du système de fichiers utilisé par les cgroups. Par exemple le fichier blkio.throttle.read_bps_device contrôle la bande passante en lecture tandis que le fichier blkio.throttle.write_iops_device contrôle le nombre d’IOPS en écriture.

Les quotas sont alors directement appliqués par le noyau Linux.

QEMU native IO throttling

L’alternative aux cgroups est d’utiliser la fonctionnalité de « IO throttling » proposée nativement par Qemu/KVM dans les versions récentes de l’hyperviseur. L’implémentation est plus simple d’autant que les versions récentes de Libvirt exposent cette fonctionnalité directement avec le XML « qui va bien ». Deux mises en place des quotas sont possibles :

  • Au démarrage de la VM, en utilisant Libvirt ou en passant les arguments « [[,bps=b]|[[,bps_rd=r][,bps_wr=w]]][[,iops=i]|[[,iops_rd=r][,iops_wr=w]] » (cf « kvm –help ») directement à l’exécutable Qemu/KVM.
  • A chaud lorsque la VM est allumée, en utilisant la commande « block_set_io_throttle » du « qemu monitor ».

Les quotas sont appliqués en espace utilisateur par Qemu/KVM.

Dans le monde propriétaire

HyperV de Microsoft et VSphere de VMWare sont 2 hyperviseurs du monde propriétaire largement reconnus. Ils n’offrent pas une fonctionnalité strictement équivalente puisqu’ils ne permettent pas de fixer de « limite forte » sur le débit ou les IOPS par VM (mais, en lieu, implémentent des « classes de service » ou essayent d’assurer une forte équité/« fairness » entre les VM).

Comparaison des performances des solutions

Dans cette section, nous comparons l’efficacité de l’implémentation des quotas avec les cgroups ou la fonctionnalité native de Qemu. Pour cela, une limite en terme de bande passante est fixée pour une VM et une commande engendrant une forte activité disque est exécutée à l’intérieure de la VM. La bande passante disque et la consommation CPU sont mesurées coté serveur hôte (hyperviseur).

(Test réalisés avec Linux 3.5, libvirt 0.9.13, KVM 1.2 et l’option KVM cache=none. Débit séquentiel généré avec l’utilitaire « dd », blocksize à 1M et option oflag=sync)

Comme on le constate sur les graphiques, les 2 solutions remplissent globalement correctement leur tâche. La moyenne des débits sur les milliers d’écritures ou lectures disques observées (après un temps de « préchauffe ») s’éloigne au maximum de 10% de la valeur de consigne. En revanche, à bas débit, les « débits instantanés » sont très fluctuants dans le cas de Qemu/KVM. En pratique avec KVM, en cas de quota très restrictif, j’ai observé que la VM pouvait se retrouver à court d’IO (« IO starvation ») pendant plusieurs secondes entrainant un freeze complet de la VM.

La consommation CPU (user et system time) est identique pour les 2 solutions.

En conclusion, l’implémentation par CGroups parait plus robuste puisqu’elle donne des débits plus stables.

Autres points différenciant

Comme vu précédemment, les CGroups ne sont utilisables que si la VM utilise directement un « block device » comme support de stockage. C’est le cas si le stockage des VMs se repose sur LVM, iSCSI ou Fibre Channel.

Avec l’ « IO throttling » de KVM il n’est pas possible de fixer en même temps un quota d’IOPS et de bande passante.

Conclusion

Longtemps oubliée, l’implémentation de quotas sur les IO semble indispensable pour tout fournisseur d’IaaS puisqu’elle permet le dimensionnement de la partie stockage du cloud et ajoute un nouvel axe de tarification. Amazon Web Services l’a bien compris puisque la société semble mettre en avant ses volumes de stockage avec « Provisioned IOPS ». Dans cet article, nous avons vu comment faire respecter de tels quotas avec 2 solutions dont le choix dépendra d’abord de l’hyperviseur utilisé puis du mode de stockage (SAN ou NAS). Si les 2 solutions sont possibles, on choisira la solution avec cgroups qui semble plus aboutie et bénéficie du support de toute la communauté du noyau Linux.