Limiter les IO

Soumis par jpp le mar 05/05/2020 - 15:21

La limitation des IO pose quelques problèmes pour les conteneurs non privilégiés, mais quelques pistes se dessinent.
Après pas mal de recherches et tests je me suis décidé à créer un conteneur MariaDB avec une limitation sur l'essentiel des caractéristiques soit les IO.

Ce container MariaDB/Mysql complétera le serveur Web de l'article précédent.
Le container est configuré avec 512M de mémoire et 768M (512M + 256M de swap) et un "disque" externe sous forme d'un répertoire contenant deux sous répertoires "data" et "binlog", le "error.log" restera dans le /var/log/mysql du conteneur. Il faut donc quelque peu corriger le fichier de configuration de MariaDB pour ne pas mettre les données dans /var/lib/mysql ou /var/log/mysql.
J'ai voulu utiliser le paramétrage "blkio.weight" mais celui-ci nécessite de disposer au niveau du système du scheduler d'IO CFQ qui n'est plus disponible dans les noyaux récents ???
De toutes les façons aucun fichier contenant "weight" n'est visible dans la hiérarchie des cgroups, vérification :

cd /sys/fs/cgroup
find ./ -name '*weight*'

ne ramène rien,
donc aucun "Cgroup" avec "weight" n'existe ...  Le paramètre "weight" (10 .. 1000) qui est censé définir la répartition entre les IO de différents conteneurs semble inutilisable.
Les seuls paramètres sur lesquels on peut agir sont ceux définissant la vitesse max autorisée :

. blkio.throttle.read_bps_device
. blkio.throttle.read_iops_device
. blkio.throttle.write_bps_device
. blkio.throttle.write_iops_device

On peut donc limiter les IO en IOPS ou en octets pas seconde, c'est déjà pas mal ... Mais quelle est la syntaxe exacte pour lxc ?
La syntaxe (évidente, si l'on a déjà pratiqué LXC) ne fonctionne malheureusement que pour les conteneurs privilégiés :

lxc.cgroup.blkio.throttle.read_bps_device = 8:0 50
8:0 car il s'agit pour moi du disque /dev/sda, on peut voir les valeurs avec :
ls -al /dev/sda
brw-rw---- 1 root disk 8, 0 mai    5 18:07 /dev/sda

J'ai trouvé ceci après un examen des logs de la commande "lxc-start" en mode "DEBUG" qui signale des "denied" depuis le programme "cgfsng.c". Pour autoriser les commandes "blkio.throttle...device" en mode non-privilégié il faut, encore, aller modifier le fichier /etc/pam.d/common-session et ajouter une autorisation. Cette ligne devient alors :
session optional pam_cgfs.so -c freezer,memory,cpu,cpuset,cpuacct,blkio,cgfsng,name=systemd
Et après avoir avoir fermé et ré-ouvert la session de mon utilisateur "testlxc" le conteneur démarre avec les limites suivantes :
# limiter IO
lxc.cgroup.blkio.throttle.read_bps_device = 8:0 50000
lxc.cgroup.blkio.throttle.write_iops_device = 8:0 50000 

et les bonnes valeurs sont inscrites dans les fichiers correspondants. 
Contrôle :

cd /sys/fs/cgroup/blkio/user/testlxc/0/lxc/debian-e
cat *device
8:0 50
8:0 50

La limite à 50000 est volontairement extrêmement faible pour voir une instance sérieusement ralentie.
C'est le cas,

  • à 50000 le démarrage et l'arrêt du conteneur sont très ralentis, des accès à la base MariaDB sont très poussifs voire interminables ...
  • Au delà de 500000 les choses s'améliorent très sérieusement, démarrage rapide, accès à la base MariaDB rapides ...

Il semble par ailleurs que la limitation soit effective sur les accès "physiques" au disque mais ne touche pas les accès à des données dans les caches. C'est visible en "droppant les caches" sur le système physique, un simple "ls -al" demande du temps la première fois mais est instantané par la suite.

En résumé la limitation joue au niveau des IO "physiques" mais ne bride pas le conteneur pour les accès depuis le cache ce qui garantit un certain niveau de performance tout en permettant de mieux maîtriser la concurrence entre conteneurs pour les accès physiques.