CPU steal sur VPS : repérer un voisin bruyant
Comprenez le CPU steal d’un VPS, lisez la colonne st de vmstat et distinguez un voisin bruyant d’une surcharge de vos propres processus.
Ce que mesure réellement le temps CPU steal
Le temps CPU steal correspond à la part du temps pendant laquelle votre CPU virtuel était prêt à s’exécuter, sans rien attendre, mais où l’hyperviseur attribuait le cœur physique à une autre machine virtuelle. Le travail était en attente dans la file. Le cœur était utilisé ailleurs. Linux comptabilise ces cycles séparément et les signale sous st. Vous pouvez ainsi distinguer « mon serveur est occupé » de « mon serveur attend son tour ».
C’est précisément la raison d’être de ce compteur. Le temps que vos propres processus passent sur le CPU est comptabilisé sous us (user) ou sy (system). Le temps pendant lequel une tâche reste bloquée sur le stockage est comptabilisé sous wa (I/O wait). Un vCPU (CPU virtuel) prêt à s’exécuter, présent dans la run queue, sans opération d’I/O en attente et qui ne s’exécute toujours pas, est comptabilisé sous st. Rien dans votre serveur ne peut mettre fin à cet état, car la décision d’ordonnancement est prise un niveau en dessous, sur l’hôte.
Cela découle directement de la manière dont un VPS partage une même machine physique entre plusieurs machines virtuelles. La cause habituelle est un voisin : une autre machine virtuelle du même nœud utilise fortement le CPU, et l’hôte répartit les cœurs entre vous. Une seconde cause est souvent oubliée. De nombreux fournisseurs plafonnent un vCPU partagé à une fraction d’un cœur physique. Sur plusieurs hyperviseurs, ce plafond appliqué est comptabilisé comme du steal dans la machine virtuelle. Une valeur st élevée indique donc que le cœur ne vous a pas été attribué. Elle n’indique pas toujours qui l’utilisait.
Origine de la valeur steal
Votre kernel ne peut pas mesurer le steal seul, car il ne voit pas l’hôte. C’est l’hyperviseur qui lui transmet cette information. Avec KVM, l’hôte écrit un compteur par vCPU dans une page partagée avec le guest, puis le guest additionne ces valeurs lorsque le kernel est compilé avec CONFIG_PARAVIRT_TIME_ACCOUNTING, ce qui est le cas de tous les kernels des distributions. Xen fournit la même information via sa zone runstate. Le total arrive dans l’espace utilisateur à un seul endroit :
head -1 /proc/statLa ligne cpu contient dix compteurs, exprimés en ticks USER_HZ depuis le démarrage, dans cet ordre : user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice. Steal est la huitième valeur après le libellé. Tous les outils ci-dessous, vmstat, top, mpstat et les exporters Prometheus, lisent ce même champ et convertissent deux échantillons en pourcentage.
Une conséquence est plus importante que les autres. Si l’hyperviseur n’exporte jamais le compteur, le champ reste à zéro indéfiniment. Tous les outils qui l’utilisent signalent alors un 0.0 calme alors que l’hôte est surchargé. KVM et Xen exportent ce compteur. Les guests sur VMware et Hyper-V signalent souvent une valeur constamment nulle. Vérifiez la plateforme avant de faire confiance à un zéro :
systemd-detect-virtCette commande affiche le nom de la plateforme, par exemple kvm, xen, vmware ou microsoft, et none sur une machine physique. Dans un conteneur, elle indique plutôt le runtime, par exemple lxc, docker ou podman. Cela renseigne sur le conteneur, pas sur la machine sous-jacente. Sur kvm, un zéro prouve réellement que l’hôte vous fournit suffisamment de ressources. Sur une plateforme qui ne renseigne jamais ce champ, un zéro ne prouve rien. Il faut alors évaluer la contention en mesurant le temps d’exécution de tâches réelles.
Comment vérifier le temps de vol CPU sur un VPS ?
vmstat provient du paquet procps. Il est présent dans presque toutes les images VPS Ubuntu et Debian. Il manque dans certaines images de conteneur minimales. Installez-le avant d’en dépendre.
sudo apt-get update
sudo apt-get install -y procps
vmstat --version
vmstat 1 5vmstat --version affiche une ligne telle que vmstat from procps-ng 4.0.4. Si cette ligne s’affiche, l’outil est installé et vous lisez de vrais compteurs du noyau. vmstat 1 5 effectue ensuite un échantillonnage par seconde, cinq fois.
procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
r b swpd free buff cache si so bi bo in cs us sy id wa st gu
1 0 0 3216484 98304 1284360 0 0 4 18 62 110 3 1 96 0 0 0
2 0 0 3216232 98304 1284360 0 0 0 0 248 431 6 2 84 0 8 0Repérez la colonne st dans le bloc cpu à droite. Les versions actuelles de procps-ng affichent une colonne gu après celle-ci pour le temps d’exécution d’un invité KVM. st est donc l’avant-dernière colonne et non la dernière. Identifiez la colonne par son en-tête, car sa position a changé entre les versions.
Deux habitudes permettent de garder une lecture fiable. La première ligne de données correspond à la moyenne depuis le démarrage. Ignorez-la et lisez les lignes suivantes. Un seul échantillon ne constitue pas une mesure, car le steal survient par rafales. Exécutez vmstat 1 60 et surveillez une minute complète avant de tirer une conclusion.
top indique le même nombre sur sa ligne récapitulative %Cpu(s), dans le champ marqué st :
%Cpu(s): 6.2 us, 2.1 sy, 0.0 ni, 83.9 id, 0.0 wa, 0.0 hi, 0.3 si, 7.5 stPour obtenir le détail par cœur, ajoutez sysstat :
sudo apt-get install -y sysstat
mpstat -P ALL 1 5mpstat affiche une ligne par CPU avec une colonne %steal. Elle indique si tous les vCPU sont concernés ou si un seul l’est. Pour conserver l’historique nécessaire à un ticket auprès du support, enregistrez les échantillons au lieu de les lire à l’écran :
date -u | tee -a ~/steal.log
mpstat -P ALL 1 5 | tee -a ~/steal.logExécutez cette commande depuis cron pendant les heures où vous soupçonnez le problème. Le fichier permet alors de passer de « c’était lent hier soir » à la présentation au fournisseur des dix minutes concernées, avec les valeurs exactes.
Que signifient les valeurs de steal ?
- Un
0.0stable. Le système est sain, ou la plateforme ne signale pas du tout le steal. Vérifiez avecsystemd-detect-virtavant de conclure. - Des pointes de quelques pour cent pendant quelques secondes. C’est normal sur tout nœud partagé. Une compilation démarre chez un voisin, ou l’hôte exécute ses sauvegardes.
- De 1 à 5 % de manière continue sur une offre mutualisée. C’est attendu. Le prix reflète l’utilisation d’un processeur partagé.
- De 5 à 10 % de manière continue. Le ralentissement est mesurable. Commencez à recueillir des éléments et comparez les mêmes heures sur plusieurs jours.
- Plus de 10 % pendant plusieurs heures. Le nœud est surabonné pour votre charge de travail. C’est le niveau qui justifie l’ouverture d’un ticket auprès du support ou une migration.
Considérez ces fourchettes comme un guide d’interprétation, et non comme une spécification, car aucun fournisseur ne garantit un niveau de steal sur une offre mutualisée. Mettez-les en regard de ce que vous exécutez. Un traitement batch nocturne peut absorber 15 % de steal sans que personne ne le remarque. Un service sensible à la latence le fait apparaître dans le p99 bien avant que la moyenne ne devienne alarmante. C’est pourquoi les charges sensibles à la latence, comme les robots de trading doivent fonctionner sur des cœurs dédiés.
Quel est le coût du steal time pour vous ?
Le calcul est simple. Si une fraction s de votre temps CPU est accaparée, une tâche qui nécessite une quantité fixe de CPU prend 1 / (1 - s) fois plus longtemps en temps réel. Pour une tâche nécessitant 60 secondes de CPU :
The data behind this chart
[
{
"steal_percent": 0,
"wall_clock_seconds": "60.0"
},
{
"steal_percent": 3,
"wall_clock_seconds": "61.9"
},
{
"steal_percent": 8,
"wall_clock_seconds": "65.2"
},
{
"steal_percent": 15,
"wall_clock_seconds": "70.6"
},
{
"steal_percent": 25,
"wall_clock_seconds": "80.0"
},
{
"steal_percent": 40,
"wall_clock_seconds": "100.0"
}
]À 3 %, selon une valeur courante sur une offre mutualisée, cette tâche prend 61.9 secondes au lieu de 60.0. Personne n’ouvre un ticket pour cela. À 8 %, elle prend 65.2 secondes. À 40 %, la même tâche nécessite 100.0 secondes, et une file qui se vidait commence alors à s’allonger.
Il s’agit de valeurs calculées, et non de mesures. Le modèle suppose un thread exécutable unique et un steal réparti uniformément sur l’intervalle. Les services réels semblent souvent plus lents que ne le suggère la courbe, car une tranche de temps accaparée peut interrompre une requête et le délai est alors subi à nouveau par tous les traitements qui attendent cette requête. Pour obtenir votre propre valeur plutôt qu’une formule, évaluez les performances du VPS pendant une période creuse, puis de nouveau pendant une période chargée, en enregistrant st pour les deux périodes.
Est-ce du steal, ou autre chose ?
Le steal est facile à confondre avec d’autres symptômes. Lisez les compteurs ensemble, sur la même ligne vmstat.
stélevé, tandis queretusrestent faibles : l’hôte ne vous attribue pas le vCPU. C’est du steal.rnettement supérieur au nombre de vCPU, avecusélevé etstproche de zéro : vous exécutez plus de tâches que vos propres processeurs ne peuvent en traiter. Comparezravec la sortie denproc. Il s’agit de votre propre oversubscription, pas de celle d’un voisin.waélevé avecstproche de zéro : les tâches sont bloquées sur le stockage. Il s’agit d’un autre problème, qui nécessite une autre correction.- Load average élevé alors que
stetussont tous les deux faibles : la charge inclut également les tâches non interruptibles. Cela indique généralement un périphérique bloqué ou un montage réseau qui ne répond plus, plutôt qu’un problème de CPU.
Les offres burstable méritent une remarque spécifique. Elles vous accordent un solde de crédits qui augmente lorsque la charge est faible et diminue lorsque vous êtes actif. Lorsqu’il est épuisé, le fournisseur vous limite à un débit de base. Sur certaines plateformes, cette limitation est indiquée comme du steal. Sur d’autres, elle est invisible depuis la machine, qui reçoit simplement moins de cycles par seconde. Lisez la description de l’offre avant d’accuser un voisin.
Pourquoi un conteneur n’indique aucun temps volé
Le temps volé est une propriété de la machine virtuelle, pas d’un conteneur qui s’exécute à l’intérieur. Un conteneur Docker sur votre propre VPS partage le /proc de l’hôte. La valeur st lue à l’intérieur correspond donc au temps volé du VPS, ce qui est le résultat recherché. La virtualisation basée sur des conteneurs et vendue comme un VPS fonctionne différemment. Avec lxcfs en place, /proc/stat à l’intérieur du conteneur est calculé à partir des statistiques des cgroups, et le temps volé vaut zéro par construction. Une stack de monitoring qui collecte les métriques uniquement depuis l’intérieur peut afficher un zéro parfaitement stable alors que la machine physique sous-jacente manque de ressources.
Dans un conteneur, le compteur qui a la même signification est la limitation du CPU par quota. Avec cgroup v2 :
cat /sys/fs/cgroup/cpu.statnr_throttled compte les périodes d’application pendant lesquelles le groupe a atteint son quota CPU, et throttled_usec totalise le temps pendant lequel il a été suspendu. Une valeur nr_throttled en hausse signifie que votre processus était exécutable mais ne s’exécutait pas. L’expérience est la même qu’avec du temps volé, mais la cause est une limite que vous avez définie vous-même. Vérifiez vos propres limites avant d’accuser l’hôte, en particulier si vous exécutez vos services dans Docker sur un VPS avec des limites CPU dans le fichier compose. La virtualisation imbriquée ajoute un autre endroit où du temps peut disparaître, car une VM exécutée dans votre VPS subit le temps volé du VPS ainsi que son propre délai d’ordonnancement. Gardez ce point à l’esprit si vous utilisez la virtualisation imbriquée sur un VPS.
Que faire face à un steal durable
Aucun réglage dans le guest ne corrige le steal, car le scheduler qui prend la décision s’exécute en dehors du guest. Une mise à niveau du kernel ne change rien non plus : le scheduling tenant compte du cache ajouté dans le kernel Linux 7.2 réorganise vos tâches entre les cores qui vous ont réellement été attribués, mais ne peut pas récupérer les cycles déjà pris par un voisin. Quatre mesures sont réellement possibles.
Commencez par collecter des éléments. Notez les horodatages en UTC, la durée de chaque épisode, sa fréquence et indiquez si mpstat montre qu’un seul vCPU est affecté ou qu’ils le sont tous. Une semaine d’échantillons consignés vaut mieux qu’une capture d’écran.
Ouvrez un ticket avec ces données. Posez deux questions directes : ce node est-il surchargé pendant ces périodes, et mon instance peut-elle être déplacée ? Ajoutez la sortie de vmstat ainsi que les heures exactes. Les providers interviennent lorsqu’une période reproductible est indiquée. Un ticket qui dit seulement que le serveur est lent reçoit une demande de précisions. La quantité de ce travail que vous pouvez déléguer est l’une des différences pratiques entre un VPS managé et un VPS non managé.
Demandez une migration. Déplacer un guest vers un node moins chargé est une opération courante pour un provider et nécessite généralement un bref redémarrage. Cette correction ne coûte rien. Elle résout le cas le plus fréquent : un node héberge par hasard plusieurs voisins lourds au même moment.
Évitez la contention en changeant d’offre. Une offre avec vCPU dédié réserve des cores physiques pour votre instance. Le compteur reste donc à zéro. Cette solution coûte plus cher chaque mois. C’est la réponse adaptée à une charge qui ne peut pas absorber cette variabilité. Si cela ne suffit toujours pas, ou si vous voulez également disposer de toute la bande passante mémoire, l’étape suivante est un serveur dédié plutôt qu’un VPS.
En attendant, réduisez l’impact du steal. Exécutez moins de worker threads que vous n’avez de vCPU, car les threads qui ne peuvent pas obtenir de core ne font qu’ajouter des changements de contexte. Déplacez les traitements batch aux heures où le node est peu chargé, comme vous l’indique maintenant votre propre journal. Mesurez ensuite à nouveau avec la même commande et pendant les mêmes heures. Vous pourrez ainsi déterminer si la modification a fonctionné au lieu de vous baser sur des suppositions.
FAQ
Quel est un temps de vol CPU normal sur un VPS ?
Sur une offre mutualisée, de brèves pointes et une valeur durable inférieure à environ 5 pour cent sont normales, car le CPU mutualisé signifie que l’hôte répartit les cœurs physiques entre les guests. Une valeur durable à deux chiffres pendant plusieurs heures n’est pas normale et justifie l’ouverture d’un ticket. Sur une offre avec vCPU dédié, la valeur attendue est 0.0 ; toute autre valeur doit être signalée. Évaluez cette valeur par rapport à votre propre charge : un traitement batch nocturne peut tolérer du temps de vol, contrairement à une API sensible à la latence.
Une offre plus importante corrigera-t-elle un temps de vol élevé ?
Pas à elle seule. Ajouter des vCPU sur le même nœud mutualisé signifie que davantage de CPU virtuels se disputent les mêmes cœurs physiques saturés, et le pourcentage peut rester exactement identique. Pour supprimer le temps de vol, il faut une allocation CPU dédiée ou une migration vers un nœud moins chargé. Une part plus importante d’une machine chargée reste une part d’une machine chargée.
Pourquoi mon VPS affiche-t-il 0 en temps de vol alors qu’il est manifestement lent ?
Deux raisons sont fréquentes. L’hyperviseur peut ne pas exporter ce compteur, ce qui est courant sur les plateformes VMware et Hyper-V ; le champ reste donc à zéro, quelle que soit l’activité de l’hôte. Exécutez systemd-detect-virt pour identifier la plateforme utilisée. Sinon, le goulot d’étranglement se trouve ailleurs : vérifiez wa pour les attentes liées au stockage, comparez r et nproc pour mesurer votre propre surcharge, et consultez /sys/fs/cgroup/cpu.stat dans les conteneurs pour détecter une limitation par quota.
Puis-je réduire le temps de vol depuis mon serveur ?
Vous ne pouvez pas modifier l’ordonnancement de l’hôte depuis le guest. Vous pouvez seulement réduire son impact. Exécutez moins de threads workers que vous n’avez de vCPU, afin de limiter le travail placé dans la run queue en attente d’un cœur disponible. Déplacez les traitements batch vers les heures où le nœud est moins chargé. Mettez les résultats en cache afin que moins de requêtes nécessitent du CPU. Les changements qui suppriment réellement le temps de vol, comme une migration vers un autre nœud ou l’utilisation de cœurs dédiés, relèvent du fournisseur.