5.9 KiB
\newpage
Utiliser les cgroups
Les cgroups (pour Control Groups) permettent de collecter des statistiques sur des groupes de processus (appelés tâches) et de leur attribuer des propriétés, comme par exemple pour leur imposer des limitations d'utilisation de ressources ou altérer leurs priorités.
Premiers tests
Nous allons commencer par faire quelques tests avec le cgroup freezer, qui permet d'interrompre l'exécution d'un groupe de processus et de la reprendre.
Montage du cgroup
En fonction de la configuration de votre système, il est possible que les
cgroups ne soient pas montés au démarrage dans /sys/fs/cgroup/
. Si vous n'avez
pas de dossier freezer
ou si celui-ci est vide, monter-le en suivant la
procédure suivante :
mkdir /sys/fs/cgroup/freezer/
mount -t cgroup -o freezer none /sys/fs/cgroup/freezer/
Cette dernière commande monte le groupe de processus racine, pour le cgroup freezer. Tous les dossiers contenu dans cette racine sont des sous-groupes de cette dernière.
Création d'un nouveau groupe
La première étape dans l'utilisation d'un cgroup est de créer un nouveau groupe.
Pour créer un groupe, il suffit de créer un nouveau dossier dans un groupe existant, par exemple la racine :
mkdir /sys/fs/cgroup/freezer/virli/
ls /sys/fs/cgroup/freezer/virli/
Vous avez maintenant un nouveau groupe de processus virli
dans le cgroup
Freezer. Comme il s'agit d'une hiérarchie, le groupe virli
hérite des
propriétés de son (ses) père(s).
Rattachement de processus
Pour le moment, ce nouveau groupe ne contient aucune tâche.
Ouvrons un nouveau terminal (c'est lui que l'on va freezer), et récupérons son
PID : echo $$
.
La liste des processus rattachés à un cgroup se trouve dans le fichier task
du groupe. Pour ajouter une tâche à ce groupe, cela se passe de cette manière :
echo $PID > /sys/fs/cgroup/freezer/virli/tasks
Il faut ici remplacer $PID
par le PID du shell que l'on a relevé juste avant.
En validant cette commande, vous avez déplacé le processus dans ce groupe, il n'est alors plus dans aucun autre groupe (dans ce cgroup, il ne bouge pas dans les autres cgroups).
Consultation de l'état
En affichant le contenu du dossier virli
, nous avons pu constater que
celui-ci contenait déjà un certain nombre de fichiers. Certain d'entre-eux sont
en lecture seule et permettent de lire des statistiques instantanées sur le
groupe ; tandis que d'autres sont des propriétés que vous pouvez modifier.
Nous pouvons consulter l'état de gel du groupe en affichant le contenu du
fichier\newline /sys/fs/cgroup/freezer/virli/freezer.state
.
Pour plus d'information sur les différents fichiers présents dans ce cgroup, consulter la documentation, accessible ici : https://www.kernel.org/doc/Documentation/cgroups/freezer-subsystem.txt
Changement d'état
Faisons exécuter à notre interpréteur une commande pour voir effectivement l'exécution s'arrêter. Si vous manquez d'inspiration, utilisez :
for i in $(seq 9999); do echo -n $i; sleep .1; echo -n " - "; sleep .1; done
Maintenant, nous avons donné l'ordre au noyau de ne plus allouer de temps de calcul à notre shell et ses fils :
echo FROZEN > /sys/fs/cgroup/freezer/virli/freezer.state
À cet instant, vous devriez voir votre compteur s'arrêter. Pour reprendre l'exécution :
echo THAWED > /sys/fs/cgroup/freezer/virli/freezer.state
Script de monitoring
À nous maintenant de concevoir un script qui va enregistrer vers la base de données créée (metrics) dans la partie précédente, des statistiques issues des cgroups.
Monitoring instantané vers la console
Dans un premier temps, commençons par afficher dans la console la quantité de mémoire utilisée par le groupe monitoré.
- Arguments de la ligne de commande :
- premier fils à lancer dans le groupe,
- intervalle de temps entre deux rafraîchissement ;
- cgroup
memory
; memory.usage_in_bytes
.
Vous pouvez utiliser un programme comme memhog
pour remplir rapidement votre
mémoire.
Si vous n'avez pas le cgroup memory, il est possible qu'il ne soit pas activé par défaut par votre système. Si vous êtes dans ce cas, essayez d'ajouter
cgroup_enable=memory
Monitoring vers InfluxDB
Maintenant, envoyons nos données vers la base https://influxdb.com/docs/v0.9/guides/writing_data.html :
curl -i -XPOST 'http://172.23.42.2:8086/write?db=metrics' --data-binary \
"$my_cgroup_name memory.usage_in_bytes=$(cat .../my_cgroup_name/memory.usage_in_bytes)"
Pour vérifier que les données sont bien ajoutées, vous pouvez effectuez la requête suivante dans l'interface web d'InfluxDB :
SELECT * from "$my_cgroup_name";
Monitorer davantage de données
Liste non exhaustive de données à monitorer :
- Nombre d'IOs effectué ;
- nombre d'octets lu/écrit sur les disques ;
- temps de calcul utilisé ;
- trafic réseau généré ;
- ...
https://www.kernel.org/doc/Documentation/cgroups/
Permettre à l'utilisateur de monitorer des process
Maintenant, séparer votre script en deux parties afin qu'un utilisateur normal (non-root) puisse utiliser la partie monitoring de notre script.
Un premier script doit s'occuper de créer le(s) cgroups et lui attribuer les bons droits, tandis que le deuxième va utiliser effectuer le monitoring, sans
Exemple
42sh# ./monitor_init my_cgroup_name
42sh$ ./monitor my_cgroup_name memhog 500
Rendu
Script de monitoring
Rendez la révision la plus avancée de vos scripts de monitoring de process via les cgroups.
Questions
-
Un même processus peut-il être dans plusieurs cgroups de type différents (freezer et cpuacct par exemple) ?
-
Que sera-t-il possible de limiter via un nouveau cgroup dans la prochaine version du noyau (4.3) ?
-
Actuellement, comment peut-on limiter le nombre de processus lancés par un utilisateur ou un groupe ?