Save tuto corrections
This commit is contained in:
parent
f5ee6b8534
commit
10448a6c8d
115 changed files with 1423 additions and 1289 deletions
|
|
@ -3,7 +3,7 @@ include ../pandoc-opts.mk
|
||||||
SOURCES = tutorial.md \
|
SOURCES = tutorial.md \
|
||||||
../docker-basis/discover.md ../docker-basis/installation.md ../docker-basis/what.md ../docker-basis/first.md ../docker-basis/cleaning.md ../docker-basis/ex-flask.md \
|
../docker-basis/discover.md ../docker-basis/installation.md ../docker-basis/what.md ../docker-basis/first.md ../docker-basis/cleaning.md ../docker-basis/ex-flask.md \
|
||||||
../docker-basis/volumes.md \
|
../docker-basis/volumes.md \
|
||||||
../docker-basis/linking.md \
|
../docker-basis/linking.md ../docker-basis/linking-ex-fic.md ../docker-basis/linking-ex-help.md \
|
||||||
../docker-advanced/what.md ../docker-advanced/setup.md ../docker-advanced/manual.md ../docker-advanced/compose.md \
|
../docker-advanced/what.md ../docker-advanced/setup.md ../docker-advanced/manual.md ../docker-advanced/compose.md \
|
||||||
../docker-advanced/security.md \
|
../docker-advanced/security.md \
|
||||||
rendu.md
|
rendu.md
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ institute: EPITA
|
||||||
date: Jeudi 16 septembre 2021
|
date: Jeudi 16 septembre 2021
|
||||||
abstract: |
|
abstract: |
|
||||||
Durant ce premier TP, nous allons apprendre à utiliser Docker, puis
|
Durant ce premier TP, nous allons apprendre à utiliser Docker, puis
|
||||||
nous apprendrons à déployer un groupe de conteneurs !
|
nous apprendrons à déployer un groupe de conteneurs !
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
Rendu
|
Rendu
|
||||||
=====
|
=====
|
||||||
|
|
||||||
Est attendu d'ici le TP suivant :
|
Est attendu d'ici le TP suivant :
|
||||||
|
|
||||||
- le rendu des exercice de ce TP ;
|
- le rendu des exercice de ce TP ;
|
||||||
- vos réponses à [l'évaluation du cours](https://virli.nemunai.re/quiz/12).
|
- vos réponses à [l'évaluation du cours](https://virli.nemunai.re/quiz/12).
|
||||||
|
|
@ -41,7 +41,7 @@ Tous les fichiers identifiés comme étant à rendre pour ce TP sont à
|
||||||
placer dans une tarball (pas d'archive ZIP, RAR, ...).
|
placer dans une tarball (pas d'archive ZIP, RAR, ...).
|
||||||
|
|
||||||
Voici une arborescence type (vous pourriez avoir des fichiers
|
Voici une arborescence type (vous pourriez avoir des fichiers
|
||||||
supplémentaires) :
|
supplémentaires) :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ date: Jeudi 23 septembre 2021
|
||||||
abstract: |
|
abstract: |
|
||||||
Durant ce deuxième TP, nous allons voir comment créer nos propres
|
Durant ce deuxième TP, nous allons voir comment créer nos propres
|
||||||
images, et comment s'assurer qu'elles n'ont pas de vulnérabilités
|
images, et comment s'assurer qu'elles n'ont pas de vulnérabilités
|
||||||
connues !
|
connues !
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ On trouve par exemple :
|
||||||
Pour émettre un ping, il est nécessaire d'envoyer des paquets ICMP. À la
|
Pour émettre un ping, il est nécessaire d'envoyer des paquets ICMP. À la
|
||||||
différence des datagrammes UDP ou des segments TCP, il n'est pas forcément
|
différence des datagrammes UDP ou des segments TCP, il n'est pas forcément
|
||||||
simple d'envoyer des paquets ICMP lorsque l'on est simple utilisateur, car
|
simple d'envoyer des paquets ICMP lorsque l'on est simple utilisateur, car
|
||||||
l'usage du protocole ICMP dans une socket est restreint : il faut soit être
|
l'usage du protocole ICMP dans une soket est restreint : il faut soit être
|
||||||
super-utilisateur, soit que le noyau ait été configuré pour autoriser certains
|
super-utilisateur, soit que le noyau ait été configuré pour autoriser certains
|
||||||
utilisateurs à envoyer des `ECHO_REQUEST`.
|
utilisateurs à envoyer des `ECHO_REQUEST`.
|
||||||
|
|
||||||
|
|
@ -64,7 +64,7 @@ se mettent à fournir par défaut une configuration qui permette de se passer de
|
||||||
*capabilities* pour lancer `ping`.\
|
*capabilities* pour lancer `ping`.\
|
||||||
|
|
||||||
Si vous vous rendez compte que votre binaire `ping` est dans ce cas, testez
|
Si vous vous rendez compte que votre binaire `ping` est dans ce cas, testez
|
||||||
depuis un conteneur, par exemple :
|
depuis un conteneur, par exemple :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -83,7 +83,7 @@ depuis un conteneur, par exemple :
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Dans le conteneur le binaire `ping` est *setuid root*, vous pouvez faire des
|
Dans le conteneur le binaire `ping` est *setuid root*, vous pouvez faire des
|
||||||
tests en retirant le *setuid* :
|
tests en retirant le *setuid* :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -94,7 +94,7 @@ tests en retirant le *setuid* :
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Puis en ajoutant la *capability* :
|
Puis en ajoutant la *capability* :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
### Exercice (obligatoire pour les SRS -- optionnel pour les GISTRE)
|
### Exercice (obligatoire pour les SRS -- optionnel pour les GISTRE)
|
||||||
|
|
||||||
Poursuivons [notre script de monitoring](#script-monitoring) afin d'envoyer nos
|
Poursuivons [notre script de monitoring](#script-monitoring) afin d'envoyer nos
|
||||||
résultats vers InfluxDB : nous l'appellerons `./telegraf.sh`
|
résultats vers InfluxDB : nous l'appellerons `./telegraf.sh`.
|
||||||
|
|
||||||
#### Rappel d'InfluxDB\
|
#### Rappel d'InfluxDB\
|
||||||
|
|
||||||
Commençons par lancer le conteneur Docker d'InfluxDB (pour éviter de
|
Commençons par lancer le conteneur Docker d'InfluxDB (pour éviter de
|
||||||
l'installer sur notre machine) :
|
l'installer sur notre machine) :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -16,7 +16,7 @@ docker container run --name mytsdb -d -p 8086:8086 influxdb:1.8
|
||||||
|
|
||||||
Il nous faut ensuite créer une base de données pour y stocker nos
|
Il nous faut ensuite créer une base de données pour y stocker nos
|
||||||
métriques. Voici comment on s'était débrouillé précédemment pour interagir avec
|
métriques. Voici comment on s'était débrouillé précédemment pour interagir avec
|
||||||
InfluxDB :
|
InfluxDB :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -33,7 +33,7 @@ Vérifiez que la base de données `metrics` a bien été créée.
|
||||||
#### Monitoring vers InfluxDB\
|
#### Monitoring vers InfluxDB\
|
||||||
|
|
||||||
Maintenant, envoyons nos données vers la base
|
Maintenant, envoyons nos données vers la base
|
||||||
<https://docs.influxdata.com/influxdb/v1.8/guides/write_data/> :
|
<https://docs.influxdata.com/influxdb/v1.8/guides/write_data/> :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -43,7 +43,7 @@ curl -i -XPOST 'http://localhost:8086/write?db=metrics' --data-binary \
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Pour vérifier que les données ont bien été ajoutées, nous pouvons effectuer la
|
Pour vérifier que les données ont bien été ajoutées, nous pouvons effectuer la
|
||||||
requête suivante dans notre client `influx` :
|
requête suivante dans notre client `influx` :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```sql
|
```sql
|
||||||
|
|
@ -54,15 +54,15 @@ SELECT * from "$my_cgroup_name";
|
||||||
|
|
||||||
#### Monitorer davantage de données\
|
#### Monitorer davantage de données\
|
||||||
|
|
||||||
Liste non exhaustive de données à monitorer :
|
Liste non exhaustive de données à monitorer :
|
||||||
|
|
||||||
* Nombre d'IOs effectué ;
|
* Nombre d'IOs effectué ;
|
||||||
* nombre d'octets lus/écrits sur les disques ;
|
* nobre d'octets lus/écrits sur les disques ;
|
||||||
* temps de calcul utilisé (`userspace`, `system`, tout confondu) ;
|
* temps de calcul utilisé (`userspace`, `system`, tout confondu) ;
|
||||||
* ...
|
* ...
|
||||||
|
|
||||||
Tous les cgroups existants dans le dernier noyau publié ont leur documentation
|
Tous les cgroups existants dans le dernier noyau publié ont leur documentation
|
||||||
accessible ici :
|
accessible ici :
|
||||||
|
|
||||||
- v1 : <https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/index.html>
|
- v1 : <https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/index.html>
|
||||||
- v2 : <https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html>
|
- v2 : <https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html>
|
||||||
|
|
|
||||||
|
|
@ -4,40 +4,40 @@ Les *cgroup*s
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Les *cgroup*s (pour *Control Group*s) permettent de collecter des statistiques
|
Les *cgroup*s (pour *Control Group*s) permettent de collecter des statistiques
|
||||||
sur des **groupes de processus** (voire même, des threads !) et de leur
|
sur des **groupes de processus** (voire même, des threads !) et de leur
|
||||||
attribuer des propriétés. Il est par exemple possible de leur imposer des
|
attribuer des propriétés. Il est par exemple possible de leur imposer des
|
||||||
limites d'utilisation de ressources ou d'altérer leur comportement : quantité
|
limites d'utilisation de ressources ou d'altérer leur comportement : quantité
|
||||||
de RAM, temps CPU, bande passante, ...
|
de RAM, temps CPU, bande passante, ...
|
||||||
|
|
||||||
Apparue dès [Linux
|
Apparue dès [Linux
|
||||||
2.6.24](https://kernelnewbies.org/Linux_2_6_24#Task_Control_Groups)
|
2.6.24](https://kernelnewbies.org/Linux_2_6_24#Task_Control_Groups)
|
||||||
(en 2008 !), les *cgroup*s sont répartis en différents sous-systèmes
|
(en 2008 !), les *cgroup*s sont répartis en différents sous-systèmes
|
||||||
(*subsystem*), chacun étant responsable d'un type de ressources
|
(*subsystem*), chacun étant responsable d'un type de ressources
|
||||||
spécifique :
|
spécifique :
|
||||||
|
|
||||||
- [`blkio` (`io` dans la v2)
|
- [`blkio` (`io` dans la v2)
|
||||||
:](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/blkio-controller.html)
|
:](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/blkio-controller.html)
|
||||||
limites et statistiques de bande passante sur les disques ;
|
limites et statistiques de bande passante sur les disques ;
|
||||||
- `cpu` : cycles CPU minimum garantis ;
|
- `cpu` : cycles CPU minimum garantis ;
|
||||||
- [`cpuacct` (inclus dans `cpu` dans la v2)
|
- [`cpuacct` (inclus dans `cpu` dans la v2)
|
||||||
:](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cpuacct.html)
|
:](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cpuacct.html)
|
||||||
statistiques du temps CPU utilisé ;
|
statistiques du temps CPU utilisé ;
|
||||||
- [`cpuset`
|
- [`cpuset`
|
||||||
:](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cpusets.html)
|
:](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cpusets.html)
|
||||||
associe des tâches à un/des CPU particuliers (par exemple pour dédier un cœur
|
associe des tâches à un/des CPU particuliers (par exemple pour dédier un cœur
|
||||||
du CPU à un programme, qui ne pourra alors utiliser que ce CPU et pas les
|
du CPU à un programme, qui ne pourra alors utiliser que ce CPU et pas les
|
||||||
autres) ;
|
autres) ;
|
||||||
- [`devices`
|
- [`devices`
|
||||||
:](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/devices.html)
|
:](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/devices.html)
|
||||||
règles de contrôle de création (`mknod`) et d'accès aux périphériques ;
|
règles de contrôle de création (`mknod`) et d'accès aux périphériques ;
|
||||||
- [`freezer`
|
- [`freezer`
|
||||||
:](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/freezer-subsystem.html)
|
:](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/freezer-subsystem.html)
|
||||||
pour suspendre et reprendre l'exécution d'un groupe de tâches ;
|
pour suspendre et reprendre l'exécution d'un groupe de tâches ;
|
||||||
- [`hugetlb` :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/hugetlb.html) statistiques et limitation de l'usage de la fonctionnalité `HugeTLB` (permettant d'obtenir des pages mémoires plus grande que 4 kB) ;
|
- [`hugetlb` :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/hugetlb.html) statistiques et limitation de l'usage de la fonctionnalité `HugeTLB` (permettant d'obtenir des pages mémoires plus grande que 4 kB) ;
|
||||||
- [`memory` :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/memory.html) statistiques et limitation d'usage de la mémoire vive et de la *swap* ;
|
- [`memory` :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/memory.html) statistiques et limitation d'usage de la mémoire vive et de la *swap* ;
|
||||||
- [`net_cls` (v1 seulement) :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/net_cls.html) applique un `classid` à tous les paquets émis par les tâches du *cgroup*, pour filtrage par le pare-feu en sortie ;
|
- [`net_cls` (v1 seulement) :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/net_cls.html) applique un `classid` à tous les paquets émis par les tâches du *cgroup*, pour filtrage par le pare-feu en sortie ;
|
||||||
- [`net_prio` (v1 seulement) :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/net_prio.html) surcharge la valeur de l'option de priorité `SO_PRIORITY`, ordonant la file d'attente des paquets sortants ;
|
- [`net_prio` (v1 seulement) :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/net_prio.html) surcharge la valeur de l'option de priorité `SO_PRIORITY`, ordonant la file d'attente des paquets sortants ;
|
||||||
- [`pids` :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/pids.html) statistiques et limitation du nombre de processus ;
|
- [`pids` :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/pids.html) statistiques et limitation du nombre de processus ;
|
||||||
- ...
|
- ...
|
||||||
|
|
||||||
Nous allons commencer par faire quelques tests avec le *cgroup* *freezer*, qui
|
Nous allons commencer par faire quelques tests avec le *cgroup* *freezer*, qui
|
||||||
|
|
@ -48,19 +48,19 @@ lorsqu'on le décide.
|
||||||
### Montage du *freezer*
|
### Montage du *freezer*
|
||||||
|
|
||||||
En fonction de la configuration de votre système, vous allez vous trouver dans
|
En fonction de la configuration de votre système, vous allez vous trouver dans
|
||||||
l'une de ces trois situations :
|
l'une de ces trois situations :
|
||||||
|
|
||||||
- Votre dossier `/sys/fs/cgroup` contient à la fois des fichiers `cgroup.*` et
|
- Votre dossier `/sys/fs/cgroup` contient à la fois des fichiers `cgroup.*` et
|
||||||
éventuellement des dossiers : vous avez une distribution moderne qui utilise
|
éventuellement des dossiers : vous avez une distribution moderne qui utilise
|
||||||
la nouvelle version des `cgroup`s.
|
la nouvelle version des `cgroup`s.
|
||||||
|
|
||||||
- Votre dossier `/sys/fs/cgroup` contient d'autres dossiers au nom des
|
- Votre dossier `/sys/fs/cgroup` contient d'autres dossiers au nom des
|
||||||
sous-systèmes que l'on a listé ci-dessus : il s'agit des `cgroup`s v1.
|
sous-systèmes que l'on a listé ci-dessus : il s'agit des `cgroup`s v1.
|
||||||
|
|
||||||
- Votre dossier `/sys/fs/cgroup` est vide ou inexistant, vous pouvez choisir
|
- Votre dossier `/sys/fs/cgroup` est vide ou inexistant, vous pouvez choisir
|
||||||
d'utiliser la version de votre choix :
|
d'utiliser la version de votre choix :
|
||||||
|
|
||||||
Pour utiliser la v1 :
|
Pour utiliser la v1 :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -70,7 +70,7 @@ l'une de ces trois situations :
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
Pour utiliser la v2 :
|
Pour utiliser la v2 :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -103,7 +103,7 @@ La première étape dans l'utilisation d'un *cgroup* est donc de créer un group
|
||||||
Pour ce faire, il suffit de créer un nouveau dossier dans un groupe existant,
|
Pour ce faire, il suffit de créer un nouveau dossier dans un groupe existant,
|
||||||
par exemple la racine.
|
par exemple la racine.
|
||||||
|
|
||||||
On commence par se rendre à la racine :
|
On commence par se rendre à la racine :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -112,7 +112,7 @@ cd /sys/fs/cgroup/ # v2
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Puis on crée notre groupe :
|
Puis on crée notre groupe :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -134,7 +134,7 @@ version, vous allez devoir activer le ou les contrôleurs dont vous avez besoin
|
||||||
sous-système que l'on voulait).
|
sous-système que l'on voulait).
|
||||||
|
|
||||||
Pour activer le contrôleur *memory* dans notre groupe `virli`, nous utilisons
|
Pour activer le contrôleur *memory* dans notre groupe `virli`, nous utilisons
|
||||||
la commande suivante :
|
la commande suivante :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -163,9 +163,9 @@ le fichier `cgroup.procs` de notre groupe. Ce fichier contient la liste des
|
||||||
processus rattachés à notre *cgroup*.
|
processus rattachés à notre *cgroup*.
|
||||||
|
|
||||||
Ouvrons un nouveau terminal (c'est lui que l'on va geler), et récupérons son
|
Ouvrons un nouveau terminal (c'est lui que l'on va geler), et récupérons son
|
||||||
PID : `echo $$`.
|
PID : `echo $$`.
|
||||||
|
|
||||||
Pour ajouter une tâche à ce groupe, cela se passe de cette manière :
|
Pour ajouter une tâche à ce groupe, cela se passe de cette manière :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -190,7 +190,7 @@ adaptés.
|
||||||
En affichant le contenu du dossier `virli`, nous pouvions constater que
|
En affichant le contenu du dossier `virli`, nous pouvions constater que
|
||||||
celui-ci contenait déjà un certain nombre de fichiers. Certains d'entre-eux
|
celui-ci contenait déjà un certain nombre de fichiers. Certains d'entre-eux
|
||||||
sont en lecture seule et permettent de lire des statistiques instantanées sur
|
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.
|
le groupe ; tandis que d'autres sont des propriétés que nous pouvons modifier.
|
||||||
|
|
||||||
Nous pouvons consulter l'état de gel du groupe en affichant le contenu du
|
Nous pouvons consulter l'état de gel du groupe en affichant le contenu du
|
||||||
fichier\
|
fichier\
|
||||||
|
|
@ -204,7 +204,7 @@ consultez
|
||||||
### Changement d'état
|
### Changement d'état
|
||||||
|
|
||||||
Faisons exécuter à notre interpréteur une commande pour voir effectivement
|
Faisons exécuter à notre interpréteur une commande pour voir effectivement
|
||||||
l'exécution s'arrêter. Si vous manquez d'inspiration, utilisez :
|
l'exécution s'arrêter. Si vous manquez d'inspiration, utilisez :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -213,7 +213,7 @@ for i in $(seq 9999); do echo -n $i; sleep .1; echo -n " - "; sleep .1; done
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Maintenant, nous avons donné l'ordre au noyau de ne plus allouer de temps de
|
Maintenant, nous avons donné l'ordre au noyau de ne plus allouer de temps de
|
||||||
calcul à notre shell et ses fils :
|
calcul à notre shell et ses fils :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -223,7 +223,7 @@ echo 1 > /sys/fs/cgroup/virli/cgroup.freeze # v2
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
À cet instant, vous devriez voir votre compteur s'arrêter. Pour reprendre
|
À cet instant, vous devriez voir votre compteur s'arrêter. Pour reprendre
|
||||||
l'exécution :
|
l'exécution :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -233,7 +233,7 @@ echo 0 > /sys/fs/cgroup/virli/cgroup.freeze # v2
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
### Exercice : script de monitoring {- #script-monitoring}
|
### Exercice : script de monitoring {- #script-monitoring}
|
||||||
|
|
||||||
À nous maintenant de concevoir un script qui va enregistrer vers une base de
|
À nous maintenant de concevoir un script qui va enregistrer vers une base de
|
||||||
données des statistiques issues des *cgroup*s, tel `telegraf`.
|
données des statistiques issues des *cgroup*s, tel `telegraf`.
|
||||||
|
|
@ -267,7 +267,7 @@ doit cependant être possible d'y trouver des statistiques intéressantes, dont
|
||||||
la quantité de mémoire utilisée. Ici nous affichons au début le PID du
|
la quantité de mémoire utilisée. Ici nous affichons au début le PID du
|
||||||
processus, ce qui peut simplifier le débogage du script.\
|
processus, ce qui peut simplifier le débogage du script.\
|
||||||
|
|
||||||
Il s'utilise de la manière suivante :
|
Il s'utilise de la manière suivante :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -275,7 +275,7 @@ Il s'utilise de la manière suivante :
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Où :
|
Où :
|
||||||
|
|
||||||
- `group_name` correspond au nom du/des *cgroup*(s) à créer/rejoindre.
|
- `group_name` correspond au nom du/des *cgroup*(s) à créer/rejoindre.
|
||||||
- `prog [args [...]]` est la commande que l'on souhaite monitorer, à exécuter
|
- `prog [args [...]]` est la commande que l'on souhaite monitorer, à exécuter
|
||||||
|
|
@ -297,7 +297,7 @@ quantité de ressources mises à disposition à un groupe de processus.
|
||||||
Pour définir une limite, nous allons écrire la valeur dans le fichier
|
Pour définir une limite, nous allons écrire la valeur dans le fichier
|
||||||
correspondant à une valeur limite, comme par exemple
|
correspondant à une valeur limite, comme par exemple
|
||||||
`memory.max_usage_in_bytes`/`memory.max`, qui limite le nombre d'octets que
|
`memory.max_usage_in_bytes`/`memory.max`, qui limite le nombre d'octets que
|
||||||
notre groupe de processus va pouvoir allouer au maximum :
|
notre groupe de processus va pouvoir allouer au maximum :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -330,7 +330,7 @@ limiteurs, n'hésitez pas à consulter la documentation associée à chaque
|
||||||
*cgroup*.
|
*cgroup*.
|
||||||
|
|
||||||
Mettez à jour votre script de monitoring pour prendre en compte les
|
Mettez à jour votre script de monitoring pour prendre en compte les
|
||||||
limites que vous avez définies :
|
limites que vous avez définies :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -352,5 +352,5 @@ limites que vous avez définies :
|
||||||
### Pour aller plus loin {-}
|
### Pour aller plus loin {-}
|
||||||
|
|
||||||
Pour tout connaître en détails, [la série d'articles de Neil Brown sur les
|
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 ! Plus [cet
|
Control groups](https://lwn.net/Articles/604609/) est excellente ! Plus [cet
|
||||||
article sur la version 2](https://lwn.net/Articles/679786/).
|
article sur la version 2](https://lwn.net/Articles/679786/).
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
L'isolation ... à 1 € ?
|
L'isolation ... à 1 € ?
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Depuis les premières versions d'Unix, il est possible de changer le répertoire
|
Depuis les premières versions d'Unix, il est possible de changer le répertoire
|
||||||
|
|
@ -83,7 +83,7 @@ pacstrap newroot/
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Dans les deux cas, nous nous retrouvons avec un dossier `newroot` contenant une
|
Dans les deux cas, nous nous retrouvons avec un dossier `newroot` contenant une
|
||||||
distribution complète minimale, dans laquelle nous pouvons entrer :
|
distribution complète minimale, dans laquelle nous pouvons entrer :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -100,9 +100,10 @@ sous forme de tarball :
|
||||||
|
|
||||||
#### Gentoo\
|
#### Gentoo\
|
||||||
|
|
||||||
|
<http://gentoo.mirrors.ovh.net/gentoo-distfiles/releases/amd64/autobuilds/current-stage3-amd64-openrc/stage3-amd64-openrc-20211128T170532Z.tar.xz>
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
wget http://gentoo.mirrors.ovh.net/gentoo-distfiles/releases/amd64/autobuilds/current-stage3-amd64/stage3-amd64-20210630T214504Z.tar.xz
|
|
||||||
tar xpf stage3-amd64-*.tar.xz -C newroot/
|
tar xpf stage3-amd64-*.tar.xz -C newroot/
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -113,7 +114,7 @@ environnement qui tient dans 200 MB.
|
||||||
:::::
|
:::::
|
||||||
|
|
||||||
Comme pour les autres distributions vues précédemment, nous pouvons entrer dans
|
Comme pour les autres distributions vues précédemment, nous pouvons entrer dans
|
||||||
notre nouvelle racine comme ceci :
|
notre nouvelle racine comme ceci :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -124,15 +125,16 @@ chroot newroot/ bash
|
||||||
|
|
||||||
#### Alpine\
|
#### Alpine\
|
||||||
|
|
||||||
|
<https://dl-cdn.alpinelinux.org/alpine/v3.14/releases/x86_64/alpine-minirootfs-3.14.2-x86_64.tar.gz>
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
wget https://dl-cdn.alpinelinux.org/alpine/v3.14/releases/x86_64/alpine-minirootfs-3.14.2-x86_64.tar.gz
|
|
||||||
tar xpf alpine-minirootfs-*.tar.xz -C newroot/
|
tar xpf alpine-minirootfs-*.tar.xz -C newroot/
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Alpine se contentant de Busybox pour son système de base, nous n'avons pas
|
Alpine se contentant de Busybox pour son système de base, nous n'avons pas
|
||||||
`bash`, mais on peut tout de même lancer `ash` :
|
`bash`, mais on peut tout de même lancer `ash` :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,5 @@ allons tâcher d'apprendre comment il fonctionne en nous penchant sur un certain
|
||||||
nombre de fonctionnalités de Linux.
|
nombre de fonctionnalités de Linux.
|
||||||
|
|
||||||
Dans un premier temps, nous allons aborder la manière dont le noyau Linux
|
Dans un premier temps, nous allons aborder la manière dont le noyau Linux
|
||||||
permet de contrôler les processus : que ce soit en collectant des informations
|
permet de contrôler les processus : que ce soit en collectant des informations
|
||||||
sur eux ou en imposant certaines restrictions.
|
sur eux ou en imposant certaines restrictions.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
Gestion de la mémoire
|
Gestion de la mémoire
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Linux a une gestion de la mémoire bien particulière[^vm-overcommit] : par
|
Linux a une gestion de la mémoire bien particulière[^vm-overcommit] : par
|
||||||
défaut, `malloc(3)` ne retournera jamais `NULL`. En se basant sur l'euristique
|
défaut, `malloc(3)` ne retournera jamais `NULL`. En se basant sur l'euristique
|
||||||
qu'un bloc mémoire demandé ne sera pas utilisé directement et que de nombreux
|
qu'un bloc mémoire demandé ne sera pas utilisé directement et que de nombreux
|
||||||
process ne feront pas un usage total des blocks qu'ils ont alloués, le noyau
|
process ne feront pas un usage total des blocks qu'ils ont alloués, le noyau
|
||||||
|
|
@ -22,7 +22,7 @@ est-ce `init` qui est en train de gérer le lancement d'un nouveau daemon). On
|
||||||
dit alors que le noyau est *Out-Of-Memory*.
|
dit alors que le noyau est *Out-Of-Memory*.
|
||||||
|
|
||||||
Pour se sortir d'une telle situation, et après avoir tenté de vider les caches,
|
Pour se sortir d'une telle situation, et après avoir tenté de vider les caches,
|
||||||
il lance son arme ultime, pour retrouver au plus vite de la mémoire :
|
il lance son arme ultime pour retrouver au plus vite de la mémoire :
|
||||||
l'*Out-Of-Memory killer*.
|
l'*Out-Of-Memory killer*.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ jusqu'à ce que le système retrouve sa sérénité.
|
||||||
[^oom-algo]: <https://linux-mm.org/OOM_Killer>
|
[^oom-algo]: <https://linux-mm.org/OOM_Killer>
|
||||||
|
|
||||||
|
|
||||||
## Esquiver l'OOM killer ?
|
## Esquiver l'OOM killer ?
|
||||||
|
|
||||||
Au sein d'un *cgroup* *memory*, les fichiers `memory.oom_control` (v1) ou
|
Au sein d'un *cgroup* *memory*, les fichiers `memory.oom_control` (v1) ou
|
||||||
`memory.events` (v2) peuvent être utilisé afin de recevoir une notification du
|
`memory.events` (v2) peuvent être utilisé afin de recevoir une notification du
|
||||||
|
|
@ -58,4 +58,4 @@ ce sujet.
|
||||||
Continuons l'exercice précédent où nous avions [fixé les
|
Continuons l'exercice précédent où nous avions [fixé les
|
||||||
limites](#Fixer-des-limites) de mémoire que pouvez réserver les processus de
|
limites](#Fixer-des-limites) de mémoire que pouvez réserver les processus de
|
||||||
notre groupe. Que se passe-t-il alors si `memhog` dépasse la quantité de
|
notre groupe. Que se passe-t-il alors si `memhog` dépasse la quantité de
|
||||||
mémoire autorisée dans le `cgroup` ?
|
mémoire autorisée dans le `cgroup` ?
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
../../subject/2/project-part1.md
|
|
||||||
115
tutorial/3/project-body.md
Normal file
115
tutorial/3/project-body.md
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
## Palier 1 : Restreindre l'environnement (2 points) {-}
|
||||||
|
|
||||||
|
Après avoir mis en place les bases de votre programme, commencez par créer les
|
||||||
|
différentes hiérarchies (si vous avez un noyau récent, vous pouvez utiliser les
|
||||||
|
cgroups-v2) dont vous allez avoir besoin pour limiter l'utilisation de
|
||||||
|
ressources.
|
||||||
|
|
||||||
|
Puis, mettez en place ces limites :
|
||||||
|
|
||||||
|
* pas plus d'1 GB de mémoire utilisée ;
|
||||||
|
* 1 seul CPU au maximum ;
|
||||||
|
* 100 PIDs ;
|
||||||
|
* ...
|
||||||
|
|
||||||
|
En bonus, vous pouvez gérer les cas où le noyau sur lequel s'exécute votre
|
||||||
|
moulinette ne possède pas tous ces *CGroup*s, au lieu de planter, ne rien faire
|
||||||
|
n'est pas forcément une mauvaise solution.
|
||||||
|
|
||||||
|
|
||||||
|
## Palier 2 : Réduire les `capabilities` (2 points) {-}
|
||||||
|
|
||||||
|
Réduisez au maximum les *capabilities*, de telle sorte qu'il ne soit pas
|
||||||
|
possible de faire un ping dans l'environnement restreint :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```
|
||||||
|
42sh# ping 9.9.9.9
|
||||||
|
PING 9.9.9.9 (9.9.9.9) 56(84) bytes of data.
|
||||||
|
64 bytes from 9.9.9.9: icmp_seq=1 ttl=56 time=3.93 ms
|
||||||
|
64 bytes from 9.9.9.9: icmp_seq=2 ttl=56 time=3.97 ms
|
||||||
|
^C
|
||||||
|
--- 9.9.9.9 ping statistics ---
|
||||||
|
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
|
||||||
|
rtt min/avg/max/mdev = 3.931/3.954/3.978/0.067 ms
|
||||||
|
|
||||||
|
42sh# ./mymoulette /bin/bash
|
||||||
|
bash# curl http://www.linuxcontainers.org/ | md5sum
|
||||||
|
c7d68d1cb4737125a84cd69f55add202
|
||||||
|
|
||||||
|
bash# ping 9.9.9.9
|
||||||
|
ping: icmp open socket: Permission denied
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
**Astuces\ :** `prctl(2)`, `capabilities(7)`, `capget(2)`, `capset(2)`, ...
|
||||||
|
|
||||||
|
Aidez-vous du visualisateur de *capabilities* de la partie 1.3 du TP, pour voir
|
||||||
|
si vous êtes sur la bonne voie.
|
||||||
|
|
||||||
|
Si votre distribution vous permet d'utiliser `ping` sans privilège, utilisez à
|
||||||
|
la place n'importe quel binaire ayant besoin de *capabilities* pour vos tests,
|
||||||
|
par exemple `arping` (qui nécessite `CAP_NET_RAW`) ou `halt` (qui nécessite
|
||||||
|
`CAP_SYS_BOOT`) :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```
|
||||||
|
42sh# ./mymoulette /bin/bash
|
||||||
|
bash# arping 192.168.0.1
|
||||||
|
arping: socket: Permission denied
|
||||||
|
|
||||||
|
bash# halt -f
|
||||||
|
halt: (null): Operation not permitted
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
## Palier bonus : Utilisable par un utilisateur (2 points) {-}
|
||||||
|
|
||||||
|
Jouez avec les attributs étendus pour qu'un utilisateur non-privilégié puisse
|
||||||
|
exécuter votre moulinette. Ajoutez la/les commande(s) à votre `Makefile` ou
|
||||||
|
script d'installation.
|
||||||
|
|
||||||
|
|
||||||
|
## Création d'un environnement d'exécution minimal {-}
|
||||||
|
|
||||||
|
Plutôt que d'utiliser votre système hôte au complet, avec tous ses programmes
|
||||||
|
et toutes ses bibliothèques, il faudrait utiliser un système contenant le
|
||||||
|
strict minimum. Recréez un environnement minimaliste, comme on a pu en voir
|
||||||
|
dans la partie sur les `chroot`.
|
||||||
|
|
||||||
|
**Ne mettez pas cet environnement dans votre tarball de rendu, il vous
|
||||||
|
sera seulement utile pour faire des tests.**
|
||||||
|
|
||||||
|
|
||||||
|
## Palier 3 : Isolation du pauvre (1 point) {-}
|
||||||
|
|
||||||
|
Nous n'avons pas encore vu de meilleure méthode pour mieux isoler
|
||||||
|
l'environnement que de faire un `chroot`, ajoutez à votre programme cette
|
||||||
|
isolation rudimentaire. Et rendez-vous au prochain cours pour avoir une
|
||||||
|
meilleure isolation !
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```
|
||||||
|
42sh$ which firefox
|
||||||
|
/usr/bin/firefox
|
||||||
|
42sh# ./mymoulette ./newrootfs/ /bin/bash
|
||||||
|
bash# which firefox
|
||||||
|
which: no firefox in (/usr/bin:/usr/local/bin:/bin:/opt/bin)
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
## Palier 4 : seccomp (2 points) {-}
|
||||||
|
|
||||||
|
Filtrez les appels système de telle sorte qu'aucun programme exécuté dans
|
||||||
|
votre bac à sable ne puisse plus lancer les appels systèmes suivants :
|
||||||
|
|
||||||
|
* `nfsservctl(2)` ;
|
||||||
|
* `personality(2)` ;
|
||||||
|
* `pivot_root(2)` ;
|
||||||
|
* ...
|
||||||
|
|
||||||
|
N'hésitez pas à en utiliser d'autres pour vos tests ;)
|
||||||
|
|
||||||
|
**Astuces\ :** `seccomp(2)`, `seccomp_init(3)`, `seccomp_load(3)`, ...
|
||||||
|
|
@ -6,7 +6,7 @@ Projet et rendu
|
||||||
## Sujet
|
## Sujet
|
||||||
|
|
||||||
Vous allez commencer aujourd'hui un projet qui s'étendra au prochain TP et qui
|
Vous allez commencer aujourd'hui un projet qui s'étendra au prochain TP et qui
|
||||||
consistera à réaliser la partie d'isolation de la moulinette des ACUs !
|
consistera à réaliser la partie d'isolation de la moulinette des ACUs !
|
||||||
|
|
||||||
Cette semaine, il faudra faire en sorte de restreindre un groupe de processus
|
Cette semaine, il faudra faire en sorte de restreindre un groupe de processus
|
||||||
pour qu'il ne puisse pas faire de déni de service sur notre machine.
|
pour qu'il ne puisse pas faire de déni de service sur notre machine.
|
||||||
|
|
@ -14,11 +14,11 @@ pour qu'il ne puisse pas faire de déni de service sur notre machine.
|
||||||
Il n'y a pas de restriction sur le langage utilisé, vous pouvez tout aussi bien
|
Il n'y a pas de restriction sur le langage utilisé, vous pouvez tout aussi bien
|
||||||
utiliser du C, du C++, du Python, etc.
|
utiliser du C, du C++, du Python, etc.
|
||||||
|
|
||||||
L'usage de bibliothèques **non relatives** au projet est autorisé : le but de
|
L'usage de bibliothèques **non relatives** au projet est autorisé : le but de
|
||||||
ce sujet est d'évaluer votre compréhension et votre utilisation de la
|
ce sujet est d'évaluer votre compréhension et votre utilisation de la
|
||||||
tuyauterie bas-niveau du noyau liée à la virtualisation légère. À partir du
|
tuyauterie bas-niveau du noyau liée à la virtualisation légère. À partir du
|
||||||
moment où vous n'utilisez pas une bibliothèque qui abstrait complètement cette
|
moment où vous n'utilisez pas une bibliothèque qui abstrait complètement cette
|
||||||
plomberie, n'hésitez pas à l'utiliser !
|
plomberie, n'hésitez pas à l'utiliser !
|
||||||
|
|
||||||
Gardez en tête que ce projet sera à continuer au prochain TP, où il sera
|
Gardez en tête que ce projet sera à continuer au prochain TP, où il sera
|
||||||
principalement question de faire des appels systèmes.
|
principalement question de faire des appels systèmes.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
Rendu
|
Rendu
|
||||||
=====
|
=====
|
||||||
|
|
||||||
Est attendu d'ici le TP suivant :
|
Est attendu d'ici le TP suivant :
|
||||||
|
|
||||||
- le rendu des exercice de ce TP ;
|
- le rendu des exercice de ce TP ;
|
||||||
- vos réponses à [l'évaluation du cours](https://virli.nemunai.re/quiz/14).
|
- vos réponses à [l'évaluation du cours](https://virli.nemunai.re/quiz/14).
|
||||||
|
|
@ -40,7 +40,7 @@ placer dans une tarball (pas d'archive ZIP, RAR, ...).
|
||||||
|
|
||||||
Voici une arborescence type (adaptez les extensions et les éventuels
|
Voici une arborescence type (adaptez les extensions et les éventuels
|
||||||
fichiers supplémentaires associés au langage que vous aurez choisi
|
fichiers supplémentaires associés au langage que vous aurez choisi
|
||||||
pour chaque exercice) :
|
pour chaque exercice) :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -41,13 +41,13 @@ apporter des modifications.
|
||||||
Linux emploie de nombreux systèmes de fichiers virtuels :
|
Linux emploie de nombreux systèmes de fichiers virtuels :
|
||||||
|
|
||||||
- `/proc` : contient, principalement, la liste des processus (`top` et ses
|
- `/proc` : contient, principalement, la liste des processus (`top` et ses
|
||||||
dérivés se contentent de lire les fichiers de ce point de montage) ;
|
dérivés se contentent de lire les fichiers de ce point de montage) ;
|
||||||
- `/proc/sys` : contient la configuration du noyau ;
|
- `/proc/sys` : contient la configuration du noyau ;
|
||||||
- `/sys` : contient des informations à propos du matériel (utilisées notamment
|
- `/sys` : contient des informations à propos du matériel (utilisées notamment
|
||||||
par `udev` pour peupler `/dev`) et des périphériques (taille des tampons,
|
par `udev` pour peupler `/dev`) et des périphériques (taille des tampons,
|
||||||
clignottement des DELs, ...) ;
|
clignottement des DELs, ...) ;
|
||||||
- `/sys/firmware/efi/efivars` : pour accéder et modifier les variables de
|
- `/sys/firmware/efi/efivars` : pour accéder et modifier les variables de
|
||||||
l'UEFI ;
|
l'UEFI ;
|
||||||
- ...
|
- ...
|
||||||
|
|
||||||
Tous ces systèmes de fichiers sont généralement exclusivement stockés en
|
Tous ces systèmes de fichiers sont généralement exclusivement stockés en
|
||||||
|
|
@ -130,7 +130,7 @@ uts:[4026531838]
|
||||||
Explorons le pseudo système de fichiers `/sys` pour écrire un script
|
Explorons le pseudo système de fichiers `/sys` pour écrire un script
|
||||||
qui va, en fonction de ce que vous avez de disponible :
|
qui va, en fonction de ce que vous avez de disponible :
|
||||||
|
|
||||||
* afficher des statistiques sur notre batterie ;
|
* afficher des statistiques sur notre batterie ;
|
||||||
* afficher des statistiques la fréquence du CPU.
|
* afficher des statistiques la fréquence du CPU.
|
||||||
|
|
||||||
##### `batinfo.sh`\
|
##### `batinfo.sh`\
|
||||||
|
|
@ -194,7 +194,7 @@ Maintenant que vous savez lire des informations dans `/sys`, tentons d'aller
|
||||||
modifier le comportement de notre système. Au choix, réalisez l'un des scripts
|
modifier le comportement de notre système. Au choix, réalisez l'un des scripts
|
||||||
suivants, en fonction du matériel dont vous disposez :
|
suivants, en fonction du matériel dont vous disposez :
|
||||||
|
|
||||||
* inverser l'état des diodes de notre clavier ;
|
* inverser l'état des diodes de notre clavier ;
|
||||||
* mettre en veille votre machine, en ayant programmé une heure de réveil.
|
* mettre en veille votre machine, en ayant programmé une heure de réveil.
|
||||||
|
|
||||||
##### `rev_kdb_leds.sh`\
|
##### `rev_kdb_leds.sh`\
|
||||||
|
|
@ -203,7 +203,7 @@ Si vous avez :
|
||||||
|
|
||||||
* numlock On,
|
* numlock On,
|
||||||
* capslock Off,
|
* capslock Off,
|
||||||
* scrolllock Off ;
|
* scrolllock Off ;
|
||||||
|
|
||||||
Après avoir exécuté le script, nous devrions avoir :
|
Après avoir exécuté le script, nous devrions avoir :
|
||||||
|
|
||||||
|
|
@ -242,7 +242,8 @@ Voici un exemple d'utilisation :
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Vous aurez besoin de définir une alarme au niveau de votre RTC, via le
|
Vous aurez besoin de définir une alarme au niveau de votre RTC, via le
|
||||||
fichier : `/sys/class/rtc/rtcX/wakealarm`.
|
fichier :\
|
||||||
|
`/sys/class/rtc/rtcX/wakealarm`
|
||||||
|
|
||||||
::::: {.warning}
|
::::: {.warning}
|
||||||
Attention au fuseau horaire utilisé par votre RTC, si votre système principal
|
Attention au fuseau horaire utilisé par votre RTC, si votre système principal
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,13 @@ particulier peut être renvoyé au programme.
|
||||||
Depuis la version 3.17 du noyau, l'appel système `seccomp(2)` permet de faire
|
Depuis la version 3.17 du noyau, l'appel système `seccomp(2)` permet de faire
|
||||||
entrer le processus courant dans ce mode. En effet, c'est le processus lui-même
|
entrer le processus courant dans ce mode. En effet, c'est le processus lui-même
|
||||||
qui déclare au noyau qu'il peut désormais se contenter d'une liste réduite
|
qui déclare au noyau qu'il peut désormais se contenter d'une liste réduite
|
||||||
d'appels système ; à l'inverse des politiques de sécurité comme SELinux ou
|
d'appels système ; à l'inverse des politiques de sécurité comme SELinux ou
|
||||||
AppArmor, qui encapsulent les programmes pour toute la durée de leur exécution.
|
AppArmor, qui encapsulent les programmes pour toute la durée de leur exécution.
|
||||||
|
|
||||||
*Seccomp* est particulièrement utile lorsqu'un processus a terminé son
|
*Seccomp* est particulièrement utile lorsqu'un processus a terminé son
|
||||||
initialisation (ne dépendant en général pas de données sujettes à
|
initialisation (ne dépendant en général pas de données sujettes à
|
||||||
l'exploitation de vulnérabilité) et doit commencer à entrer dans des portions
|
l'exploitation de vulnérabilité) et doit commencer à entrer dans des portions
|
||||||
de code promptes aux vulnérabilités : c'est notamment le cas des moteurs de
|
de code promptes aux vulnérabilités : c'est notamment le cas des moteurs de
|
||||||
rendus des navigateurs Firefox et Chrome.
|
rendus des navigateurs Firefox et Chrome.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ des appels système `read(2)`, `write(2)` (sur les descripteurs de fichier déj
|
||||||
ouvert), `_exit(2)` et `sigreturn(2)`.
|
ouvert), `_exit(2)` et `sigreturn(2)`.
|
||||||
|
|
||||||
Historiquement, avant la création de l'appel système `seccomp(2)`, on activait
|
Historiquement, avant la création de l'appel système `seccomp(2)`, on activait
|
||||||
ce mode via :
|
ce mode via :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```c
|
```c
|
||||||
|
|
@ -63,7 +63,7 @@ auquel est appliqué un filtre `seccomp`, héritent également de ce filtre.
|
||||||
|
|
||||||
La construction de ce filtre est faite de manière programmatique, via
|
La construction de ce filtre est faite de manière programmatique, via
|
||||||
des règles BPF (`Berkeley Packet Filter`). On passe ensuite ce filtre BPF en
|
des règles BPF (`Berkeley Packet Filter`). On passe ensuite ce filtre BPF en
|
||||||
argument de l'appel système :
|
argument de l'appel système :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```c
|
```c
|
||||||
|
|
@ -79,7 +79,7 @@ seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
|
||||||
|
|
||||||
### Exercice {-}
|
### Exercice {-}
|
||||||
|
|
||||||
Écrivez un programme filtrant un appel système, à l'aide de `seccomp` :
|
Écrivez un programme filtrant un appel système, à l'aide de `seccomp` :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
\newpage
|
\newpage
|
||||||
|
|
||||||
### Exercice : comparaison de *namespace* -- `cmpns.sh`
|
### Exercice : comparaison de *namespace* -- `cmpns.sh`
|
||||||
|
|
||||||
Les *namespaces* d'un programme sont exposés sous forme de liens symboliques
|
Les *namespaces* d'un programme sont exposés sous forme de liens symboliques
|
||||||
dans le répertoire `/proc/<PID>/ns/`.
|
dans le répertoire `/proc/<PID>/ns/`.
|
||||||
|
|
@ -46,9 +46,9 @@ que l'on cherche à comparer.
|
||||||
|
|
||||||
Ici, `self` fait référence au processus actuellement exécuté (comme il existe
|
Ici, `self` fait référence au processus actuellement exécuté (comme il existe
|
||||||
un dossier `/proc/self/`, vous n'avez pas besoin de gérer de cas particulier
|
un dossier `/proc/self/`, vous n'avez pas besoin de gérer de cas particulier
|
||||||
pour ça !).
|
pour ça !).
|
||||||
|
|
||||||
Et pourquoi pas :
|
Et pourquoi pas :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
\newpage
|
\newpage
|
||||||
|
|
||||||
Exercice : `docker exec`
|
Exercice : `docker exec`
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
Après voir lu la partie concernant les *namespaces*, vous avez dû comprendre
|
Après voir lu la partie concernant les *namespaces*, vous avez dû comprendre
|
||||||
qu'un `docker exec`, n'était donc rien de plus qu'un `nsenter(1)`.
|
qu'un `docker exec`, n'était donc rien de plus qu'un `nsenter(1)`.
|
||||||
|
|
||||||
Réécrivons, en quelques lignes, la commande `docker exec` !
|
Réécrivons, en quelques lignes, la commande `docker exec` !
|
||||||
|
|
||||||
Pour savoir si vous avez réussi, comparez les sorties des commandes :
|
Pour savoir si vous avez réussi, comparez les sorties des commandes :
|
||||||
|
|
||||||
- `ip address` ;
|
- `ip address` ;
|
||||||
- `hostname` ;
|
- `hostname` ;
|
||||||
- `mount` ;
|
- `mount` ;
|
||||||
- `pa -aux` ;
|
- `ps -aux` ;
|
||||||
- ...
|
- ...
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -27,11 +27,11 @@ d63ceae863956f8312aca60b7a57fbcc1fdf679ae4c90c5d9455405005d4980a
|
||||||
234269
|
234269
|
||||||
|
|
||||||
42sh# ./mydocker_exec mywebserver ip address
|
42sh# ./mydocker_exec mywebserver ip address
|
||||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
|
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group def
|
||||||
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
||||||
inet 127.0.0.1/8 scope host lo
|
inet 127.0.0.1/8 scope host lo
|
||||||
valid_lft forever preferred_lft forever
|
valid_lft forever preferred_lft forever
|
||||||
13: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
13: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP group def
|
||||||
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
||||||
inet 172.17.0.1/16 scope global eth0
|
inet 172.17.0.1/16 scope global eth0
|
||||||
valid_lft forever preferred_lft forever
|
valid_lft forever preferred_lft forever
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ En fonction des options qui lui sont passées, `unshare(1)` va créer le/les
|
||||||
nouveaux *namespaces* et placer le processus dedans.
|
nouveaux *namespaces* et placer le processus dedans.
|
||||||
|
|
||||||
Par exemple, nous pouvons modifier sans crainte le nom de notre machine, si
|
Par exemple, nous pouvons modifier sans crainte le nom de notre machine, si
|
||||||
nous sommes passés dans un autre *namespace* `UTS` :
|
nous sommes passés dans un autre *namespace* `UTS` :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -64,7 +64,7 @@ Ce *syscall*, propre à Linux, crée habituellement un nouveau processus (mais
|
||||||
aussi des threads) enfant de notre processus courant, comme `fork(2)` (qui lui
|
aussi des threads) enfant de notre processus courant, comme `fork(2)` (qui lui
|
||||||
est un appel système POSIX) mais prend en plus de nombreux
|
est un appel système POSIX) mais prend en plus de nombreux
|
||||||
paramètres. L'isolement ou non du processus se fait en fonction des *flags* qui
|
paramètres. L'isolement ou non du processus se fait en fonction des *flags* qui
|
||||||
sont passés :
|
sont passés :
|
||||||
|
|
||||||
* `CLONE_NEWNS`,
|
* `CLONE_NEWNS`,
|
||||||
* `CLONE_NEWUTS`,
|
* `CLONE_NEWUTS`,
|
||||||
|
|
@ -83,7 +83,7 @@ que nous verrons plus tard.
|
||||||
|
|
||||||
Pour créer un nouveau processus qui sera à la fois dans un nouvel espace de
|
Pour créer un nouveau processus qui sera à la fois dans un nouvel espace de
|
||||||
noms réseau et dans un nouveau *namespace* `cgroup`, on écrirait un code C
|
noms réseau et dans un nouveau *namespace* `cgroup`, on écrirait un code C
|
||||||
semblable à :
|
semblable à :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```c
|
```c
|
||||||
|
|
@ -118,7 +118,7 @@ dans un nouvel espace de noms. Dans ce cas, on utilisera l'appel système
|
||||||
|
|
||||||
::::: {.warning}
|
::::: {.warning}
|
||||||
Le comportement de `unshare(2)` (ou `unshare(3)`) avec les *namespace*s *PID*
|
Le comportement de `unshare(2)` (ou `unshare(3)`) avec les *namespace*s *PID*
|
||||||
et *Time* n'est pas celui que l'on peut attendre !
|
et *Time* n'est pas celui que l'on peut attendre !
|
||||||
|
|
||||||
En effet, après avoir appelé `unshare`, le processus reste tout de même dans
|
En effet, après avoir appelé `unshare`, le processus reste tout de même dans
|
||||||
son *namespace* *Time* ou *PID* d'origine, seuls ses enfants (après un appel à
|
son *namespace* *Time* ou *PID* d'origine, seuls ses enfants (après un appel à
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,12 @@ Les espaces de noms du noyau, que l'on appelle *namespaces*, permettent de
|
||||||
dupliquer certaines structures, habituellement considérées uniques pour le
|
dupliquer certaines structures, habituellement considérées uniques pour le
|
||||||
noyau, dans le but de les isoler d'un groupe de processus à un autre.
|
noyau, dans le but de les isoler d'un groupe de processus à un autre.
|
||||||
|
|
||||||
On en dénombre huit (le dernier ayant été ajouté dans Linux 5.6) : `cgroup`,
|
On en dénombre huit (le dernier ayant été ajouté dans Linux 5.6) : `cgroup`,
|
||||||
`IPC`, `network`, `mount`, `PID`, `time`, `user` et `UTS`.
|
`IPC`, `network`, `mount`, `PID`, `time`, `user` et `UTS`.
|
||||||
|
|
||||||
La notion d'espace de noms est relativement nouvelle et a été intégrée
|
La notion d'espace de noms est relativement nouvelle et a été intégrée
|
||||||
progressivement au sein du noyau Linux. Aussi, toutes les structures ne sont
|
progressivement au sein du noyau Linux. Aussi, toutes les structures ne sont
|
||||||
pas encore *containerisables* : le document fondateur[^NSDOC] parle ainsi
|
pas encore *containerisables* : le document fondateur[^NSDOC] parle ainsi
|
||||||
d'isoler les journaux d'événements ou encore les modules de sécurité (LSM, tels
|
d'isoler les journaux d'événements ou encore les modules de sécurité (LSM, tels
|
||||||
que AppArmor, SELinux, Yama, ...).
|
que AppArmor, SELinux, Yama, ...).
|
||||||
|
|
||||||
|
|
@ -74,12 +74,12 @@ Cet espace de noms isole la liste des processus et virtualise leurs numéros.
|
||||||
|
|
||||||
Une fois dans un espace, le processus ne voit que le sous-arbre de processus
|
Une fois dans un espace, le processus ne voit que le sous-arbre de processus
|
||||||
également attachés à son espace. Il s'agit d'un sous-ensemble de l'arbre global
|
également attachés à son espace. Il s'agit d'un sous-ensemble de l'arbre global
|
||||||
de PID : les processus de tous les PID *namespaces* apparaissent donc dans
|
de PID : les processus de tous les PID *namespaces* apparaissent donc dans
|
||||||
l'arbre initial.
|
l'arbre initial.
|
||||||
|
|
||||||
Pour chaque nouvel espace de noms de processus, une nouvelle numérotation est
|
Pour chaque nouvel espace de noms de processus, une nouvelle numérotation est
|
||||||
initiée. Ainsi, le premier processus de cet espace porte le numéro 1 et aura
|
initiée. Ainsi, le premier processus de cet espace porte le numéro 1 et aura
|
||||||
les mêmes propriétés que le processus `init` usuel\ ; entre autres, si un
|
les mêmes propriétés que le processus `init` usuel\ ; entre autres, si un
|
||||||
processus est rendu orphelin dans ce *namespace*, il devient un fils de ce
|
processus est rendu orphelin dans ce *namespace*, il devient un fils de ce
|
||||||
processus, et non un fils de l'`init` de l'arbre global.
|
processus, et non un fils de l'`init` de l'arbre global.
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ processus, et non un fils de l'`init` de l'arbre global.
|
||||||
Depuis Linux 2.6.29.
|
Depuis Linux 2.6.29.
|
||||||
|
|
||||||
Cet espace de noms fournit une isolation pour toutes les ressources associées
|
Cet espace de noms fournit une isolation pour toutes les ressources associées
|
||||||
aux réseaux : les interfaces, les piles protocolaires IPv4 et IPv6, les tables
|
aux réseaux : les interfaces, les piles protocolaires IPv4 et IPv6, les tables
|
||||||
de routage, règles pare-feu, ports numérotés, etc.
|
de routage, règles pare-feu, ports numérotés, etc.
|
||||||
|
|
||||||
Une interface réseau (`eth0`, `wlan0`, ...) ne peut se trouver que dans un seul
|
Une interface réseau (`eth0`, `wlan0`, ...) ne peut se trouver que dans un seul
|
||||||
|
|
@ -126,7 +126,7 @@ correspond en fait à un sous-groupe de l'arborescence globale.
|
||||||
Ainsi, un processus dans un *CGroup* *namespace* ne peut pas voir le contenu
|
Ainsi, un processus dans un *CGroup* *namespace* ne peut pas voir le contenu
|
||||||
des sous-groupes parents (pouvant laisser fuiter des informations sur le reste
|
des sous-groupes parents (pouvant laisser fuiter des informations sur le reste
|
||||||
du système). Cela peut également permettre de faciliter la migration de
|
du système). Cela peut également permettre de faciliter la migration de
|
||||||
processus (d'un système à un autre) : l'arborescence des *cgroups* n'a alors
|
processus (d'un système à un autre) : l'arborescence des *cgroups* n'a alors
|
||||||
plus d'importance car le processus ne voit que son groupe.
|
plus d'importance car le processus ne voit que son groupe.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ de processus qui l'utilisent. C'est-à-dire que, la plupart du temps, le
|
||||||
termine.
|
termine.
|
||||||
|
|
||||||
Lorsque l'on a besoin de référencer un *namespace* (par exemple pour le faire
|
Lorsque l'on a besoin de référencer un *namespace* (par exemple pour le faire
|
||||||
persister après le dernier processus), on peut utiliser un `mount bind` :
|
persister après le dernier processus), on peut utiliser un `mount bind` :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -29,7 +29,7 @@ obtenir un descripteur de fichier valide vers le *namespace* (pour passer à
|
||||||
|
|
||||||
|
|
||||||
::::: {.question}
|
::::: {.question}
|
||||||
#### Faire persister un *namespace* ? {-}
|
#### Faire persister un *namespace* ? {-}
|
||||||
\
|
\
|
||||||
|
|
||||||
Il n'est pas possible de faire persister un espace de noms d'un reboot à
|
Il n'est pas possible de faire persister un espace de noms d'un reboot à
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ Le *namespace* `mount`
|
||||||
L'espace de noms `mount` permet d'isoler la vision du système de fichiers
|
L'espace de noms `mount` permet d'isoler la vision du système de fichiers
|
||||||
qu'ont un processus et ses fils.
|
qu'ont un processus et ses fils.
|
||||||
|
|
||||||
Peut-être que l'on peut trouver avec ça, un moyen de faire un `chroot` plus sûr ?
|
Peut-être que l'on peut trouver avec ça, un moyen de faire un `chroot` plus sûr ?
|
||||||
|
|
||||||
::::: {.warning}
|
::::: {.warning}
|
||||||
Attention il convient de prendre garde aux types de liaison existant entre vos
|
Attention il convient de prendre garde aux types de liaison existant entre vos
|
||||||
|
|
@ -33,7 +33,7 @@ Nous allons essayer de changer la racine de notre système de fichier. À la
|
||||||
différence d'un `chroot(2)`, changer de racine est quelque chose d'un peu plus
|
différence d'un `chroot(2)`, changer de racine est quelque chose d'un peu plus
|
||||||
sportif car il s'agit de ne plus avoir aucune trace de l'ancienne racine. Au
|
sportif car il s'agit de ne plus avoir aucune trace de l'ancienne racine. Au
|
||||||
moins ici, il ne sera certainement pas possible de revenir en arrière dans
|
moins ici, il ne sera certainement pas possible de revenir en arrière dans
|
||||||
l'arborescence\ !
|
l'arborescence !
|
||||||
|
|
||||||
Pour l'instant, votre système utilise sans doute la partition d'un disque
|
Pour l'instant, votre système utilise sans doute la partition d'un disque
|
||||||
physique comme racine de son système de fichier. Le changement de racine, va
|
physique comme racine de son système de fichier. Le changement de racine, va
|
||||||
|
|
@ -52,7 +52,7 @@ la racine d'un point de montage, comme l'explique `pivot_root(2)`. En effet, il
|
||||||
serait encore possible hypothétiquement de remonter dans l'arborescence si l'on
|
serait encore possible hypothétiquement de remonter dans l'arborescence si l'on
|
||||||
ne se trouvait pas à la racine d'une partition au moment du basculement.
|
ne se trouvait pas à la racine d'une partition au moment du basculement.
|
||||||
|
|
||||||
Si vous n'avez pas de partition à disposition, vous pouvez utiliser un `tmpfs` :
|
Si vous n'avez pas de partition à disposition, vous pouvez utiliser un `tmpfs` :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -61,32 +61,31 @@ Si vous n'avez pas de partition à disposition, vous pouvez utiliser un `tmpfs`
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Placez ensuite dans cette nouvelle racine le système de votre choix (cf. le TP
|
Placez ensuite dans cette nouvelle racine le système de votre choix.
|
||||||
précédent pour les différentes méthodes et liens).
|
|
||||||
|
|
||||||
|
|
||||||
### Exercice : Changer de racine -- `myswitch_root.sh`
|
### Exercice : Changer de racine -- `myswitch_root.sh`
|
||||||
|
|
||||||
Voici les grandes étapes du changement de racine :
|
Voici les grandes étapes du changement de racine :
|
||||||
|
|
||||||
1. S'isoler dans les *namespaces* adéquats ;
|
1. S'isoler dans les *namespaces* adéquats ;
|
||||||
2. Démonter ou déplacer toutes les partitions de l'ancienne racine vers la
|
2. Démonter ou déplacer toutes les partitions de l'ancienne racine vers la
|
||||||
nouvelle racine ;
|
nouvelle racine ;
|
||||||
3. `pivot_root` !
|
3. `pivot_root` !
|
||||||
|
|
||||||
|
|
||||||
#### S'isoler\
|
#### S'isoler\
|
||||||
|
|
||||||
Notre but étant de démonter toutes les partitions superflues, nous allons
|
Notre but étant de démonter toutes les partitions superflues, nous allons
|
||||||
devoir nous isoler sur :
|
devoir nous isoler sur :
|
||||||
|
|
||||||
* les points de montages, ça semble évident ;
|
* les points de montages, ça semble évident ;
|
||||||
* les PIDs : car on ne pourra pas démonter une partition en cours
|
* les PIDs : car on ne pourra pas démonter une partition en cours
|
||||||
d'utilisation. S'il n'y a pas de processus, il n'y a personne pour nous
|
d'utilisation. S'il n'y a pas de processus, il n'y a personne pour nous
|
||||||
empêcher de démonter une partition !
|
empêcher de démonter une partition !
|
||||||
* les autres *namespaces* ne sont pas forcément nécessaires.
|
* les autres *namespaces* ne sont pas forcément nécessaires.
|
||||||
|
|
||||||
Isolons-nous :
|
Isolons-nous :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -97,12 +96,12 @@ Isolons-nous :
|
||||||
|
|
||||||
#### Dissocier la propagation des démontages\
|
#### Dissocier la propagation des démontages\
|
||||||
|
|
||||||
Attention ! avant de pouvoir commencer à démonter les partitions, il faut
|
Attention ! avant de pouvoir commencer à démonter les partitions, il faut
|
||||||
s'assurer que les démontages ne se propagent pas via une politique de *shared
|
s'assurer que les démontages ne se propagent pas via une politique de *shared
|
||||||
mount*.
|
mount*.
|
||||||
|
|
||||||
Commençons donc par étiqueter tous nos points de montage (de ce *namespace*),
|
Commençons donc par étiqueter tous nos points de montage (de ce *namespace*),
|
||||||
comme esclaves :
|
comme esclaves :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -111,15 +110,15 @@ comme esclaves :
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
#### Démonter tout !\
|
#### Démonter tout !\
|
||||||
|
|
||||||
À vous maintenant de démonter vos points d'attache. Il ne devrait vous rester
|
À vous maintenant de démonter vos points d'attache. Il ne devrait vous rester
|
||||||
après cette étape que : `/`, `/dev`, `/sys`, `/proc`, `/run` et leurs fils.
|
après cette étape que : `/`, `/dev`, `/sys`, `/proc`, `/run` et leurs fils.
|
||||||
|
|
||||||
|
|
||||||
#### Switch !\
|
#### Switch !\
|
||||||
|
|
||||||
À ce stade, dans votre console, vous avez plusieurs solutions : utiliser
|
À ce stade, dans votre console, vous avez plusieurs solutions : utiliser
|
||||||
`switch_root(8)` ou `pivot_root(8)`. La première abstrait plus de choses que la
|
`switch_root(8)` ou `pivot_root(8)`. La première abstrait plus de choses que la
|
||||||
seconde.
|
seconde.
|
||||||
|
|
||||||
|
|
@ -136,7 +135,7 @@ Cette commande, plus proche du fonctionnement de l'appel système
|
||||||
`pivot_root(2)`, requiert de notre part que nous ayons préalablement déplacé
|
`pivot_root(2)`, requiert de notre part que nous ayons préalablement déplacé
|
||||||
les partitions systèmes à leur place dans la nouvelle racine.
|
les partitions systèmes à leur place dans la nouvelle racine.
|
||||||
|
|
||||||
L'appel de la commande sert à intervertir les deux racines ; elle prend en argument :
|
L'appel de la commande sert à intervertir les deux racines ; elle prend en argument :
|
||||||
|
|
||||||
* le chemin de la nouvelle racine,
|
* le chemin de la nouvelle racine,
|
||||||
* le chemin dans la nouvelle racine où placer l'ancienne.
|
* le chemin dans la nouvelle racine où placer l'ancienne.
|
||||||
|
|
@ -144,7 +143,7 @@ L'appel de la commande sert à intervertir les deux racines ; elle prend en argu
|
||||||
Une fois le pivot effectué, on peut démonter l'ancienne racine.
|
Une fois le pivot effectué, on peut démonter l'ancienne racine.
|
||||||
|
|
||||||
Pour lancer la première commande dans la nouvelle racine, on passe généralement
|
Pour lancer la première commande dans la nouvelle racine, on passe généralement
|
||||||
par :
|
par :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ Je vous recommande la lecture du *man* `namespaces(7)` introduisant et
|
||||||
énumérant les *namespaces*.
|
énumérant les *namespaces*.
|
||||||
|
|
||||||
Pour tout connaître en détails, [la série d'articles de Michael Kerrisk sur les
|
Pour tout connaître en détails, [la série d'articles de Michael Kerrisk sur les
|
||||||
*namespaces*](https://lwn.net/Articles/531114/) est excellente ! Auquel il faut
|
*namespaces*](https://lwn.net/Articles/531114/) est excellente ! Auquel il faut
|
||||||
ajouter [l'article sur le plus récent `cgroup`
|
ajouter [l'article sur le plus récent `cgroup`
|
||||||
*namespace*](https://lwn.net/Articles/621006/) et [le petit dernier sur le
|
*namespace*](https://lwn.net/Articles/621006/) et [le petit dernier sur le
|
||||||
*namespace* `time`](https://lwn.net/Articles/766089/).
|
*namespace* `time`](https://lwn.net/Articles/766089/).
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@ Le *namespace* `network` {#net-ns}
|
||||||
### Introduction
|
### Introduction
|
||||||
|
|
||||||
L'espace de noms `network`, comme son nom l'indique permet de virtualiser tout
|
L'espace de noms `network`, comme son nom l'indique permet de virtualiser tout
|
||||||
ce qui est en lien avec le réseau : les interfaces, les ports, les routes, les
|
ce qui est en lien avec le réseau : les interfaces, les ports, les routes, les
|
||||||
règles de filtrage, etc.
|
règles de filtrage, etc.
|
||||||
|
|
||||||
En entrant dans un nouvel espace de noms `network`, on se retrouve dans un
|
En entrant dans un nouvel espace de noms `network`, on se retrouve dans un
|
||||||
environnement qui n'a plus qu'une interface de *loopback* :
|
environnement qui n'a plus qu'une interface de *loopback* :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -25,7 +25,7 @@ environnement principal, il s'agit bien de deux interfaces isolées l'une de
|
||||||
l'autre.
|
l'autre.
|
||||||
|
|
||||||
Qui dit nouvelle pile réseau, dit également que les ports qui sont assignés
|
Qui dit nouvelle pile réseau, dit également que les ports qui sont assignés
|
||||||
dans l'espace principal, ne le sont plus dans le conteneur : il est donc
|
dans l'espace principal, ne le sont plus dans le conteneur : il est donc
|
||||||
possible de lancer un serveur web sans qu'il n'entre en conflit avec celui d'un
|
possible de lancer un serveur web sans qu'il n'entre en conflit avec celui d'un
|
||||||
autre espace de noms.
|
autre espace de noms.
|
||||||
|
|
||||||
|
|
@ -33,9 +33,9 @@ autre espace de noms.
|
||||||
### Premiers pas avec `ip netns`
|
### Premiers pas avec `ip netns`
|
||||||
|
|
||||||
La suite d'outils `iproute2` propose une interface simplifiée pour utiliser le
|
La suite d'outils `iproute2` propose une interface simplifiée pour utiliser le
|
||||||
*namespace* `network` : `ip netns`.
|
*namespace* `network` : `ip netns`.
|
||||||
|
|
||||||
Nous pouvons tout d'abord créer un nouvel espace de noms :
|
Nous pouvons tout d'abord créer un nouvel espace de noms :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -45,17 +45,17 @@ Nous pouvons tout d'abord créer un nouvel espace de noms :
|
||||||
|
|
||||||
La technique utilisée ici pour avoir des *namespaces* nommés est la même que
|
La technique utilisée ici pour avoir des *namespaces* nommés est la même que
|
||||||
celle que nous avons vue dans
|
celle que nous avons vue dans
|
||||||
[la première partie sur les *namespaces*](#ns-lifetime) : via un `mount --bind`
|
[la première partie sur les *namespaces*](#ns-lifetime) : via un `mount --bind`
|
||||||
dans le dossier `/var/run/netns/`. Cela permet de faire persister le namespace
|
dans le dossier `/var/run/netns/`. Cela permet de faire persister le namespace
|
||||||
malgré le fait que plus aucun processus ne s'y exécute.
|
malgré le fait que plus aucun processus ne s'y exécute.
|
||||||
|
|
||||||
Maintenant que notre *namespace* est créé, nous pouvons regarder s'il contient
|
Maintenant que notre *namespace* est créé, nous pouvons regarder s'il contient
|
||||||
des interfaces :
|
des interfaces :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
42sh# ip netns exec virli ip link
|
42sh# ip netns exec virli ip link
|
||||||
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1
|
1: lo: <LOOPBACK> mut 65536 qdisc noop state DOWN mode DEFAULT group default
|
||||||
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -64,7 +64,7 @@ Cette commande ne nous montre que l'interface de *loopback*, car nous n'avons
|
||||||
pour l'instant pas encore attaché la moindre interface.
|
pour l'instant pas encore attaché la moindre interface.
|
||||||
|
|
||||||
D'ailleurs, cette interface est rapportée comme étant désactivée, activons-là
|
D'ailleurs, cette interface est rapportée comme étant désactivée, activons-là
|
||||||
via la commande :
|
via la commande :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -92,7 +92,7 @@ interface physique par conteneur, d'autant plus si l'on a plusieurs
|
||||||
centaines de conteneurs à gérer.
|
centaines de conteneurs à gérer.
|
||||||
|
|
||||||
Une technique couramment employée consiste à créer une interface virtuelle de
|
Une technique couramment employée consiste à créer une interface virtuelle de
|
||||||
type `veth` :
|
type `veth` :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -100,16 +100,16 @@ type `veth` :
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Une interface `veth` se comporte comme un tube bidirectionnel : tout ce qui
|
Une interface `veth` se comporte comme un tube bidirectionnel : tout ce qui
|
||||||
entre d'un côté sort de l'autre et inversement. La commande précédente a donc
|
entre d'un côté sort de l'autre et inversement. La commande précédente a donc
|
||||||
créé deux interfaces `veth0` et `veth1` : les paquets envoyés sur `veth0` sont
|
créé deux interfaces `veth0` et `veth1` : les paquets envoyés sur `veth0` sont
|
||||||
donc reçus par `veth1` et les paquets envoyés à `veth1` sont reçus par `veth0`.
|
donc reçus par `veth1` et les paquets envoyés à `veth1` sont reçus par `veth0`.
|
||||||
|
|
||||||
Dans cette configuration, ces deux interfaces ne sont pas très utiles, mais si
|
Dans cette configuration, ces deux interfaces ne sont pas très utiles, mais si
|
||||||
l'on place l'une des deux extrémités dans un autre *namespace* `network`, il
|
l'on place l'une des deux extrémités dans un autre *namespace* `network`, il
|
||||||
devient alors possible de réaliser un échange de paquets entre les deux.
|
devient alors possible de réaliser un échange de paquets entre les deux.
|
||||||
|
|
||||||
Pour déplacer `veth1` dans notre *namespace* `virli` :
|
Pour déplacer `veth1` dans notre *namespace* `virli` :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -117,7 +117,7 @@ Pour déplacer `veth1` dans notre *namespace* `virli` :
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Il ne reste maintenant plus qu'à assigner une IP à chacune des interfaces :
|
Il ne reste maintenant plus qu'à assigner une IP à chacune des interfaces :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -126,7 +126,7 @@ Il ne reste maintenant plus qu'à assigner une IP à chacune des interfaces :
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Dès lors[^linkdown], nous pouvons `ping`er chaque extrêmité :
|
Dès lors[^linkdown], nous pouvons `ping`er chaque extrêmité :
|
||||||
|
|
||||||
[^linkdown]: Il peut être nécessaire d'activer chaque lien, via `ip link set
|
[^linkdown]: Il peut être nécessaire d'activer chaque lien, via `ip link set
|
||||||
vethX up`.
|
vethX up`.
|
||||||
|
|
@ -140,7 +140,7 @@ Dès lors[^linkdown], nous pouvons `ping`er chaque extrêmité :
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Il ne reste donc pas grand chose à faire pour fournir Internet à notre
|
Il ne reste donc pas grand chose à faire pour fournir Internet à notre
|
||||||
conteneur : via un peu de NAT ou grâce à un pont Ethernet.
|
conteneur : via un peu de NAT ou grâce à un pont Ethernet.
|
||||||
|
|
||||||
|
|
||||||
### Les autres types d'interfaces
|
### Les autres types d'interfaces
|
||||||
|
|
@ -171,9 +171,9 @@ derrière notre machine.
|
||||||
<!-- https://hicu.be/bridge-vs-macvlan -->
|
<!-- https://hicu.be/bridge-vs-macvlan -->
|
||||||
|
|
||||||
Lorsque l'on n'a pas assez de carte ethernet et que le switch ne supporte pas
|
Lorsque l'on n'a pas assez de carte ethernet et que le switch ne supporte pas
|
||||||
les VLAN, le noyau met à disposition un routage basé sur les adresses MAC : le
|
les VLAN, le noyau met à disposition un routage basé sur les adresses MAC : le
|
||||||
MACVLAN. S'il est activé dans votre noyau, vous allez avoir le choix entre l'un
|
MACVLAN. S'il est activé dans votre noyau, vous allez avoir le choix entre l'un
|
||||||
des quatre modes : *private*, VEPA, *bridge* ou *passthru*.
|
des quatre modes : *private*, VEPA, *bridge* ou *passthru*.
|
||||||
|
|
||||||
Quel que soit le mode choisi, les paquets en provenance d'autres machines et à
|
Quel que soit le mode choisi, les paquets en provenance d'autres machines et à
|
||||||
destination d'un MAC seront délivrés à l'interface possédant la MAC. Les
|
destination d'un MAC seront délivrés à l'interface possédant la MAC. Les
|
||||||
|
|
@ -189,7 +189,7 @@ la machine, c'est à l'équipement réseau derrière la machine de rerouter le
|
||||||
paquet vers la machine émettrice (par exemple un switch
|
paquet vers la machine émettrice (par exemple un switch
|
||||||
[802.1Qbg](http://www.ieee802.org/1/pages/802.1bg.html)).
|
[802.1Qbg](http://www.ieee802.org/1/pages/802.1bg.html)).
|
||||||
|
|
||||||
Pour construire une nouvelle interface de ce type :
|
Pour construire une nouvelle interface de ce type :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -217,11 +217,11 @@ conteneur de la même machine.
|
||||||
##### *Bridge*
|
##### *Bridge*
|
||||||
|
|
||||||
À l'inverse des modes *VEPA* et *private*, les paquets sont routés selon leur
|
À l'inverse des modes *VEPA* et *private*, les paquets sont routés selon leur
|
||||||
adresse MAC : si jamais une adresse MAC est connue, le paquet est délivré à
|
adresse MAC : si jamais une adresse MAC est connue, le paquet est délivré à
|
||||||
l'interface MACVLAN correspondante ; dans le cas contraire, le paquet est
|
l'interface MACVLAN correspondante ; dans le cas contraire, le paquet est
|
||||||
envoyé sur l'interface de sortie.
|
envoyé sur l'interface de sortie.
|
||||||
|
|
||||||
Pour construire une nouvelle interface de ce type :
|
Pour construire une nouvelle interface de ce type :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -233,9 +233,9 @@ Pour construire une nouvelle interface de ce type :
|
||||||
### Aller plus loin {-}
|
### Aller plus loin {-}
|
||||||
|
|
||||||
Pour approfondir les différentes techniques de routage, je vous
|
Pour approfondir les différentes techniques de routage, je vous
|
||||||
recommande cet article :
|
recommande cet article :
|
||||||
[Linux Containers and Networking](https://blog.flameeyes.eu/2010/09/linux-containers-and-networking).
|
[Linux Containers and Networking](https://blog.flameeyes.eu/2010/09/linux-containers-and-networking).
|
||||||
|
|
||||||
Appliqué à Docker, vous apprécierez cet article : [Understanding Docker
|
Appliqué à Docker, vous apprécierez cet article : [Understanding Docker
|
||||||
Networking Drivers and their use
|
Networking Drivers and their use
|
||||||
cases](https://www.docker.com/blog/understanding-docker-networking-drivers-use-cases/).
|
cases](https://www.docker.com/blog/understanding-docker-networking-drivers-use-cases/).
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@ pas de PID en cours de route, puisqu'il dépend du *namespace* dans lequel il se
|
||||||
trouve.
|
trouve.
|
||||||
|
|
||||||
|
|
||||||
### Isolons !
|
### Isolons !
|
||||||
|
|
||||||
Première étape s'isoler :
|
Première étape s'isoler :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -45,9 +45,9 @@ notre système initial. Pour s'en sortir, il est nécessaire de s'isoler dans un
|
||||||
*namespace* `mount` séparé.
|
*namespace* `mount` séparé.
|
||||||
|
|
||||||
|
|
||||||
#### Double isolation : ajout du *namespace* `mount`\
|
#### Double isolation : ajout du *namespace* `mount`\
|
||||||
|
|
||||||
Voici la nouvelle ligne de commande que l'on va utiliser :
|
Voici la nouvelle ligne de commande que l'on va utiliser :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -65,11 +65,11 @@ Cette fois, `top` et `ps` nous rapportent bien que l'on est seul dans notre
|
||||||
### Arborescence à l'extérieur du *namespace*
|
### Arborescence à l'extérieur du *namespace*
|
||||||
|
|
||||||
Lors de notre première tentative de `top`, lorsque `/proc` était encore monté
|
Lors de notre première tentative de `top`, lorsque `/proc` était encore monté
|
||||||
sur le `procfs` de l'espace de noms initial : notre processus (au PID 1 dans
|
sur le `procfs` de l'espace de noms initial : notre processus (au PID 1 dans
|
||||||
son nouveau *namespace*) était présent dans l'arborescence de l'espace initial
|
son nouveau *namespace*) était présent dans l'arborescence de l'espace initial
|
||||||
avec un PID dans la continuité des autres processus, étonnant !
|
avec un PID dans la continuité des autres processus, étonnant !
|
||||||
|
|
||||||
En fait, l'isolation consiste en une virtualisation des numéros du processus :
|
En fait, l'isolation consiste en une virtualisation des numéros du processus :
|
||||||
la plupart des processus du système initial ne sont pas accessibles, et ceux qui
|
la plupart des processus du système initial ne sont pas accessibles, et ceux qui
|
||||||
font partie de l'espace de noms créé disposent d'une nouvelle numérotation. Et
|
font partie de l'espace de noms créé disposent d'une nouvelle numérotation. Et
|
||||||
c'est cette nouvelle numérotation qui est montrée au processus.
|
c'est cette nouvelle numérotation qui est montrée au processus.
|
||||||
|
|
@ -85,12 +85,12 @@ Au sein d'un *namespace*, le processus au PID 1 est considéré comme le
|
||||||
programme `init`, les mêmes propriétés s'appliquent donc.
|
programme `init`, les mêmes propriétés s'appliquent donc.
|
||||||
|
|
||||||
Si un processus est orphelin, il est donc affiché comme étant fils du PID 1
|
Si un processus est orphelin, il est donc affiché comme étant fils du PID 1
|
||||||
dans son *namespace*[^PR_SET_CHILD_SUBREAPER] ; il n'est pas sorti de l'espace
|
dans son *namespace*[^PR_SET_CHILD_SUBREAPER] ; il n'est pas sorti de l'espace
|
||||||
de noms.
|
de noms.
|
||||||
|
|
||||||
[^PR_SET_CHILD_SUBREAPER]: en réalité, ce comportement est lié à la propriété
|
[^PR_SET_CHILD_SUBREAPER]: en réalité, ce comportement est lié à la propriété
|
||||||
`PR_SET_CHILD_SUBREAPER`, qui peut être définie pour n'importe quel processus
|
`PR_SET_CHILD_SUBREAPER`, qui peut être définie pour n'importe quel processus
|
||||||
de l'arborescence. Le processus au PID 1 hérite forcément de cette propriété\ ;
|
de l'arborescence. Le processus au PID 1 hérite forcément de cette propriété\ ;
|
||||||
il va donc récupérer tous les orphelins, si aucun de leurs parents n'ont la
|
il va donc récupérer tous les orphelins, si aucun de leurs parents n'ont la
|
||||||
propriété définie.
|
propriété définie.
|
||||||
|
|
||||||
|
|
@ -104,4 +104,4 @@ l'intérieur pour conserver un comportement cohérent.
|
||||||
### Aller plus loin {-}
|
### Aller plus loin {-}
|
||||||
|
|
||||||
N'hésitez pas à jeter un œil à la page de manuel consacrée à cet espace de
|
N'hésitez pas à jeter un œil à la page de manuel consacrée à cet espace de
|
||||||
noms : `pid_namespaces(7)`.
|
noms : `pid_namespaces(7)`.
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ Projet et rendu
|
||||||
notation de ce cours.**
|
notation de ce cours.**
|
||||||
|
|
||||||
Vous allez continuer aujourd'hui le projet qui s'étendra depuis le TP précédent
|
Vous allez continuer aujourd'hui le projet qui s'étendra depuis le TP précédent
|
||||||
et qui consistera à réaliser la partie d'isolation de la moulinette des ACUs !
|
et qui consistera à réaliser la partie d'isolation de la moulinette des ACUs !
|
||||||
|
|
||||||
Cette semaine, il faudra faire en sorte de restreindre un groupe de processus
|
Cette semaine, il faudra faire en sorte de restreindre un groupe de processus
|
||||||
pour qu'il s'exécute indépendemment de votre système.
|
pour qu'il s'exécute indépendemment de votre système.
|
||||||
|
|
@ -17,8 +17,8 @@ pour qu'il s'exécute indépendemment de votre système.
|
||||||
Il n'y a pas de restriction sur le langage utilisé, vous pouvez tout aussi bien
|
Il n'y a pas de restriction sur le langage utilisé, vous pouvez tout aussi bien
|
||||||
utiliser du C, du C++, du Python, du shell, etc.
|
utiliser du C, du C++, du Python, du shell, etc.
|
||||||
|
|
||||||
L'usage de bibliothèques **non relatives** au projet est autorisé : le but de
|
L'usage de bibliothèques **non relatives** au projet est autorisé : le but de
|
||||||
ce sujet est d'évaluer votre compréhension et votre utilisation de la
|
ce sujet est d'évaluer votre compréhension et votre utilisation de la
|
||||||
tuyauterie bas-niveau du noyau liée à la virtualisation légère. À partir du
|
tuyauterie bas-niveau du noyau liée à la virtualisation légère. À partir du
|
||||||
moment où vous n'utilisez pas une bibliothèque qui abstrait complètement cette
|
moment où vous n'utilisez pas une bibliothèque qui abstrait complètement cette
|
||||||
plomberie, n'hésitez pas à l'utiliser !
|
plomberie, n'hésitez pas à l'utiliser !
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
Projet et rendu
|
Projet et rendu
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Est attendu d'ici le TP suivant :
|
Est attendu d'ici le TP suivant :
|
||||||
|
|
||||||
- le rendu des exercice de ce TP ;
|
- le rendu des exercice de ce TP ;
|
||||||
- vos réponses à [l'évaluation du cours](https://virli.nemunai.re/quiz/15).
|
- vos réponses à [l'évaluation du cours](https://virli.nemunai.re/quiz/15).
|
||||||
|
|
||||||
Pour les GISTRE (et en bonus pour les SRS), [un
|
Pour les GISTRE (et en bonus pour les SRS), [un
|
||||||
|
|
@ -40,7 +40,7 @@ RAR, ...).
|
||||||
|
|
||||||
Voici une arborescence type (adaptez les extensions et les éventuels
|
Voici une arborescence type (adaptez les extensions et les éventuels
|
||||||
fichiers supplémentaires associés au langage que vous aurez choisi
|
fichiers supplémentaires associés au langage que vous aurez choisi
|
||||||
pour chaque exercice) :
|
pour chaque exercice) :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#### Exemple C\
|
#### Exemple C\
|
||||||
|
|
||||||
Voici un exemple de code C utilisant `setns(2)` :
|
Voici un exemple de code C utilisant `setns(2)` :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```c
|
```c
|
||||||
|
|
@ -38,7 +38,7 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
#### Exemple shell\
|
#### Exemple shell\
|
||||||
|
|
||||||
Dans un shell, on utilisera la commande `nsenter(1)` :
|
Dans un shell, on utilisera la commande `nsenter(1)` :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ l'autre, d'une version du noyau à l'autre, il est normal d'avoir une liste de
|
||||||
aurons les mêmes.
|
aurons les mêmes.
|
||||||
|
|
||||||
Ces fichiers sont en fait des liens symboliques un peu particuliers, car ils ne
|
Ces fichiers sont en fait des liens symboliques un peu particuliers, car ils ne
|
||||||
pointent pas vers une destination valide :
|
pointent pas vers une destination valide :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -52,7 +52,7 @@ On ne peut pas afficher tel quel les structures, mais on peut l'ouvrir avec
|
||||||
`setns(2)`.
|
`setns(2)`.
|
||||||
|
|
||||||
Pour les commandes *shell*, il convient de donner en argument le chemin vers le
|
Pour les commandes *shell*, il convient de donner en argument le chemin vers le
|
||||||
lien symbolique : la commande se chargera d'`open(2)` le fichier.
|
lien symbolique : la commande se chargera d'`open(2)` le fichier.
|
||||||
|
|
||||||
|
|
||||||
#### `*_for_children`\
|
#### `*_for_children`\
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
Pour pouvoir suivre les exercices ci-après, vous devez disposez d'un noyau
|
Pour pouvoir suivre les exercices ci-après, vous devez disposez d'un noyau
|
||||||
Linux, idéalement dans sa version 5.6 ou mieux. Il doit de plus être compilé
|
Linux, idéalement dans sa version 5.6 ou mieux. Il doit de plus être compilé
|
||||||
avec les options suivantes (lorsqu'elles sont disponibles pour votre version) :
|
avec les options suivantes (lorsqu'elles sont disponibles pour votre version) :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -28,7 +28,7 @@ Device Drivers --->
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Les variables de configuration correspondantes sont :
|
Les variables de configuration correspondantes sont :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -62,13 +62,13 @@ Nous allons utiliser des programmes issus des
|
||||||
[`procps-ng`](https://gitlab.com/procps-ng/procps) ainsi que ceux de la
|
[`procps-ng`](https://gitlab.com/procps-ng/procps) ainsi que ceux de la
|
||||||
[`libcap`](https://sites.google.com/site/fullycapable/).
|
[`libcap`](https://sites.google.com/site/fullycapable/).
|
||||||
|
|
||||||
Sous Debian et ses dérivés, ces paquets sont respectivement :
|
Sous Debian et ses dérivés, ces paquets sont respectivement :
|
||||||
|
|
||||||
* `util-linux`
|
* `util-linux`
|
||||||
* `procps`
|
* `procps`
|
||||||
* `libcap2-bin`
|
* `libcap2-bin`
|
||||||
|
|
||||||
Sous ArchLinux et ses dérivés, ces paquets sont respectivement :
|
Sous ArchLinux et ses dérivés, ces paquets sont respectivement :
|
||||||
|
|
||||||
* `util-linux`
|
* `util-linux`
|
||||||
* `procps-ng`
|
* `procps-ng`
|
||||||
|
|
@ -79,17 +79,17 @@ Sous ArchLinux et ses dérivés, ces paquets sont respectivement :
|
||||||
|
|
||||||
La sécurité du *namespace* `user` a souvent été remise en cause par le passé,
|
La sécurité du *namespace* `user` a souvent été remise en cause par le passé,
|
||||||
on lui attribue de nombreuses vulnérabilités. Vous devriez notamment consulter
|
on lui attribue de nombreuses vulnérabilités. Vous devriez notamment consulter
|
||||||
à ce sujet :
|
à ce sujet :
|
||||||
|
|
||||||
* [Security Implications of User Namespaces](https://blog.araj.me/security-implications-of-user-namespaces/) ;
|
* [Security Implications of User Namespaces](https://blog.araj.me/security-implications-of-user-namespaces/) ;
|
||||||
* [Anatomy of a user namespaces vulnerability](https://lwn.net/Articles/543273/) ;
|
* [Anatomy of a user namespaces vulnerability](https://lwn.net/Articles/543273/) ;
|
||||||
* <http://marc.info/?l=linux-kernel&m=135543612731939&w=2> ;
|
* <http://marc.info/?l=linux-kernel&m=135543612731939&w=2> ;
|
||||||
* <http://marc.info/?l=linux-kernel&m=135545831607095&w=2>.
|
* <http://marc.info/?l=linux-kernel&m=135545831607095&w=2>.
|
||||||
|
|
||||||
De nombreux projets ont choisi de ne pas autoriser l'utilisation de cet espace
|
De nombreux projets ont choisi de ne pas autoriser l'utilisation de cet espace
|
||||||
de noms sans disposer de certaines *capabilities*[^userns-caps].
|
de noms sans disposer de certaines *capabilities*[^userns-caps].
|
||||||
|
|
||||||
[^userns-caps]: Sont nécessaires, conjointement : `CAP_SYS_ADMIN`, `CAP_SETUID` et `CAP_SETGID`.
|
[^userns-caps]: Sont nécessaires, conjointement : `CAP_SYS_ADMIN`, `CAP_SETUID` et `CAP_SETGID`.
|
||||||
|
|
||||||
De nombreuses distributions ont choisi d'utiliser un paramètre du noyau pour
|
De nombreuses distributions ont choisi d'utiliser un paramètre du noyau pour
|
||||||
adapter le comportement.
|
adapter le comportement.
|
||||||
|
|
@ -99,7 +99,7 @@ adapter le comportement.
|
||||||
##### Debian et ses dérivées {.unnumbered}
|
##### Debian et ses dérivées {.unnumbered}
|
||||||
|
|
||||||
Si vous utilisez Debian ou l'un de ses dérivés, vous devrez autoriser
|
Si vous utilisez Debian ou l'un de ses dérivés, vous devrez autoriser
|
||||||
explicitement cette utilisation non-privilégiée :
|
explicitement cette utilisation non-privilégiée :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ utilisateur, on obtient les privilèges requis pour créer tous les autres types
|
||||||
de *namespaces*.
|
de *namespaces*.
|
||||||
|
|
||||||
Grâce à cette technique, il est possible de lancer des conteneurs en tant que
|
Grâce à cette technique, il est possible de lancer des conteneurs en tant que
|
||||||
simple utilisateur ; le projet [Singularity](https://sylabs.io/) repose
|
simple utilisateur ; le projet [Singularity](https://sylabs.io/) repose
|
||||||
en grande partie sur cela.
|
en grande partie sur cela.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -34,11 +34,11 @@ garder dans le nouvel espace, que les utilisateurs et les groupes utiles au
|
||||||
processus, en les renumérotant au passage si besoin.
|
processus, en les renumérotant au passage si besoin.
|
||||||
|
|
||||||
|
|
||||||
#### L'utilisateur -2 : *nobody*\
|
#### L'utilisateur -2 : *nobody*\
|
||||||
|
|
||||||
Lorsque l'on arrive dans un nouvel espace, aucun utilisateur ni groupe n'est
|
Lorsque l'on arrive dans un nouvel espace, aucun utilisateur ni groupe n'est
|
||||||
défini. Dans cette situation, tous les identifiants d'utilisateur et de groupe,
|
défini. Dans cette situation, tous les identifiants d'utilisateur et de groupe,
|
||||||
renvoyés par le noyau sont à -2 ; valeur qui correspond par convention à
|
renvoyés par le noyau sont à -2 ; valeur qui correspond par convention à
|
||||||
l'utilisateur *nobody* et au groupe *nogroup*.
|
l'utilisateur *nobody* et au groupe *nogroup*.
|
||||||
|
|
||||||
-1 étant réservé pour indiquer une erreur dans le retour d'une commande, ou la
|
-1 étant réservé pour indiquer une erreur dans le retour d'une commande, ou la
|
||||||
|
|
@ -53,7 +53,7 @@ Pour établir la correspondance, une fois que l'on a créé le nouveau
|
||||||
|
|
||||||
##### `uid_map`\
|
##### `uid_map`\
|
||||||
|
|
||||||
Sur chaque ligne, on doit indiquer :
|
Sur chaque ligne, on doit indiquer :
|
||||||
|
|
||||||
- L'identifiant marquant le début de la plage d'utilisateurs, pour le processus
|
- L'identifiant marquant le début de la plage d'utilisateurs, pour le processus
|
||||||
en question.
|
en question.
|
||||||
|
|
@ -62,7 +62,7 @@ Sur chaque ligne, on doit indiquer :
|
||||||
- La taille de la plage.
|
- La taille de la plage.
|
||||||
|
|
||||||
|
|
||||||
Par exemple, le *namespace* `user` initial défini la correspondance suivante :
|
Par exemple, le *namespace* `user` initial défini la correspondance suivante :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -75,7 +75,7 @@ Cela signifie que les utilisateurs dont l'identifiant court de 0 à `MAX_INT -
|
||||||
2` inclus, dans cet espace de noms, correspondent aux utilisateurs allant de 0 à
|
2` inclus, dans cet espace de noms, correspondent aux utilisateurs allant de 0 à
|
||||||
`MAX_INT - 1` inclus, pour le processus affichant ce fichier.
|
`MAX_INT - 1` inclus, pour le processus affichant ce fichier.
|
||||||
|
|
||||||
Lorsque l'on crée un *namespace* `user`, généralement, la correspondance vaut :
|
Lorsque l'on crée un *namespace* `user`, généralement, la correspondance vaut :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
@ -99,18 +99,18 @@ des groupes au lieu des utilisateurs.
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
42sh$ unshare --mount --pid --mount-proc --fork --net --user --map-root-user /bin/bash
|
42sh$ unshare --mount --pid --mount-proc --fork --net --user --map-root-user bash
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Un `capsh --print` nous montre que l'on est bien `root` et que l'on possède
|
Un `capsh --print` nous montre que l'on est bien `root` et que l'on possède
|
||||||
toutes les *capabilities*. Cependant, cela ne signifie pas que l'on a tous les
|
toutes les *capabilities*. Cependant, cela ne signifie pas que l'on a tous les
|
||||||
droits sur le système ; il y a plusieurs niveaux de validation qui entrent en
|
droits sur le système ; il y a plusieurs niveaux de validation qui entrent en
|
||||||
jeu. L'idée étant que l'on a été désigné root dans son conteneur, on devrait
|
jeu. L'idée étant que l'on a été désigné root dans son conteneur, on devrait
|
||||||
pouvoir y faire ce que l'on veut, tant que l'on n'agit pas en dehors.
|
pouvoir y faire ce que l'on veut, tant que l'on n'agit pas en dehors.
|
||||||
|
|
||||||
|
|
||||||
### Aller plus loin {-}
|
### Aller plus loin {-}
|
||||||
|
|
||||||
N'hésitez pas à jeter un œil à la page du manuel consacrée à ce *namespace* :
|
N'hésitez pas à jeter un œil à la page du manuel consacrée à ce *namespace* :
|
||||||
`user_namespaces(7)`.
|
`user_namespaces(7)`.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ include ../pandoc-opts.mk
|
||||||
|
|
||||||
SOURCES_SRS = tutorial-srs.md \
|
SOURCES_SRS = tutorial-srs.md \
|
||||||
../devops/devops.md \
|
../devops/devops.md \
|
||||||
../devops/what.md \
|
../devops/what-srs.md \
|
||||||
|
../devops/what-ansible.md \
|
||||||
|
../devops/what-hosts.md \
|
||||||
../devops/tools.md \
|
../devops/tools.md \
|
||||||
../devops/tools-gitea.md \
|
../devops/tools-gitea.md \
|
||||||
../devops/tools-gitea-ansible.md \
|
../devops/tools-gitea-ansible.md \
|
||||||
|
|
@ -12,6 +14,7 @@ SOURCES_SRS = tutorial-srs.md \
|
||||||
../devops/tools-drone-oauth.md \
|
../devops/tools-drone-oauth.md \
|
||||||
../devops/tools-drone-runner.md \
|
../devops/tools-drone-runner.md \
|
||||||
../devops/tools-drone-runner-ansible.md \
|
../devops/tools-drone-runner-ansible.md \
|
||||||
|
../devops/tools-drone-runner-end.md \
|
||||||
../devops/tools-end.md \
|
../devops/tools-end.md \
|
||||||
../devops/ci.md \
|
../devops/ci.md \
|
||||||
../devops/publish-docker.md \
|
../devops/publish-docker.md \
|
||||||
|
|
@ -19,6 +22,8 @@ SOURCES_SRS = tutorial-srs.md \
|
||||||
|
|
||||||
SOURCES_GISTRE = tutorial-gistre.md \
|
SOURCES_GISTRE = tutorial-gistre.md \
|
||||||
../devops/what-gistre.md \
|
../devops/what-gistre.md \
|
||||||
|
../devops/what-cmd.md \
|
||||||
|
../devops/what-hosts.md \
|
||||||
../devops/what-gistre-see-srs.md \
|
../devops/what-gistre-see-srs.md \
|
||||||
../devops/tools.md \
|
../devops/tools.md \
|
||||||
../devops/tools-gitea.md \
|
../devops/tools-gitea.md \
|
||||||
|
|
@ -29,6 +34,7 @@ SOURCES_GISTRE = tutorial-gistre.md \
|
||||||
../devops/tools-drone-oauth.md \
|
../devops/tools-drone-oauth.md \
|
||||||
../devops/tools-drone-runner.md \
|
../devops/tools-drone-runner.md \
|
||||||
../devops/tools-drone-runner-cmd.md \
|
../devops/tools-drone-runner-cmd.md \
|
||||||
|
../devops/tools-drone-runner-end.md \
|
||||||
../devops/tools-end.md \
|
../devops/tools-end.md \
|
||||||
../devops/ci-gistre.md \
|
../devops/ci-gistre.md \
|
||||||
../devops/run-gistre.md \
|
../devops/run-gistre.md \
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ Tous les fichiers identifiés comme étant à rendre pour ce TP sont à
|
||||||
placer dans une tarball (pas d'archive ZIP, RAR, ...).
|
placer dans une tarball (pas d'archive ZIP, RAR, ...).
|
||||||
|
|
||||||
Voici une arborescence type (vous pourriez avoir des fichiers
|
Voici une arborescence type (vous pourriez avoir des fichiers
|
||||||
supplémentaires) :
|
supplémentaires) :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ Tous les fichiers identifiés comme étant à rendre pour ce TP sont à
|
||||||
placer dans une tarball (pas d'archive ZIP, RAR, ...).
|
placer dans une tarball (pas d'archive ZIP, RAR, ...).
|
||||||
|
|
||||||
Voici une arborescence type (vous pourriez avoir des fichiers
|
Voici une arborescence type (vous pourriez avoir des fichiers
|
||||||
supplémentaires) :
|
supplémentaires) :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ Tous les fichiers identifiés comme étant à rendre pour ce TP sont à
|
||||||
placer dans une tarball (pas d'archive ZIP, RAR, ...).
|
placer dans une tarball (pas d'archive ZIP, RAR, ...).
|
||||||
|
|
||||||
Voici une arborescence type (vous pourriez avoir des fichiers
|
Voici une arborescence type (vous pourriez avoir des fichiers
|
||||||
supplémentaires) :
|
supplémentaires) :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
---
|
---
|
||||||
title: Virtualisation légère -- TP n^o^ 5
|
title: Virtualisation légère -- TP n^o^ 5
|
||||||
subtitle: "Application des conteneurs : tests et intégration continue"
|
subtitle: "Application des conteneurs : tests et intégration continue"
|
||||||
author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps}
|
author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps}
|
||||||
institute: EPITA
|
institute: EPITA
|
||||||
date: Jeudi 4 novembre 2021
|
date: Jeudi 4 novembre 2021
|
||||||
abstract: |
|
abstract: |
|
||||||
Durant ce nouveau TP, appréhenderons l'intégration continue et nous
|
Durant ce nouveau TP, appréhenderons l'intégration continue et nous
|
||||||
plongerons dans l'IoT pour trouver une solution innovante à des problèmes de
|
plongerons dans l'IoT pour trouver une solution innovante à des problèmes de
|
||||||
déploiement !
|
déploiement !
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ institute: EPITA
|
||||||
date: Jeudi 4 novembre 2021
|
date: Jeudi 4 novembre 2021
|
||||||
abstract: |
|
abstract: |
|
||||||
Durant ce nouveau TP, nous allons jouer les DevOps et déployer
|
Durant ce nouveau TP, nous allons jouer les DevOps et déployer
|
||||||
automatiquement des services !
|
automatiquement des services !
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ institute: EPITA
|
||||||
date: Jeudi 4 novembre 2021
|
date: Jeudi 4 novembre 2021
|
||||||
abstract: |
|
abstract: |
|
||||||
Durant ce nouveau TP, nous allons jouer les DevOps et déployer
|
Durant ce nouveau TP, nous allons jouer les DevOps et déployer
|
||||||
automatiquement des services !
|
automatiquement des services !
|
||||||
|
|
||||||
\vspace{1em}
|
\vspace{1em}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ function Div(el)
|
||||||
-- insert element in front
|
-- insert element in front
|
||||||
table.insert(
|
table.insert(
|
||||||
el.content, 1,
|
el.content, 1,
|
||||||
pandoc.RawBlock("latex", "\\begin{alertbox}"))
|
pandoc.RawBlock("latex", "\\noindent\\begin{alertbox}"))
|
||||||
-- insert element at the back
|
-- insert element at the back
|
||||||
table.insert(
|
table.insert(
|
||||||
el.content,
|
el.content,
|
||||||
|
|
@ -15,7 +15,7 @@ function Div(el)
|
||||||
-- insert element in front
|
-- insert element in front
|
||||||
table.insert(
|
table.insert(
|
||||||
el.content, 1,
|
el.content, 1,
|
||||||
pandoc.RawBlock("latex", "\\begin{codebox}"))
|
pandoc.RawBlock("latex", "\\noindent\\begin{codebox}"))
|
||||||
-- insert element at the back
|
-- insert element at the back
|
||||||
table.insert(
|
table.insert(
|
||||||
el.content,
|
el.content,
|
||||||
|
|
@ -26,7 +26,7 @@ function Div(el)
|
||||||
-- insert element in front
|
-- insert element in front
|
||||||
table.insert(
|
table.insert(
|
||||||
el.content, 1,
|
el.content, 1,
|
||||||
pandoc.RawBlock("latex", "\\begin{questionbox}"))
|
pandoc.RawBlock("latex", "\\noindent\\begin{questionbox}"))
|
||||||
-- insert element at the back
|
-- insert element at the back
|
||||||
table.insert(
|
table.insert(
|
||||||
el.content,
|
el.content,
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,4 @@
|
||||||
Déploiement
|
Déploiement
|
||||||
===========
|
===========
|
||||||
|
|
||||||
TODO il faudrait pouvoir cliquer sur le bouton pour mettre à jour l'image docker qui tourne localement ? en passant par Ansible ?
|
TODO il faudrait pouvoir cliquer sur le bouton pour mettre à jour l'image docker qui tourne localement ? en passant par Ansible ?
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,11 @@ configuration des dépôts.
|
||||||
:::::
|
:::::
|
||||||
|
|
||||||
Une fois Gitea et Drone installés et configurés, nous allons pouvoir rentrer
|
Une fois Gitea et Drone installés et configurés, nous allons pouvoir rentrer
|
||||||
dans le vif du sujet : faire de l'intégration continue sur notre premier projet !
|
dans le vif du sujet : faire de l'intégration continue sur notre premier projet !
|
||||||
|
|
||||||
### Créez un dépôt pour `linky2influx`
|
### Créez un dépôt pour `linky2influx`
|
||||||
|
|
||||||
Après avoir créé (ou migré pour les plus malins !) le dépôt
|
Après avoir créé (ou migré pour les plus malins !) le dépôt
|
||||||
[`linky2influx`](https://git.nemunai.re/nemunaire/linky2influx) dans Drone,
|
[`linky2influx`](https://git.nemunai.re/nemunaire/linky2influx) dans Drone,
|
||||||
synchronisez les dépôts, puis activez la surveillance de `linky2influx`.
|
synchronisez les dépôts, puis activez la surveillance de `linky2influx`.
|
||||||
|
|
||||||
|
|
@ -57,33 +57,33 @@ Committons puis poussons notre travail. Dès qu'il sera reçu par Gitea, nous
|
||||||
devrions voir l'interface de Drone lancer les étapes décrites dans le fichier.
|
devrions voir l'interface de Drone lancer les étapes décrites dans le fichier.
|
||||||
|
|
||||||
::::: {.warning}
|
::::: {.warning}
|
||||||
**IMPORTANT :** si vous avez l'impression que ça ne marche pas et que vous avez
|
**IMPORTANT :** si vous avez l'impression que ça ne marche pas et que vous avez
|
||||||
réutilisé le fichier présent sur le dépôt au lieu de partir de l'exemple donné
|
réutilisé le fichier présent sur le dépôt au lieu de partir de l'exemple donné
|
||||||
dans la documentation, **commencez en partant de l'exemple de la
|
dans la documentation, **commencez en partant de l'exemple de la
|
||||||
documentation** ! Le fichier présent sur le dépôt **ne fonctionnera pas** dans
|
documentation** ! Le fichier présent sur le dépôt **ne fonctionnera pas** dans
|
||||||
votre situation !
|
votre situation !
|
||||||
:::::
|
:::::
|
||||||
|
|
||||||
{height=7.5cm}
|
{height=7.5cm}
|
||||||
|
|
||||||
Lorsqu'apparaît enfin la ligne `git.nemunai.re/linky2influx`, le projet est compilé !
|
Lorsqu'apparaît enfin la ligne `git.nemunai.re/linky2influx`, le projet est compilé !
|
||||||
|
|
||||||
|
|
||||||
### Publier le binaire correspondant aux tags/jalons
|
### Publier le binaire correspondant aux tags/jalons
|
||||||
|
|
||||||
Nous savons maintenant que notre projet compile bien dans un environnement
|
Nous savons maintenant que notre projet compile bien dans un environnement
|
||||||
différent de celui du développeur ! Néanmoins, le binaire produit est perdu dès
|
différent de celui du développeur ! Néanmoins, le binaire produit est perdu dès
|
||||||
lors que la compilation est terminée, car nous n'en faisons rien.
|
lors que la compilation est terminée, car nous n'en faisons rien.
|
||||||
|
|
||||||
Ajoutons donc une nouvelle règle à notre `.droneci.yml` pour placer le binaire
|
Ajoutons donc une nouvelle règle à notre `.droneci.yml` pour placer le binaire
|
||||||
au sein de la liste des fichiers téléchargeable aux côtés des tags.
|
au sein de la liste des fichiers téléchargeable aux côtés des tags.
|
||||||
|
|
||||||
Vous aurez sans doute besoin de :
|
Vous aurez sans doute besoin de :
|
||||||
|
|
||||||
- <https://docs.drone.io/pipeline/conditions/>
|
- <https://docs.drone.io/pipeline/conditions/>
|
||||||
- <http://plugins.drone.io/drone-plugins/drone-gitea-release/>
|
- <http://plugins.drone.io/drone-plugins/drone-gitea-release/>
|
||||||
|
|
||||||
Attention à ne pas stocker votre clef d'API dans le fichier YAML !
|
Attention à ne pas stocker votre clef d'API dans le fichier YAML !
|
||||||
|
|
||||||
{height=8cm}
|
{height=8cm}
|
||||||
|
|
||||||
|
|
@ -95,16 +95,16 @@ l'interface de Drone.
|
||||||
:::::
|
:::::
|
||||||
|
|
||||||
|
|
||||||
### Publier pour plusieurs architectures ?
|
### Publier pour plusieurs architectures ?
|
||||||
|
|
||||||
Le compilateur Go est fourni avec l'ensemble des backends des différentes
|
Le compilateur Go est fourni avec l'ensemble des backends des différentes
|
||||||
architectures matérielles qu'il supporte, nous pouvons donc aisément faire de
|
architectures matérielles qu'il supporte, nous pouvons donc aisément faire de
|
||||||
la compilation croisée pour d'autres architectures.
|
la compilation croisée pour d'autres architectures.
|
||||||
|
|
||||||
Essayons maintenant de compiler `linky2influx` pour plusieurs architectures afin de
|
Essayons maintenant de compiler `linky2influx` pour plusieurs architectures afin de
|
||||||
vérifier que cela fonctionne bien !
|
vérifier que cela fonctionne bien !
|
||||||
|
|
||||||
Un exemple est donné tout en haut de cette page :
|
Un exemple est donné tout en haut de cette page :
|
||||||
<https://docs.drone.io/pipeline/environment/syntax/>.
|
<https://docs.drone.io/pipeline/environment/syntax/>.
|
||||||
|
|
||||||
En faisant varier `$GOARCH` en `mips`, `powerpc`, ... nous pouvons générer les
|
En faisant varier `$GOARCH` en `mips`, `powerpc`, ... nous pouvons générer les
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,26 @@
|
||||||
## Intégration continue
|
## Intégration continue
|
||||||
|
|
||||||
Une fois Gitea et Drone installés et configurés, nous allons pouvoir rentrer
|
Une fois Gitea et Drone installés et configurés, nous allons pouvoir rentrer
|
||||||
dans le vif du sujet : faire de l'intégration continue sur notre premier projet !
|
dans le vif du sujet : faire de l'intégration continue sur notre premier projet !
|
||||||
|
|
||||||
### Créez un dépôt pour `youp0m`
|
### Créez un dépôt pour `youp0m`
|
||||||
|
|
||||||
Reprenez les travaux réalisés au TP précédent. Nous allons notamment avoir
|
Reprenez les travaux déjà réalisés : nous allons notamment avoir besoin du
|
||||||
besoin du `Dockerfile` dans la section suivante.
|
`Dockerfile` que nous avons réalisé pour ce projet `youp0m`.
|
||||||
|
|
||||||
Après avoir créé (ou migré pour les plus malins !) le dépôt
|
Après avoir créé (ou migré pour les plus malins !) le dépôt
|
||||||
[`youp0m`](https://git.nemunai.re/nemunaire/youp0m) dans Drone,
|
`youp0m`[^urlyoup0m] dans gitea, synchronisez les dépôts dans Drone, puis
|
||||||
synchronisez les dépôts, puis activez la surveillance de `youp0m`.
|
activez la surveillance de `youp0m`.
|
||||||
|
|
||||||
Nous allons devoir rédiger un fichier `.drone.yml`, que l'on placera à la racine
|
[^urlyoup0m]: <https://git.nemunai.re/nemunaire/youp0m>
|
||||||
|
|
||||||
|
Nous allons devoir rédiger un fichier `drone.yml`, que l'on placera à la racine
|
||||||
du dépôt. C'est ce fichier qui sera traité par DroneCI pour savoir comment
|
du dépôt. C'est ce fichier qui sera traité par DroneCI pour savoir comment
|
||||||
compiler et tester le projet.
|
compiler et tester le projet.
|
||||||
|
|
||||||
::::: {.warning}
|
::::: {.warning}
|
||||||
Un fichier `.drone.yml` existe déjà à la racine du dépôt. Celui-ci pourra vous
|
Un fichier `drone.yml` existe déjà à la racine du dépôt. Celui-ci pourra vous
|
||||||
servir d'inspiration, mais il ne fonctionnera pas directement sur votre
|
servir d'inspiration, mais il ne fonctionnera pas directement dans votre
|
||||||
installation.
|
installation.
|
||||||
|
|
||||||
**Vous rencontrerez des problèmes inattendus si vous utilisez le fichier
|
**Vous rencontrerez des problèmes inattendus si vous utilisez le fichier
|
||||||
|
|
@ -32,11 +34,11 @@ documentation pour obtenir un `.drone.yml` fonctionnel.
|
||||||
### Définir les étapes d'intégration
|
### Définir les étapes d'intégration
|
||||||
|
|
||||||
Toutes les informations nécessaires à l'écriture du fichier `.drone.yml` se
|
Toutes les informations nécessaires à l'écriture du fichier `.drone.yml` se
|
||||||
trouvent dans [l'excellente documentation du
|
trouvent dans l'excellente documentation du projet :\
|
||||||
projet](https://docs.drone.io/pipeline/docker/examples/languages/golang/).
|
<https://docs.drone.io/pipeline/docker/examples/languages/golang/>.
|
||||||
|
|
||||||
Les étapes sont sensiblement les mêmes que dans le `Dockerfile` que nous avons
|
Les étapes sont sensiblement les mêmes que dans le `Dockerfile` que nous avons
|
||||||
écrit lors du TP précédent.
|
écrit précédemment.
|
||||||
|
|
||||||
Committons puis poussons notre travail. Dès qu'il sera reçu par Gitea, nous
|
Committons puis poussons notre travail. Dès qu'il sera reçu par Gitea, nous
|
||||||
devrions voir l'interface de Drone lancer les étapes décrites dans le fichier.
|
devrions voir l'interface de Drone lancer les étapes décrites dans le fichier.
|
||||||
|
|
@ -44,23 +46,22 @@ devrions voir l'interface de Drone lancer les étapes décrites dans le fichier.
|
||||||
{height=6cm}
|
{height=6cm}
|
||||||
|
|
||||||
::::: {.warning}
|
::::: {.warning}
|
||||||
**IMPORTANT :** si vous avez l'impression que ça ne marche pas et que vous avez
|
**IMPORTANT :** si vous avez l'impression que ça ne marche pas et que vous avez
|
||||||
réutilisé le fichier présent sur le dépôt au lieu de partir de l'exemple donné
|
réutilisé le fichier présent sur le dépôt au lieu de partir de l'exemple donné
|
||||||
dans la documentation, **commencez en partant de l'exemple de la
|
dans la documentation, **commencez en partant de l'exemple de la
|
||||||
documentation** ! Le fichier présent sur le dépôt **ne fonctionnera pas** dans
|
documentation** ! Le fichier présent sur le dépôt **ne fonctionnera pas** dans
|
||||||
votre situation !
|
votre situation !
|
||||||
:::::
|
:::::
|
||||||
|
|
||||||
Lorsqu'apparaît enfin la ligne `git.nemunai.re/youp0m`, le projet est compilé !
|
Lorsqu'apparaît enfin la ligne `git.nemunai.re/youp0m`, le projet est compilé !
|
||||||
|
|
||||||
|
|
||||||
### Inspection qualité
|
### Inspection qualité
|
||||||
|
|
||||||
Nous n'avons pas encore de test à proprement parler. Nous allons utiliser
|
Nous n'avons pas encore de test à proprement parler. Nous allons utiliser
|
||||||
[Sonarqube](https://www.sonarqube.org/) pour faire une revue qualité du code !
|
[Sonarqube](https://www.sonarqube.org/) pour faire une revue qualité du code !
|
||||||
|
|
||||||
Tout d'abord, il faut lancer le conteneur Sonarqube (SRS, pensez à l'ajouter à
|
Tout d'abord, il faut lancer le conteneur Sonarqube :
|
||||||
votre playbook !) :
|
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -72,7 +73,7 @@ Le service met un bon moment avant de démarrer, dès qu'il se sera initialisé,
|
||||||
nous pourrons accéder à l'interface sur <http://localhost:9000>.
|
nous pourrons accéder à l'interface sur <http://localhost:9000>.
|
||||||
|
|
||||||
En attendant qu'il démarre, nous pouvons commencer à ajouter le nécessaire à
|
En attendant qu'il démarre, nous pouvons commencer à ajouter le nécessaire à
|
||||||
notre `.drone.yml` : <http://plugins.drone.io/aosapps/drone-sonar-plugin/>.
|
notre `.drone.yml` : <http://plugins.drone.io/aosapps/drone-sonar-plugin/>.
|
||||||
|
|
||||||
Après s'être connecté à Sonarqube (`admin:admin`), nous pouvons aller générer
|
Après s'être connecté à Sonarqube (`admin:admin`), nous pouvons aller générer
|
||||||
un token, tel que décrit dans la [documentation du plugin
|
un token, tel que décrit dans la [documentation du plugin
|
||||||
|
|
@ -86,18 +87,18 @@ qui en fera une analyse minutieuse. Rendez-vous sur
|
||||||
### Publier le binaire correspondant aux tags/jalons
|
### Publier le binaire correspondant aux tags/jalons
|
||||||
|
|
||||||
Nous savons maintenant que notre projet compile bien dans un environnement
|
Nous savons maintenant que notre projet compile bien dans un environnement
|
||||||
différent de celui du développeur ! Néanmoins, le binaire produit est perdu dès
|
différent de celui du développeur ! Néanmoins, le binaire produit est perdu dès
|
||||||
lors que la compilation est terminée, car nous n'en faisons rien.
|
lors que la compilation est terminée, car nous n'en faisons rien.
|
||||||
|
|
||||||
Ajoutons donc une nouvelle règle à notre `.droneci.yml` pour placer le binaire
|
Ajoutons donc une nouvelle règle à notre `.droneci.yml` pour placer le binaire
|
||||||
au sein de la liste des fichiers téléchargeables aux côtés des tags.
|
au sein de la liste des fichiers téléchargeables aux côtés des tags.
|
||||||
|
|
||||||
Vous aurez sans doute besoin de :
|
Vous aurez sans doute besoin de :
|
||||||
|
|
||||||
- <https://docs.drone.io/pipeline/conditions/>
|
- <https://docs.drone.io/pipeline/conditions/>
|
||||||
- <http://plugins.drone.io/drone-plugins/drone-gitea-release/>
|
- <http://plugins.drone.io/drone-plugins/drone-gitea-release/>
|
||||||
|
|
||||||
Attention à ne pas stocker votre clef d'API dans le fichier YAML !
|
Attention à ne pas stocker votre clef d'API dans le fichier YAML !
|
||||||
|
|
||||||
{height=8cm}
|
{height=8cm}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@ Le mouvement DevOps
|
||||||
===================
|
===================
|
||||||
|
|
||||||
Jusqu'à récemment, et encore dans de nombreuses entreprises, les développeurs
|
Jusqu'à récemment, et encore dans de nombreuses entreprises, les développeurs
|
||||||
et les administrateurs système faisaient partie de deux équipes différentes :
|
et les administrateurs système faisaient partie de deux équipes différentes :
|
||||||
les uns développant sur leurs machines avec les dernières bibliothèques,
|
les uns développant sur leurs machines avec les dernières bibliothèques,
|
||||||
utilisant les derniers frameworks à la mode, sans se préoccuper de la sécurité
|
utilisant les derniers frameworks à la mode, sans se préoccuper de la sécurité
|
||||||
(ils travaillent en `root` ou avec `sudo` ;)), tandis que les autres tentaient
|
(ils travaillent en `root` ou avec `sudo` ;)), tandis que les autres tentaient
|
||||||
tant bien que mal de déployer ces services avec les contraintes opérationnelles
|
tant bien que mal de déployer ces services avec les contraintes opérationnelles
|
||||||
en tête.\
|
en tête.\
|
||||||
Ces contraintes : tant liées à la **sécurité** (il faut s'assurer
|
Ces contraintes : tant liées à la **sécurité** (il faut s'assurer
|
||||||
qu'un service n'utilise pas une bibliothèque vulnérable par exemple, donc soit
|
qu'un service n'utilise pas une bibliothèque vulnérable par exemple, donc soit
|
||||||
utilisé sur un système à jour, et qu'il ne tourne pas en `root`), qu'à la
|
utilisé sur un système à jour, et qu'il ne tourne pas en `root`), qu'à la
|
||||||
**disponibilité** (si le service est mal codé est contient beaucoup de fuites
|
**disponibilité** (si le service est mal codé est contient beaucoup de fuites
|
||||||
|
|
@ -19,13 +19,13 @@ pâtissent).
|
||||||
|
|
||||||
Une guerre faisait donc rage entre les développeurs qui ne comprenaient pas que
|
Une guerre faisait donc rage entre les développeurs qui ne comprenaient pas que
|
||||||
les administrateurs système ne pouvaient pas maintenir autant de versions d'une
|
les administrateurs système ne pouvaient pas maintenir autant de versions d'une
|
||||||
bibliothèque qu'il y avait de services : par exemple dans le cas de plusieurs
|
bibliothèque qu'il y avait de services : par exemple dans le cas de plusieurs
|
||||||
services en PHP, on pouvait leur demander de déployer des applications
|
services en PHP, on pouvait leur demander de déployer des applications
|
||||||
utilisant la version 5.6, et la 7.2 pour d'autres, ... lorsqu'il y avait des
|
utilisant la version 5.6, et la 7.2 pour d'autres, ... lorsqu'il y avait des
|
||||||
incompatibilités mineures et plus personne pour s'occuper de la maintenance
|
incompatibilités mineures et plus personne pour s'occuper de la maintenance
|
||||||
d'un vieux service toujours utilisé.
|
d'un vieux service toujours utilisé.
|
||||||
|
|
||||||
Le même principe est aussi valable pour Python, Ruby, ... : les développeurs
|
Le même principe est aussi valable pour Python, Ruby, ... : les développeurs
|
||||||
ont toujours eu tendance à vouloir utiliser les dernières améliorations d'un
|
ont toujours eu tendance à vouloir utiliser les dernières améliorations d'un
|
||||||
langage, mais les administrateurs système n'ont alors pas de paquets stables
|
langage, mais les administrateurs système n'ont alors pas de paquets stables
|
||||||
dans la distribution. En effet, les distributions stables telles que Debian,
|
dans la distribution. En effet, les distributions stables telles que Debian,
|
||||||
|
|
@ -64,10 +64,10 @@ charges, les pannes, ...
|
||||||
|
|
||||||
::::: {.warning}
|
::::: {.warning}
|
||||||
Attention par contre aux entreprises qui recrutent un profil DevOps, car cela a
|
Attention par contre aux entreprises qui recrutent un profil DevOps, car cela a
|
||||||
autant de sens que recruter un développeur Scrum ou un développeur cycle en V :
|
autant de sens que recruter un développeur Scrum ou un développeur cycle en V :
|
||||||
DevOps est une méthodologie. Les entreprises qui recrutent un DevOps
|
DevOps est une méthodologie. Les entreprises qui recrutent un DevOps
|
||||||
recherchent généralement quelqu'un qui fera à la fois du développement logiciel
|
recherchent généralement quelqu'un qui fera à la fois du développement logiciel
|
||||||
d'un côté et de l'administration système de l'autre : une situation
|
d'un côté et de l'administration système de l'autre : une situation
|
||||||
généralement assez difficile à vivre. Alors qu'au contraire, la mouvance DevOps
|
généralement assez difficile à vivre. Alors qu'au contraire, la mouvance DevOps
|
||||||
doit être prise au sérieux par l'ensemble des développeurs. Lors d'un entretien
|
doit être prise au sérieux par l'ensemble des développeurs. Lors d'un entretien
|
||||||
d'embauche pour ce genre de poste, assurez-vous bien de ne pas être le seul à
|
d'embauche pour ce genre de poste, assurez-vous bien de ne pas être le seul à
|
||||||
|
|
@ -77,14 +77,14 @@ faire du DevOps.
|
||||||
|
|
||||||
## Intégration continue
|
## Intégration continue
|
||||||
|
|
||||||
L'**intégration continue** est la première brique à mettre en place : le but
|
L'**intégration continue** est la première brique à mettre en place : le but
|
||||||
est de compiler automatiquement chaque commit dans un environnement proche de
|
est de compiler automatiquement chaque commit dans un environnement proche de
|
||||||
celui de production, puis de lancer les suites de tests du logiciel.
|
celui de production, puis de lancer les suites de tests du logiciel.
|
||||||
|
|
||||||
Cela permet de détecter les problèmes au plus tôt dans le cycle de
|
Cela permet de détecter les problèmes au plus tôt dans le cycle de
|
||||||
développement, mais cela permet également d'améliorer la qualité du code sur le
|
développement, mais cela permet également d'améliorer la qualité du code sur le
|
||||||
long terme, car on peut y ajouter facilement des outils qui vont se charger
|
long terme, car on peut y ajouter facilement des outils qui vont se charger
|
||||||
automatiquement de réaliser des analyses : cela peut aller de la couverture des
|
automatiquement de réaliser des analyses : cela peut aller de la couverture des
|
||||||
tests, à de l'analyse statique ou dynamique de binaire, en passant par la
|
tests, à de l'analyse statique ou dynamique de binaire, en passant par la
|
||||||
recherche de vulnérabilités ou de mauvaises pratiques de programmation.
|
recherche de vulnérabilités ou de mauvaises pratiques de programmation.
|
||||||
|
|
||||||
|
|
@ -101,7 +101,7 @@ les développeurs considéreront avoir atteint un jalon, une version stable.
|
||||||
## Déploiement continu
|
## Déploiement continu
|
||||||
|
|
||||||
Une fois tous les tests passés et les objets produits (on parle d'*artifact* ou
|
Une fois tous les tests passés et les objets produits (on parle d'*artifact* ou
|
||||||
d'*assets*), il est possible de déclencher un déploiement : il s'agit de rendre
|
d'*assets*), il est possible de déclencher un déploiement : il s'agit de rendre
|
||||||
accessible aux utilisateurs finaux le service ou les objets.
|
accessible aux utilisateurs finaux le service ou les objets.
|
||||||
|
|
||||||
Dans le cas d'un programme à télécharger
|
Dans le cas d'un programme à télécharger
|
||||||
|
|
@ -113,15 +113,15 @@ vers la dernière version (pour que les utilisateurs aient la notifications).
|
||||||
Ou bien dans le cas d'un service en ligne (GitHub, Netflix, GMail, ...), il
|
Ou bien dans le cas d'un service en ligne (GitHub, Netflix, GMail, ...), il
|
||||||
s'agira de mettre à jour le service.
|
s'agira de mettre à jour le service.
|
||||||
|
|
||||||
Parfois les deux seront à faire : à la fois publier un paquet ou un
|
Parfois les deux seront à faire : à la fois publier un paquet ou un
|
||||||
conteneur et mettre à jour un service en ligne : par exemple, [le
|
conteneur et mettre à jour un service en ligne : par exemple, [le
|
||||||
serveur Synapse](https://buildkite.com/matrix-dot-org/synapse) du
|
serveur Synapse](https://buildkite.com/matrix-dot-org/synapse) du
|
||||||
protocole de messagerie Matrix ou encore
|
protocole de messagerie Matrix ou encore
|
||||||
[Gitlab](https://gitlab.com/gitlab-org/gitlab/-/pipelines), tous deux
|
[Gitlab](https://gitlab.com/gitlab-org/gitlab/-/pipelines), tous deux
|
||||||
publient des paquets à destination de leurs communautés, et mettent à
|
publient des paquets à destination de leurs communautés, et mettent à
|
||||||
jour leur service en ligne.\
|
jour leur service en ligne.\
|
||||||
|
|
||||||
Il existe pour cela de très nombreuses stratégies : lorsque l'on n'a pas
|
Il existe pour cela de très nombreuses stratégies : lorsque l'on n'a pas
|
||||||
beaucoup de trafic ni beaucoup de machines, on peut simplement éteindre
|
beaucoup de trafic ni beaucoup de machines, on peut simplement éteindre
|
||||||
l'ancien service et démarrer le nouveau, si ça prend quelques millisecondes en
|
l'ancien service et démarrer le nouveau, si ça prend quelques millisecondes en
|
||||||
étant automatisé, cela peut être suffisant compte tenu du faible
|
étant automatisé, cela peut être suffisant compte tenu du faible
|
||||||
|
|
@ -133,11 +133,11 @@ de tout rallumer. Déjà parce que trop de visiteurs vont se retrouver avec des
|
||||||
pages d'erreur, et aussi parce qu'en cas de bug logiciel qui n'aurait pas été
|
pages d'erreur, et aussi parce qu'en cas de bug logiciel qui n'aurait pas été
|
||||||
vu malgré les étapes précédentes, cela pourrait créer une situation
|
vu malgré les étapes précédentes, cela pourrait créer une situation
|
||||||
catastrophique (imaginez qu'on ne puisse plus valider une commande sur Amazon à
|
catastrophique (imaginez qu'on ne puisse plus valider une commande sur Amazon à
|
||||||
cause d'une ligne commentée par erreur !).\
|
cause d'une ligne commentée par erreur !).\
|
||||||
On va donc privilégier un déploiement progressif de la nouvelle version (que
|
On va donc privilégier un déploiement progressif de la nouvelle version (que
|
||||||
l'on va étendre sur plusieurs minutes, heures ou mêmes jours), en éteignant
|
l'on va étendre sur plusieurs minutes, heures ou mêmes jours), en éteignant
|
||||||
tour à tour les instances, et en veillant à ce que les métriques (voir la
|
tour à tour les instances, et en veillant à ce que les métriques (voir la
|
||||||
section suivante !) soient constantes.
|
section suivante !) soient constantes.
|
||||||
|
|
||||||
|
|
||||||
## Monitoring et supervision
|
## Monitoring et supervision
|
||||||
|
|
@ -145,16 +145,16 @@ section suivante !) soient constantes.
|
||||||
Une fois déployé, le service peut avoir des ratés, alors il convient de le
|
Une fois déployé, le service peut avoir des ratés, alors il convient de le
|
||||||
surveiller afin d'être le plus proactif possible dans la résolution des
|
surveiller afin d'être le plus proactif possible dans la résolution des
|
||||||
problèmes. La pire situation est celle dans laquelle c'est un utilisateur qui
|
problèmes. La pire situation est celle dans laquelle c'est un utilisateur qui
|
||||||
nous informe d'un problème... (sur Twitter !?)
|
nous informe d'un problème... (sur Twitter !?)
|
||||||
|
|
||||||
Nous avons réalisé précédemment une partie collecte de métriques, avec nos
|
Nous avons réalisé précédemment une partie collecte de métriques, avec nos
|
||||||
conteneurs TICK. Nous n'allons donc pas nous en occuper aujourd'hui.
|
conteneurs TICK. Nous n'allons donc pas nous en occuper aujourd'hui.
|
||||||
\
|
\
|
||||||
|
|
||||||