Entrées/sorties, limites et cgroups
Tu sais trouver le disque saturé et le processus qui le sature, choisir le bon outil pour chaque question, lire et régler les limites d'un utilisateur ou d'un processus, et plafonner la mémoire ou le CPU d'un service avec systemd.
Mis à jour le
À recouper avec le cours. Cette leçon a été écrite à partir du plan du chapitre, avant relecture avec les supports. En cas de doute, le cours fait foi.
Pourquoi on voit ça
Tu sais lire le processeur et la mémoire. Il reste deux causes de lenteur ou de panne : le disque qui ne suit pas, et une limite atteinte (trop de fichiers ouverts, trop de processus). Cette leçon ferme le chapitre avec les outils pour les voir, un tableau « quelle question, quel outil », puis la façon moderne de poser des limites : par service, avec systemd et les cgroups.
Les entrées/sorties
Une entrée/sortie (E/S, I/O), c’est une lecture ou une écriture sur un disque. Premier signal : le champ wa de top. S’il est élevé, le processeur attend le disque. Il reste à savoir quel disque et quel processus.
Quel disque : iostat
iostat fait partie du paquet sysstat.
iostat -x 2
-x donne les statistiques détaillées, 2 rafraîchit toutes les 2 secondes. Le premier bloc affiché est une moyenne depuis le démarrage : regarde les suivants. Extrait (la vraie sortie a plus de colonnes) :
Device r/s w/s rkB/s wkB/s w_await %util
sda 1.0 12.0 40.0 310.0 1.10 2.40
sdb 8.0 320.0 130.0 97400.0 185.30 99.70
| Colonne | Ce qu’elle dit |
|---|---|
r/s, w/s |
lectures et écritures par seconde |
rkB/s, wkB/s |
kilooctets lus et écrits par seconde |
r_await, w_await |
temps d’attente moyen d’une lecture, d’une écriture, en millisecondes |
%util |
part du temps où le disque est occupé |
Un %util proche de 100 avec un temps d’attente qui grimpe : le disque est saturé. Ici, c’est sdb.
Quel processus : iotop
iotop -o
iotop est un top trié par E/S. Il se lance en root. -o (only) n’affiche que les processus qui lisent ou écrivent en ce moment.
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
2210 be/4 postgres 0.00 B/s 95.10 M/s 0.00 % 87.20 % postgres: checkpointer
Les colonnes DISK READ et DISK WRITE donnent le débit de chaque processus. Le coupable est en haut.
Quelle question, quel outil
| Ta question | Outil | Ce que tu y lis |
|---|---|---|
| Qui consomme le CPU ? Le processeur attend-il le disque ? | top, htop |
ligne %Cpu(s), liste des processus |
| Que se passe-t-il seconde après seconde ? | vmstat 1 |
une ligne par seconde : processus, mémoire, swap, E/S, CPU |
| Reste-t-il de la mémoire ? | free -h |
colonne available, ligne Swap |
| Quel disque est saturé ? | iostat -x 2 |
%util, temps d’attente |
| Quel processus écrit sur le disque ? | iotop -o |
DISK READ, DISK WRITE |
htop est un top plus lisible, avec une barre par cœur. Dans vmstat, trois repères suffisent : si et so (ce qui entre et sort du swap : autre chose que 0 en continu, la machine swappe), et wa, le même que dans top.
Les limites système
Le noyau plafonne ce que chaque processus peut consommer, pour qu’un seul programme ne puisse pas épuiser la machine. Deux limites sont à connaître :
| Commande | Limite |
|---|---|
ulimit -n |
nombre de descripteurs de fichiers ouverts par processus |
ulimit -u |
nombre de processus de l’utilisateur |
Un descripteur de fichier est le numéro que le noyau donne à chaque fichier ouvert. Une connexion réseau en consomme un aussi. La valeur habituelle est 1024, vite atteinte par un serveur web ou une base de données. L’erreur est alors toujours la même :
Too many open files
Chaque limite a deux valeurs. La limite soft est celle qui s’applique. La limite hard est le plafond jusqu’où l’utilisateur peut relever sa limite soft. Seul root peut monter la hard.
ulimit -n # limite soft actuelle
ulimit -Hn # limite hard
ulimit -n 4096 # change la limite, pour cette session seulement
Rendre une limite durable : /etc/security/limits.conf
deploy soft nofile 8192
deploy hard nofile 16384
@devs hard nproc 200
Quatre colonnes : qui (un utilisateur, ou un groupe avec @), soft ou hard, quoi (nofile pour les fichiers ouverts, nproc pour les processus), la valeur. Le fichier est lu à l’ouverture de session : il faut se reconnecter. Et il ne concerne pas les services lancés par systemd.
Les ressources d’un processus dans /proc/<PID>/
Tu connais /proc/<PID>/. Trois entrées répondent à « que consomme ce processus, et jusqu’où a-t-il le droit d’aller ? ».
| Entrée | Contenu |
|---|---|
status |
l’état du processus et sa mémoire : VmRSS (RAM réellement occupée), VmSwap, Threads |
limits |
ses limites, avec les colonnes soft et hard |
fd/ |
un lien par descripteur ouvert |
grep "open files" /proc/2210/limits
ls /proc/2210/fd | wc -l
Max open files 1024 4096 files
1017
1017 descripteurs ouverts pour une limite soft de 1024 : ce processus est au bord du « Too many open files ».
Les limites posées par systemd
Un service ne passe pas par une session : ses limites s’écrivent dans son unité, section [Service]. Le plus propre est un drop-in, avec systemctl edit api :
[Service]
MemoryMax=500M
CPUQuota=50%
TasksMax=100
LimitNOFILE=65536
| Directive | Effet |
|---|---|
MemoryMax= |
plafond de mémoire. S’il est dépassé, l’OOM killer tue un processus du service |
CPUQuota= |
part de CPU maximale. 50% = la moitié d’un cœur, 200% = deux cœurs |
TasksMax= |
nombre maximal de processus et de threads du service |
LimitNOFILE= |
l’équivalent de ulimit -n pour le service |
Puis systemctl restart api. systemctl status api affiche alors la consommation et ses plafonds (lignes Tasks: et Memory:).
L’idée des cgroups
Un cgroup (control group) est une boîte du noyau dans laquelle on range des processus pour mesurer et limiter ce qu’ils consomment ensemble. systemd crée un cgroup par service : MemoryMax=, CPUQuota= et TasksMax= sont des réglages de cette boîte. Différence avec ulimit : une limite ulimit vaut pour chaque processus, une limite de cgroup vaut pour tout le groupe.
systemd-cgtop
C’est un top par cgroup : une ligne par service, avec ses tâches, son CPU, sa mémoire et ses E/S.
Contexte, pas à apprendre. Les cgroups sont visibles dans
/sys/fs/cgroup/. La limite de mémoire du serviceapise lit dans/sys/fs/cgroup/system.slice/api.service/memory.max. Les conteneurs Docker reposent sur le même mécanisme.
À retenir
waélevé danstop: le disque.iostat -xdit quel disque (%utilproche de 100, temps d’attente élevé),iotopdit quel processus.- Une question, un outil :
top/htoppour le CPU,vmstat 1pour suivre dans le temps,free -hpour la mémoire,iostatpour les disques,iotoppour les E/S par processus. ulimit -n: descripteurs de fichiers ouverts.ulimit -u: processus. « Too many open files » = limite-natteinte.- Limites durables d’un utilisateur :
/etc/security/limits.conf(soft, hard,nofile,nproc), lu à l’ouverture de session. /proc/<PID>/status(mémoire),/proc/<PID>/limits(limites),/proc/<PID>/fd/(descripteurs ouverts).- Pour un service :
MemoryMax=,CPUQuota=,TasksMax=,LimitNOFILE=dans[Service]. Les trois premières règlent le cgroup du service ;systemd-cgtopmontre la consommation par cgroup.
Entraînement
12 questions, dont 4 à compléter. Tu réponds, on passe à la suivante. La note arrive à la fin.
Ta note
Cartes · 8
Réviser les cartes ici
Pourquoi