Kafe-in.net Blog/OpenVZ : Les ressources système dans un VE

Le noyau linux OpenVZ permet de se cloisonner en VE (Virtual Environment). Pour chaque VE créé, il attribue une certaine quantité de ressources système comme par exemple un nombre de processus maximum ou bien une certaine quantité de mémoire. Ces ressources sont appelées, en jargon « OpenVZique » les « bean counters », soit les « compteurs de haricots »…si quelqu’un connait l’origine de ce terme, je suis preneur. Il sont consultables dans le fichier /proc/user_beancounters autant sur le HN pour le détail de tous les VE que sur chaque VE pour ses valeurs propres.

Pour la dernière version d’OpenVZ disponible au moment de l’écriture de cet article, il y a une vingtaine de paramètres disponibles. Avant de créer un VE, il est donc important de bien comprendre le rôle de chacun de ses paramètres car, la plupart du temps, les problèmes liés à l’exécution d’un programme dans un VE est lié à une mauvaise quantification de ceux-ci.

Informations générales sur tous les paramètres

Valeurs des paramètres

Chaque paramètre contient 6 valeurs, certains sont modifiables, d’autres en lecture seule.

En voici le détail :

* resource : c’est le nom du paramètre.

* held : c’est la valeur en cours pour le paramètre, elle varie donc dans le temps. Cette valeur peut utilisée pour monitorer un VE.

* maxheld : c’est la valeur maximum que le paramètre a atteint depuis le démarrage du VE. Cette valeur ne peut être remise à zéro qu’en redémarrant le VE.

* barrier et limit : ces deux valeurs ont une utilité dépendante du paramètre associé. Elles peuvent parfois être considérées comme une limite soft et hard, ou bien comme une valeur limite indépassable, ou bien ne pas du tout être prises en compte.

* failcnt : c’est un compteur qui s’incrémente chaque fois que les barrier ou limit sont dépassées. Il est également dépendant du paramètre.

Unités des paramètres

Les paramètres peuvent avoir trois unités de mesure :

* En unité : cette unité est utilisée par tous les paramètres dont le nom commence par « num ». Comme par exemple « nomproc » qui correspond au nombre de processus.

* En page de mémoire (memory page) : cette unitée est utilisée par tous les paramètres dont le nom fini par « page ». Comme par exemple « vmguarpages » qui permet de contrôler la quantité de mémoire allouée aux applications lancées dans le VE. Une page de mémoire fait 4ko sur les architectures x86 et x86_64.

* En octets : cette unité est utilisée par tous les autres paramètres. Comme par exemple « tcpsndbuf » qui représente la taille du tampon utilisé pour l’envoi de données sur une connexion TCP.

Les types de paramètres

Chaque paramètre peut être d’un type parmi les suivants :

* limiting : le paramètre pose une limite sur les ressources système qu’un VE peut utiliser. Si cette limite est dépassée, le processus qui provoquera ce dépassement sera tué. A noter quand même que si le paramètre a une barrière (barrier) et une limite (limit), une fois la barrière atteinte, le processus ne sera tué que s’il n’est pas vital pour le VE. Par contre la limite est réellement une frontière à ne pas dépasser quelque soit le processus.

* guarantee : le paramètre défini une quantité de ressources garantie. C’est à dire que, peut importe les ressources systèmes du HN et utilisées par les autres VE, cette quantité sera utilisée pour ce VE quitte à prendre des ressources chez les autres.

* accounting : ce paramètre est en lecture seule et c’est juste un compteur pour une valeur particulière. Il peut donc être utilisé pour monitorer le VE.

Tableau récapitulatif des paramètres

Voilà un tableau récapitulatif de tous les paramètres, leur type, leurs valeurs possibles et leur unité.

Name Type Account Barrier Limit Units

Primary parameters

numproc limiting Yes No Yes pieces

numtcpsock limiting Yes No Yes pieces

numothersock limiting Yes No Yes pieces

vmguarpages guarantee No guarantee No pages

Secondary parameters

kmemsize limiting Yes Yes Yes bytes

tcpsndbuf limiting Yes Yes Yes bytes

tcprcvbuf limiting Yes Yes Yes bytes

othersockbuf limiting Yes Yes Yes bytes

dgramrcvbuf limiting Yes Yes Yes bytes

oomguarpages guarantee Yes guarantee No pages

privvmpages limiting Yes Yes Yes pages

Auxiliary parameters

lockedpages limiting Yes Yes Yes pages

shmpages limiting Yes No Yes pages

physpages accounting Yes No No pages

numfile limiting Yes No Yes pieces

numflock limiting Yes Yes Yes pieces

numpty limiting Yes No Yes pieces

numsiginfo limiting Yes No Yes pieces

dcachesize limiting Yes Yes Yes bytes

numiptent limiting Yes No Yes pieces

Détails des paramètres

Paramètres primaires

numproc

Le paramètre numroc représente le nombre de processus en cours dans le VE. Il est de type « limiting », c’est à dire que sa valeur « limit » impose un nombre maximum de processus exécutables dans le VE.

Beaucoup d’application du type apache ou courier-imap exécutent un processus pour chaque connexion ouverte ainsi qu’un certain nombre de processus « dormants ». Il faut donc prévoir cette limite avec parcimonie car si elle est dépassée, les nouveaux processus sont tués dés leur création…ce qui peut avoir des effets de bords graves.

A noter également qu’à partir de 16000 processus simultanés (même dormants), un système sous linux commence à voir ses performances se réduire significativement. Au delà de 32000 processus simultanés, il y a de grandes chances que le système plante.

numtcpsock

Ce paramètre permet de limiter le nom de connexion TCP simultanées dans un VE. Etant donné le réseau est géré de façon interne par chaque VE (que ce soit en mode VENET ou VETH), le paramètre numtcpsock n’a aucune influence sur le réseau du HN. Le nombre de connexions TCP doit être limité car chaque socket ouvert nécessite une certaine quantité de mémoire et la mémoire est une ressource limitée.

Une limite trop basse peut avoir comme effet le refus de nouvelles connexions sur un service. Par exemple un serveur apache hébergeant un site très visité peut facilement avoir plusieurs centaines de connexions concurrentes, la limite de numtcpsock devra donc être modifiée en conséquence.

numothersock

Ce paramètre agit exactement de la même façon que numtcpsock mais pour tous les autres types de sockets (UDP, local, etc.). Il influe donc sur les serveurs DNS qui utilisent des sockets UDP, ou bien sur les bases de données MySQL qui utilisent des sockets locaux.

vmguarpages

Ce paramètre permet de définir la quantité de mémoire garantie pour le VE. Il est lié au paramètre privvmpages (voir plus loin).

En clair, cela veut dire que :

* Si la quantité de mémoire utilisée par le VE est inférieure à la barrière de vmguarpage, alors un nouveau processus pourra s’exécuter sans problèmes.

* Si la quantité de mémoire utilisée par le VE est comprise entre la barrière de vmguarpage et la barrière de privvmpages, un nouveau processus pourra s’exécuter sans problème s’il reste de la mémoire disponible sur le HN.

* L’exécution de nouveau processus sera ensuite dépendant du paramètre privvmpages (voir plus loin).

Ce paramètre est donc le principal paramètre influant sur la mémoire d’un VE. Une valeur trop faible empêche directement l’exécution d’un VE et/ou des programmes s’exécutant à l’intérieur de celui-ci. Et une valeur trop importante diminuera la quantité de mémoire disponible pour le HN, ce qui peut conduire à un plantage du système. Dans tous les cas, la valeur de vmguarpages ne peut excéder la quantité de ressource système disponible sur le HN (RAM+SWAP).

Etant donné que vmguardpages n’a pas de limite, celle-ci doit être positionnée à la valeur maximum (MAX_ULONG), soit 2147483647 (232-1) pour une architecture 32 bits et 9223372036854775807 (264-1) pour une architecture 64 bits.

L’unité de vmguarpages est variable selon l’architecture matérielle. Pour du matériel x86 ou x86_64, c’est 4ko.

Paramètres secondaires

kmemsize

Ce paramètre est la quantité de mémoire « unswappable » disponible pour un VE en octets. C’est à dire la somme de la quantité de mémoire utilisée par le noyau pour gérer chaque processus sans compter les tampons réseau (voir plus loin).

Ce paramètre est donc lié au paramètre numproc. Chaque processus utilise une certaine quantité de mémoire noyau, au minimum 24ko, en moyenne autour de 50ko mais elle peut être bien supérieure.

Si la quantité de mémoire noyau utilisée pour les processus du VE est supérieure à la valeur barrière, alors seuls les processus prioritaires pourront utiliser cette mémoire. Si elle dépasse la valeur limite, alors les nouveaux processus ne pourront pas s’exécuter et cela risquera de provoquer un plantage du VE. Les valeurs limite et barrière sont limitées par les ressources disponibles sur le HN.

tcpsndbuf, tcprcvbuf et othersockbuf

Ces deux valeurs déterminent la taille de la mémoire tampon utilisée pour, respectivement, envoyer et recevoir des données sur le réseau via le protocole TCP.

Elles dépendent directement du paramètre numtcpsock pour tcpsndbuf et tcprcvbuf et de numothersock pour othersockbuf. Elles doivent donc être suffisamment importantes pour que chaque socket ait assez de mémoire tampon disponible. Pour valider ce point, il suffit de respecter cette simple règle :

tcpsndbuflim – tcpsndbufbar >= 2.5ko × numtcpsock

(idem pour tcprcvbuf et othersockbuf)

Si elle n’est pas respectée, les connexions entrantes, sortantes ou via socket local peuvent devenir instables.

dgramrcvbuf

Ce paramètre est la taille du tampon utilisée pour la réception de datagrammes UDP. Si la valeur courante (account) dépasse la valeur limite alors les datagrammes seront refusés à la réception.

Mais comme UDP est un protocole non connecté les applications l’utilisant sont conçues pour gérer les pertes de données en réception. C’est pourquoi la limite de dgramrcvbuf n’a pas forcément besoin d’être élevée. Toutefois une valeur trop faible entraînerait trop de pertes de données et ainsi provoquerait une dégradation de service. Et une valeur trop élevée n’a pas de plus-value et serait de la mémoire inutilisée.

oomguarpages

Ce paramètre est lié à vmguardpages. C’est la quantité de mémoire garantie dans le cas où le noyau linux entre en mode oom (Out Of Memory).

C’est à dire que si la somme des quantités de mémoire et swap utilisées par tous les VE plus la somme des kmemsize plus la somme des buffers est supérieure à la quantité de mémoire (RAM+SWAP) disponible sur le HN, alors le noyau linux entre en mode oom et commence à tuer les processus dans les VE. Les VE dont la valeur de oomguardpage dépasse le plus la valeur barrière verront leurs processus tués en priorité.

Si la valeur barrière de ce paramètre est inférieure à la valeur limite de privvmpages (voir plus loin), les chances que des processus soient tués dans ce VE sont réduites. Si elle est définie à la moitié de cette limite, les chances deviennent nulles.

La valeur courante (account) de ce paramètre est la quantité de mémoire (RAM+SWAP) utilisée par les processus du VE. Elle est donc utile pour monitorer le VE.

privvmpages

Ce paramètre permet de contrôler la quantité de mémoire allouée par VE pour les processus. Cette quantité n’est toutefois pas garantie et dépend des ressources systèmes disponibles sur le HN. La quantité de mémoire garantie est définie par vmguardpages (voir plus haut). La somme des valeurs courantes (account) de privvmpages pour toutes les VE peut donc dépasser la quantité de mémoire (RAM+SWAP) disponible sur le HN. De plus la quantité de mémoire réellement utilisée par un VE est comptée par oomguardpages (voir plus haut).

Si la quantité de mémoire utilisée par le VE dépasse la valeur barrière de privvmpages, alors seule les allocations de mémoire prioritaires seront autorisées par le noyau (celles pour les processus déjà en cours d’exécution). Si cette quantité dépasse la valeur limite alors plus aucune allocation de mémoire ne sera autorisée et cela pourra provoquer une instabilité du VE.

Paramètres auxiliaires

lockedpages

Ce paramètre défini la quantité de mémoire bloquée, c’est à dire qui n’est pas autorisée à être mise sur la SWAP. Son fonctionnement est similaire à privvmpages au niveau des valeurs limite et barrière (voir plus haut).

La plupart des applications type serveur web, ftp, ou mail n’utilisent pas ce type de mémoire.

shmpages

Ce paramètre permet de définir la quantité de mémoire partagée (SHared Memory), c’est à dire la mémoire utilisable par plusieurs processus simultanément. C’est une méthode parfois utilisée pour faire communiquer deux processus entre eux. Son fonctionnement est également similaire à privvmpages (voir plus haut).

physpages

Ce paramètre est en lecture seule, c’est à dire que seule la valeur courante (account) évolue dans le temps et que les autres valeurs (limit et barrier) ne sont pas modifiables.

Il permet de quantifier la mémoire utilisée uniquement par les processus dans un VE. Elle est donc utile pour monitorer un VE.

numfile

Ce paramètre permet de contrôler le nombre de fichiers ouverts simultanément. Il a été développé uniquement pour les développeurs. Réduire la valeur limite de ce paramètre peut influer sur la stabilité d’un VE.

numflock

Ce paramètre contrôle le nombre de « lock » sur les fichiers. Un nombre trop élevé de « lock » peut baisser les performances d’un VE, la valeur limite doit donc être positionnée raisonnablement en fonction des besoins réels des applications.

numpty

C’est le nombre maximum de shell ouverts sur un VE. Le nombre de shell ouverts n’affecte pas les performances ou la stabilité d’un VE, toutefois le nombre maximum autorisé pour la valeur limite par le noyau OpenVZ est de 256.

numsiginfo

Ce paramètre permet de limiter le nombre de signaux de type SIGINFO simultanés sur un VE.

Une valeur limite trop élevée peut réduire les performances d’un VE et/ou du HN.

dcachesize

C’est la taille de la mémoire tampon pour les opérations sur disque dur. Si elle est supérieure à la valeur limite, la stabilité ou la sécurité d’un VE ne sera pas réduite, toutefois la performance des opérations sur disque sera réduite pour le VE uniquement.

numiptent

Ce paramètre permet de limiter le nombre d’entrées possibles pour iptables (netfilter). Si la limite est dépassée il y aura des erreurs dans le traitement de paquets par netfilter.

Une valeur trop importante provoquera un ralentissement du système, il est conseillé de limiter ce paramètre à une valeur maximale d’environ 250 entrées.

Exemple de fichier /proc/user_beancounters

Un fichier /proc/user_beancounters est donc disponible sur chaque VE. Il y en a également un sur le HN, il permet de lister celui de chaque VE ainsi que la somme des valeurs account pour chaque paramètre.

VE# cat /proc/user_beancounters

22: kmemsize 1124493 3977600 14372700 14790164 0

lockedpages 0 0 256 256 0

privvmpages 12703 39415 65536 69632 0

shmpages 0 1936 21504 21504 0

dummy 0 0 0 0 0

numproc 9 25 240 240 0

physpages 2151 17745 0 9223372036854775807 0

vmguarpages 0 0 33792 9223372036854775807 0

oomguarpages 2151 17745 26112 9223372036854775807 0

numtcpsock 2 12 360 360 0

numflock 1 5 188 206 0

numpty 0 3 16 16 0

numsiginfo 0 3 256 256 0

tcpsndbuf 34880 1343936 1720320 2703360 0

tcprcvbuf 32768 1125248 1720320 2703360 0

othersockbuf 2312 40080 1126080 2097152 0

dgramrcvbuf 0 2576 262144 262144 0

numothersock 16 38 360 360 0

dcachesize 102351 210219 3409920 3624960 0

numfile 215 649 9312 9312 0

dummy 0 0 0 0 0

dummy 0 0 0 0 0

dummy 0 0 0 0 0

numiptent 24 25 128 128 0

viaKafe-in.net Blog/OpenVZ : Les ressources système dans un VE.