virli/tutorial/3/cgroups.md

288 lines
8.7 KiB
Markdown
Raw Normal View History

2016-10-03 10:27:18 +00:00
\newpage
2016-10-05 09:13:56 +00:00
Utiliser les *cgroup*s
======================
2016-10-03 10:27:18 +00:00
Les *cgroup*s (pour *Control Group*s) permettent de collecter des statistiques
sur des groupes de processus (appelés tâches) et de leur attribuer des
2017-10-23 20:25:51 +00:00
propriétés. Par exemple, il est possible leur imposer des limites d'utilisation
de ressources ou d'altérer leur comportement.
2016-10-03 10:27:18 +00:00
## Premiers tests
2017-10-22 22:14:32 +00:00
Nous allons commencer par faire quelques tests avec le *cgroup* *freezer*, qui
2016-10-03 10:27:18 +00:00
permet d'interrompre l'exécution d'un groupe de processus et de la reprendre.
2016-10-05 20:49:08 +00:00
2016-10-03 10:27:18 +00:00
### Montage du *cgroup*
En fonction de la configuration de votre système, il est possible que les
*cgroup*s ne soient pas montés au démarrage dans `/sys/fs/cgroup/`. Si vous n'avez
2016-10-05 20:49:08 +00:00
pas de dossier `freezer` ou si celui-ci est vide, montez-le en suivant la
2016-10-03 10:27:18 +00:00
procédure suivante :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
mkdir /sys/fs/cgroup/freezer/
mount -t cgroup -o freezer none /sys/fs/cgroup/freezer/
2016-10-03 10:27:18 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-10-03 10:27:18 +00:00
2018-10-31 08:41:27 +00:00
Cette dernière commande monte l'arborescence de groupes relative à ce *cgroup*
2017-10-23 20:25:51 +00:00
*freezer*. Tous les dossiers contenus dans cette racine sont donc des
2016-10-05 20:49:08 +00:00
sous-groupes.
2016-10-03 10:27:18 +00:00
### Création d'un nouveau groupe
2017-10-22 22:14:32 +00:00
La première étape dans l'utilisation d'un *cgroup* est de créer un groupe.
2016-10-03 10:27:18 +00:00
2017-10-22 22:14:32 +00:00
Pour ce faire, il suffit de créer un nouveau dossier dans un groupe existant,
par exemple la racine :
2016-10-03 10:27:18 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
mkdir /sys/fs/cgroup/freezer/virli/
ls /sys/fs/cgroup/freezer/virli/
2016-10-03 10:27:18 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-10-03 10:27:18 +00:00
2017-09-27 08:02:52 +00:00
Nous avons maintenant un nouveau groupe de processus `virli` dans le *cgroup*
2017-10-22 22:14:32 +00:00
*Freezer*. Comme il s'agit d'une hiérarchie, le groupe `virli` hérite des
2016-10-03 10:27:18 +00:00
propriétés de son (ses) père(s).
2016-10-05 20:49:08 +00:00
2016-10-03 10:27:18 +00:00
### Rattachement de processus
Pour le moment, ce nouveau groupe ne contient aucune tâche.
2017-10-22 22:14:32 +00:00
Ouvrons un nouveau terminal (c'est lui que l'on va geler), et récupérons son
2016-10-03 10:27:18 +00:00
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 :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
echo $PID > /sys/fs/cgroup/freezer/virli/tasks
2016-10-03 10:27:18 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-10-03 10:27:18 +00:00
Il faut ici remplacer `$PID` par le PID du shell que l'on a relevé juste avant.
2017-09-27 08:02:52 +00:00
En validant cette commande, nous avons déplacé le processus dans ce groupe, il
2016-10-05 20:49:08 +00:00
n'est alors plus dans aucun autre groupe (pour ce *cgroup*, il ne bouge pas
2016-10-03 10:27:18 +00:00
dans les autres *cgroup*s).
2017-10-22 22:14:32 +00:00
Malgré l'utilisation de la redirection `>` (et non `>>`), il s'agit belle et
bien d'un ajout au fichier et non d'un écrasement. Il faut garder en tête que
le système de fichier est entièrement simulé et que certains comportements sont
adaptés.
2016-10-05 20:49:08 +00:00
2016-10-03 10:27:18 +00:00
### Consultation de l'état
2017-10-23 20:25:51 +00:00
En affichant le contenu du dossier `virli`, nous pouvions 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 nous pouvons modifier.
2016-10-03 10:27:18 +00:00
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*,
2017-10-22 22:14:32 +00:00
consultez
2019-10-22 16:03:09 +00:00
[la documentation associée](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/freezer-subsystem.html).
2016-10-05 20:49:08 +00:00
2016-10-03 10:27:18 +00:00
### 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 :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
for i in $(seq 9999); do echo -n $i; sleep .1; echo -n " - "; sleep .1; done
2016-10-03 10:27:18 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-10-03 10:27:18 +00:00
Maintenant, nous avons donné l'ordre au noyau de ne plus allouer de temps de
calcul à notre shell et ses fils :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
echo FROZEN > /sys/fs/cgroup/freezer/virli/freezer.state
2016-10-03 10:27:18 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-10-03 10:27:18 +00:00
À cet instant, vous devriez voir votre compteur s'arrêter. Pour reprendre
l'exécution :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
echo THAWED > /sys/fs/cgroup/freezer/virli/freezer.state
2016-10-03 10:27:18 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-10-03 10:27:18 +00:00
2016-10-05 20:49:08 +00:00
## Exercice : script de monitoring
À nous maintenant de concevoir un script qui va enregistrer vers une base de
données des statistiques issues des *cgroup*s.
### Rappel d'InfluxDB
Commençons par lancer le conteneur Docker d'InfluxDB (pour éviter de
l'installer sur notre machine) :
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
docker container run --name mytsdb -d -p 8086:8086 influxdb
2016-10-05 20:49:08 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-10-05 20:49:08 +00:00
2017-10-22 22:14:32 +00:00
Il nous faut ensuite créer une base de données pour y stocker nos
2018-10-31 08:41:27 +00:00
métriques. Voici comment on s'était débrouillé dans un précédent TP pour
interagir avec InfluxDB :
2016-10-05 20:49:08 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
docker container exec -i mytsdb influxdb <<EOF
CREATE DATABASE metrics;
SHOW DATABASES;
EOF
2016-10-05 20:49:08 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-10-03 10:27:18 +00:00
2017-10-23 20:25:51 +00:00
Vérifiez que la base de données `metrics` a bien été créée.
2017-10-22 22:14:32 +00:00
2016-10-03 10:27:18 +00:00
### Monitoring instantané vers la console
2017-10-22 22:14:32 +00:00
Dans un premier temps, commençons par afficher dans la console, la quantité de
2016-10-03 10:27:18 +00:00
mémoire utilisée par le groupe monitoré.
2019-11-03 17:54:39 +00:00
Vous pouvez utiliser un programme comme
[`memhog`](https://virli.nemunai.re/memhog.c) pour remplir rapidement votre
2016-10-03 10:27:18 +00:00
mémoire.
<div lang="en-US">
2018-10-31 08:41:27 +00:00
```
42sh# mkdir /sys/fs/cgroup...
42sh$ echo $$ | sudo tee /sys/fs/cgroup.../tasks
42sh# ./monitor group_name memhog 500
~~~ 13595 ~~~ Current memory usage: 75194368/550502400 (13%)
~~~ 13595 ~~~ Current memory usage: 150290432/550502400 (27%)
~~~ 13595 ~~~ Current memory usage: 223690752/550502400 (40%)
~~~ 13595 ~~~ Current memory usage: 296828928/550502400 (53%)
~~~ 13595 ~~~ Current memory usage: 368001024/550502400 (66%)
~~~ 13595 ~~~ Current memory usage: 438517760/550502400 (79%)
~~~ 13595 ~~~ Current memory usage: 480329728/550502400 (87%)
~~~ 13595 ~~~ Current memory usage: 155648/550502400 (0%)
2018-10-31 08:41:27 +00:00
```
</div>
2018-10-31 08:41:27 +00:00
2017-10-23 20:25:51 +00:00
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` à la ligne de commande de votre noyau.
2016-10-03 10:27:18 +00:00
### Monitoring vers InfluxDB
Maintenant, envoyons nos données vers la base
2018-10-31 08:41:27 +00:00
<https://docs.influxdata.com/influxdb/v1.6/guides/writing_data/> :
2016-10-03 10:27:18 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
```bash
curl -i -XPOST 'http://localhost:8086/write?db=metrics' --data-binary \
"$my_cgroup_name memory.usage_in_bytes=$(cat .../my_cgroup_name/memory.usage_in_bytes)"
2016-10-03 10:27:18 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-10-03 10:27:18 +00:00
2017-09-27 08:02:52 +00:00
Pour vérifier que les données ont bien été ajoutées, nous pouvons effectuer la
2017-10-22 22:14:32 +00:00
requête suivante dans notre client `influx` :
2016-10-03 10:27:18 +00:00
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2016-10-06 01:58:52 +00:00
```sql
SELECT * from "$my_cgroup_name";
2016-10-03 10:27:18 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-10-03 10:27:18 +00:00
2016-10-05 20:49:08 +00:00
2016-10-03 10:27:18 +00:00
### 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é ;
* ...
2017-09-27 08:05:55 +00:00
Tous les cgroups existants dans le dernier noyau publié ont leur documentation
2019-10-22 16:03:09 +00:00
accessible ici :
<https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/index.html>
2016-10-05 20:49:08 +00:00
2016-10-03 10:27:18 +00:00
2016-10-06 01:58:52 +00:00
### Permettre à l'utilisateur de monitorer des processus
2016-10-03 10:27:18 +00:00
2017-09-27 08:02:52 +00:00
Maintenant, séparons notre script en deux parties afin qu'un utilisateur normal
2016-10-03 10:27:18 +00:00
(non-root) puisse utiliser la partie monitoring de notre script.
Un premier script doit s'occuper de créer le(s) *cgroup*s et lui attribuer les
2017-10-23 20:25:51 +00:00
bons droits, tandis que le deuxième va effectuer le monitoring, sans privilèges
particuliers.
2016-10-03 10:27:18 +00:00
#### Exemple
2017-10-17 06:29:07 +00:00
<div lang="en-US">
2016-10-03 10:27:18 +00:00
```
42sh$ sudo ./monitor_init my_cgroup_name
42sh$ ./monitor my_cgroup_name memhog 500
2016-10-03 10:27:18 +00:00
```
2017-10-17 06:29:07 +00:00
</div>
2016-10-03 10:27:18 +00:00
2017-10-04 23:42:56 +00:00
## Fixer des limites
2017-10-22 22:14:32 +00:00
Au delà de la simple consultation, les *cgroup*s peuvent servir à limiter la
quantité de ressources mise à disposition à un groupe de processus.
2017-10-04 23:42:56 +00:00
2017-10-22 22:14:32 +00:00
Pour définir une limite, nous allons écrire la valeur dans le fichier
correspondant à une valeur limite, comme par exemple
`memory.max_usage_in_bytes`, qui limite le nombre d'octets que notre groupe de
processus va pouvoir allouer au maximum :
2017-10-04 23:42:56 +00:00
<div lang="en-US">
```
42sh$ cat /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
0
# 0 = Aucune limite
42sh$ echo 4M > /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
# Maintenant, la limite est à 4MB, vérifions...
42sh$ cat /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
4194304
2017-10-22 22:14:32 +00:00
```
</div>
2017-10-04 23:42:56 +00:00
2017-10-22 22:14:32 +00:00
Chaque *cgroup*s défini de nombreux indicateurs et possède de nombreux
limiteurs, n'hésitez pas à consulter la documentation associée à chaque
*cgroup*.
2017-10-04 23:42:56 +00:00
## Pour aller plus loin {-}
2016-10-05 20:49:08 +00:00
2017-09-27 08:05:55 +00:00
Pour tout connaître en détails, [la série d'articles de Neil Brown sur les
Control groups](https://lwn.net/Articles/604609/) est excellente !
2016-10-05 20:49:08 +00:00
Depuis les noyaux 4.5, il est possible d'utiliser la nouvelle version du
pseudo système de fichiers des *CGroup*s. Le principal changement vient du
regroupement au sein d'une seule hiérarchie des différents *CGroup*s que l'on
avait dans la v1. Davantage d'informations sont disponibles :
2016-10-06 01:58:52 +00:00
* [Understanding the new control groups API](https://lwn.net/Articles/679786/)
2016-10-05 20:49:08 +00:00
;
2019-10-22 16:03:09 +00:00
* [Kernel Document about Control Group v2](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html).