tutorials: improve theme + use pandoc 2

This commit is contained in:
nemunaire 2018-11-16 02:38:41 +01:00
commit d25af4fdb2
65 changed files with 1283 additions and 1294 deletions

View file

@ -1,18 +1,6 @@
include ../pandoc-opts.mk
SOURCES = tutorial.md installation.md chroot.md pseudofs.md capabilities.md cgroups.md oom.md seccomp.md project-intro.md project-body.md project-rendu.md SOURCES = tutorial.md installation.md chroot.md pseudofs.md capabilities.md cgroups.md oom.md seccomp.md project-intro.md project-body.md project-rendu.md
PANDOCOPTS = --latex-engine=xelatex \
--standalone \
--normalize \
--number-sections \
--smart \
-M lang=fr-FR \
-M fontsize=12pt \
-M papersize=a4paper \
-M mainfont="Linux Libertine O" \
-M monofont="FantasqueSansMono-Regular" \
-M sansfont="Linux Biolinum O" \
-M colorlinks=true \
-M linkcolor="black" \
--include-in-header=../header.tex
all: tutorial.pdf all: tutorial.pdf

View file

@ -78,25 +78,25 @@ Sous Linux, les attributs sont regroupés dans des espaces de noms :
Par exemple, on peut définir un attribut sur un fichier comme cela : Par exemple, on peut définir un attribut sur un fichier comme cela :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh$ echo 'Hello World!' > toto 42sh$ echo 'Hello World!' > toto
42sh$ setfattr -n user.foo -v bar toto 42sh$ setfattr -n user.foo -v bar toto
42sh$ getfattr -d toto 42sh$ getfattr -d toto
# file: toto # file: toto
user.foo="bar" user.foo="bar"
``` ```
</div> </div>
Encore plus fort, vous pouvez utiliser les ACL POSIX : Encore plus fort, vous pouvez utiliser les ACL POSIX :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh$ sudo chown root:root toto && sudo chmod o-r toto 42sh$ sudo chown root:root toto && sudo chmod o-r toto
42sh$ cat toto 42sh$ cat toto
cat: toto: Permission denied cat: toto: Permission denied
42sh$ sudo setfattr -m u:$USER:r toto 42sh$ sudo setfattr -m u:$USER:r toto
42sh$ cat toto 42sh$ cat toto
Hello World! Hello World!
``` ```
</div> </div>
@ -106,10 +106,10 @@ les ACL POSIX vous autorisent à le lire.
Vous pouvez voir ces attributs avec la commande : Vous pouvez voir ces attributs avec la commande :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh$ getfattr -d -m "^system" toto 42sh$ getfattr -d -m "^system" toto
# file: toto # file: toto
system.posix_acl_access=0sgAAEAD/////AgAEOgDAEAA/////xAABAD////8= system.posix_acl_access=0sgAAEAD/////AgAEOgDAEAA/////xAABAD////8=
``` ```
</div> </div>
@ -126,19 +126,19 @@ l'utilisation de cet attribut auquel on accroîtrait l'ensemble des
Si votre distribution profite de ces attributs étendus, vous devriez obtenir : Si votre distribution profite de ces attributs étendus, vous devriez obtenir :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh$ getfattr -d -m "^security" $(which ping) 42sh$ getfattr -d -m "^security" $(which ping)
# file: bin/ping # file: bin/ping
security.capability=0sAQAAAgAgAAAAAAAAAAAAAAAAAAA= security.capability=0sAQAAAgAgAAAAAAAAAAAAAAAAAAA=
``` ```
</div> </div>
Ou, dans sa version plus lisible : Ou, dans sa version plus lisible :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh$ getcap $(which ping) 42sh$ getcap $(which ping)
/bin/ping = cap_net_raw+ep /bin/ping = cap_net_raw+ep
``` ```
</div> </div>
@ -149,39 +149,39 @@ Ou, dans sa version plus lisible :
d'un processus : d'un processus :
<div lang="en-US"> <div lang="en-US">
```shell ```
42sh$ ./view_caps 1 42sh$ ./view_caps 1
cap_user_header_t cap_user_header_t
----------------- -----------------
Version: 20080522 Version: 20080522
PID: 1 PID: 1
cap_user_data_t cap_user_data_t
--------------- ---------------
effective: 0x3fffffffff effective: 0x3fffffffff
CAP_AUDIT_CONTROL CAP_AUDIT_CONTROL
CAP_AUDIT_READ CAP_AUDIT_READ
[...] [...]
CAP_SYS_TIME CAP_SYS_TIME
CAP_SYS_TTY_CONFIG CAP_SYS_TTY_CONFIG
CAP_SYSLOG CAP_SYSLOG
CAP_WAKE_ALARM CAP_WAKE_ALARM
permitted: 0x3fffffffff permitted: 0x3fffffffff
CAP_AUDIT_CONTROL CAP_AUDIT_CONTROL
CAP_AUDIT_READ CAP_AUDIT_READ
[...] [...]
CAP_SYS_TIME CAP_SYS_TIME
CAP_SYS_TTY_CONFIG CAP_SYS_TTY_CONFIG
CAP_SYSLOG CAP_SYSLOG
CAP_WAKE_ALARM CAP_WAKE_ALARM
inheritable: 0x0 inheritable: 0x0
``` ```
</div> </div>
Astuces : `capget(2)`, X-macros, ... Astuces : `capget(2)`, X-macros, ...
## Pour aller plus loin ## Pour aller plus loin {-}
Je vous recommande la lecture des *man* suivants : Je vous recommande la lecture des *man* suivants :

View file

@ -23,9 +23,9 @@ pas de dossier `freezer` ou si celui-ci est vide, montez-le en suivant la
procédure suivante : procédure suivante :
<div lang="en-US"> <div lang="en-US">
``` ```bash
mkdir /sys/fs/cgroup/freezer/ mkdir /sys/fs/cgroup/freezer/
mount -t cgroup -o freezer none /sys/fs/cgroup/freezer/ mount -t cgroup -o freezer none /sys/fs/cgroup/freezer/
``` ```
</div> </div>
@ -42,9 +42,9 @@ Pour ce faire, il suffit de créer un nouveau dossier dans un groupe existant,
par exemple la racine : par exemple la racine :
<div lang="en-US"> <div lang="en-US">
``` ```bash
mkdir /sys/fs/cgroup/freezer/virli/ mkdir /sys/fs/cgroup/freezer/virli/
ls /sys/fs/cgroup/freezer/virli/ ls /sys/fs/cgroup/freezer/virli/
``` ```
</div> </div>
@ -64,8 +64,8 @@ La liste des processus rattachés à un *cgroup* se trouve dans le fichier `task
du groupe. Pour ajouter une tâche à ce groupe, cela se passe de cette manière : du groupe. Pour ajouter une tâche à ce groupe, cela se passe de cette manière :
<div lang="en-US"> <div lang="en-US">
``` ```bash
echo $PID > /sys/fs/cgroup/freezer/virli/tasks echo $PID > /sys/fs/cgroup/freezer/virli/tasks
``` ```
</div> </div>
@ -102,8 +102,8 @@ 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
for i in $(seq 9999); do echo -n $i; sleep .1; echo -n " - "; sleep .1; done for i in $(seq 9999); do echo -n $i; sleep .1; echo -n " - "; sleep .1; done
``` ```
</div> </div>
@ -111,8 +111,8 @@ 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
echo FROZEN > /sys/fs/cgroup/freezer/virli/freezer.state echo FROZEN > /sys/fs/cgroup/freezer/virli/freezer.state
``` ```
</div> </div>
@ -120,8 +120,8 @@ calcul à notre shell et ses fils :
l'exécution : l'exécution :
<div lang="en-US"> <div lang="en-US">
``` ```bash
echo THAWED > /sys/fs/cgroup/freezer/virli/freezer.state echo THAWED > /sys/fs/cgroup/freezer/virli/freezer.state
``` ```
</div> </div>
@ -138,8 +138,8 @@ 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">
```shell ```bash
docker container run --name mytsdb -d -p 8086:8086 influxdb docker container run --name mytsdb -d -p 8086:8086 influxdb
``` ```
</div> </div>
@ -148,11 +148,11 @@ métriques. Voici comment on s'était débrouillé dans un précédent TP pour
interagir avec InfluxDB : interagir avec InfluxDB :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
docker container exec -i mytsdb influxdb <<EOF docker container exec -i mytsdb influxdb <<EOF
CREATE DATABASE metrics; CREATE DATABASE metrics;
SHOW DATABASES; SHOW DATABASES;
EOF EOF
``` ```
</div> </div>
@ -167,19 +167,21 @@ mémoire utilisée par le groupe monitoré.
Vous pouvez utiliser un programme comme `memhog` pour remplir rapidement votre Vous pouvez utiliser un programme comme `memhog` pour remplir rapidement votre
mémoire. mémoire.
<div lang="en-US">
``` ```
42sh# mkdir /sys/fs/cgroup... 42sh# mkdir /sys/fs/cgroup...
42sh$ echo $$ | sudo tee /sys/fs/cgroup.../tasks 42sh$ echo $$ | sudo tee /sys/fs/cgroup.../tasks
42sh# ./monitor group_name memhog 500 42sh# ./monitor group_name memhog 500
~~~ 13595 ~~~ Current memory usage: 75194368/550502400 (13%) ~~~ 13595 ~~~ Current memory usage: 75194368/550502400 (13%)
~~~ 13595 ~~~ Current memory usage: 150290432/550502400 (27%) ~~~ 13595 ~~~ Current memory usage: 150290432/550502400 (27%)
~~~ 13595 ~~~ Current memory usage: 223690752/550502400 (40%) ~~~ 13595 ~~~ Current memory usage: 223690752/550502400 (40%)
~~~ 13595 ~~~ Current memory usage: 296828928/550502400 (53%) ~~~ 13595 ~~~ Current memory usage: 296828928/550502400 (53%)
~~~ 13595 ~~~ Current memory usage: 368001024/550502400 (66%) ~~~ 13595 ~~~ Current memory usage: 368001024/550502400 (66%)
~~~ 13595 ~~~ Current memory usage: 438517760/550502400 (79%) ~~~ 13595 ~~~ Current memory usage: 438517760/550502400 (79%)
~~~ 13595 ~~~ Current memory usage: 480329728/550502400 (87%) ~~~ 13595 ~~~ Current memory usage: 480329728/550502400 (87%)
~~~ 13595 ~~~ Current memory usage: 155648/550502400 (0%) ~~~ 13595 ~~~ Current memory usage: 155648/550502400 (0%)
``` ```
</div>
Si vous n'avez pas le *cgroup* *memory*, il est possible qu'il ne soit pas Si vous n'avez pas le *cgroup* *memory*, il est possible qu'il ne soit pas
activé par défaut par votre système. Si vous êtes dans ce cas, essayez activé par défaut par votre système. Si vous êtes dans ce cas, essayez
@ -192,9 +194,9 @@ Maintenant, envoyons nos données vers la base
<https://docs.influxdata.com/influxdb/v1.6/guides/writing_data/> : <https://docs.influxdata.com/influxdb/v1.6/guides/writing_data/> :
<div lang="en-US"> <div lang="en-US">
``` ```bash
curl -i -XPOST 'http://localhost:8086/write?db=metrics' --data-binary \ curl -i -XPOST 'http://localhost:8086/write?db=metrics' --data-binary \
"$my_cgroup_name memory.usage_in_bytes=$(cat .../my_cgroup_name/memory.usage_in_bytes)" "$my_cgroup_name memory.usage_in_bytes=$(cat .../my_cgroup_name/memory.usage_in_bytes)"
``` ```
</div> </div>
@ -203,7 +205,7 @@ requête suivante dans notre client `influx` :
<div lang="en-US"> <div lang="en-US">
```sql ```sql
SELECT * from "$my_cgroup_name"; SELECT * from "$my_cgroup_name";
``` ```
</div> </div>
@ -235,8 +237,8 @@ particuliers.
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ sudo ./monitor_init my_cgroup_name 42sh$ sudo ./monitor_init my_cgroup_name
42sh$ ./monitor my_cgroup_name memhog 500 42sh$ ./monitor my_cgroup_name memhog 500
``` ```
</div> </div>
@ -251,22 +253,24 @@ correspondant à une valeur limite, comme par exemple
`memory.max_usage_in_bytes`, qui limite le nombre d'octets que notre groupe de `memory.max_usage_in_bytes`, qui limite le nombre d'octets que notre groupe de
processus va pouvoir allouer au maximum : processus va pouvoir allouer au maximum :
```shell <div lang="en-US">
42sh$ cat /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
0
# 0 = Aucune limite
42sh$ echo 4M > /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
# Maintenant, la limite est à 4MB, vérifions...
42sh$ cat /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
4194304
``` ```
42sh$ cat /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
0
# 0 = Aucune limite
42sh$ echo 4M > /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
# Maintenant, la limite est à 4MB, vérifions...
42sh$ cat /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes
4194304
```
</div>
Chaque *cgroup*s défini de nombreux indicateurs et possède de nombreux Chaque *cgroup*s défini de nombreux indicateurs et possède de nombreux
limiteurs, n'hésitez pas à consulter la documentation associée à chaque limiteurs, n'hésitez pas à consulter la documentation associée à chaque
*cgroup*. *cgroup*.
## 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 ! Control groups](https://lwn.net/Articles/604609/) est excellente !

View file

@ -15,8 +15,8 @@ Pour se créer un environnement afin de changer notre racine, il va falloir
commencer par créer le dossier de notre nouvelle racine : commencer par créer le dossier de notre nouvelle racine :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
mkdir newroot mkdir newroot
``` ```
</div> </div>
@ -26,12 +26,12 @@ Queques mots, pour commencer, à propos du projet Busybox : c'est un programme
*linké* statiquement, c'est-à-dire qu'il ne va pas chercher ni charger de *linké* statiquement, c'est-à-dire qu'il ne va pas chercher ni charger de
bibliothèque dynamique à son lancement. Il se suffit donc à lui-même dans un bibliothèque dynamique à son lancement. Il se suffit donc à lui-même dans un
*chroot*, car il n'a pas de dépendances. Nous pouvons donc tester notre *chroot*, car il n'a pas de dépendances. Nous pouvons donc tester notre
première isolation : première isolation\ :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
cp $(which busybox) newroot/ cp $(which busybox) newroot/
chroot newroot /busybox ash chroot newroot /busybox ash
``` ```
</div> </div>
@ -39,10 +39,10 @@ Jusque là ... ça fonctionne, rien de surprenant ! Mais qu'en est-il pour
`bash` : `bash` :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh$ cp $(which bash) newroot/ 42sh$ cp $(which bash) newroot/
42sh# chroot newroot /bash 42sh# chroot newroot /bash
chroot: failed to run command bash: No such file or directory chroot: failed to run command bash: No such file or directory
``` ```
</div> </div>
@ -57,8 +57,8 @@ dossier correspond au point de montage de la nouvelle racine choisie par
l'utilisateur lors de l'installation) le système de base. l'utilisateur lors de l'installation) le système de base.
<div lang="en-US"> <div lang="en-US">
```shell ```bash
debootstrap jessie newroot/ http://httpredir.debian.org/debian/ debootstrap jessie newroot/ http://httpredir.debian.org/debian/
``` ```
</div> </div>
@ -68,12 +68,12 @@ l'utilisateur lors de l'installation) le système de base.
### *stage3* ### *stage3*
Les distributions *à l'ancienne* proposent encore de télécharger leur système Les distributions *à l'ancienne* proposent encore de télécharger leur système
de base sous forme de tarball : de base sous forme de tarball\ :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
wget http://gentoo.mirrors.ovh.net/gentoo-distfiles/releases/amd64/autobuilds/current-stage3-amd64/stage3-amd64-20181021T214502Z.tar.xz wget http://gentoo.mirrors.ovh.net/gentoo-distfiles/releases/amd64/autobuilds/current-stage3-amd64/stage3-amd64-20181021T214502Z.tar.xz
tar xpf stage3-amd64-*.tar.xz -C newroot/ tar xpf stage3-amd64-*.tar.xz -C newroot/
``` ```
</div> </div>
@ -81,31 +81,31 @@ L'avantage de télécharger l'archive de Gentoo est que l'on a déjà `gcc` dans
environnement qui tient dans 300 MB. environnement qui tient dans 300 MB.
## Exercice ## Exercice {-}
Écrivons maintenant un programme dont le seul but est de s'échapper du `chroot`: Écrivons maintenant un programme dont le seul but est de s'échapper du `chroot` :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
make escape make escape
echo bar > ../foo echo bar > ../foo
chroot . chroot .
``` ```
</div> </div>
Dans le nouvel environnement, vous ne devriez pas pouvoir faire : Dans le nouvel environnement, vous ne devriez pas pouvoir faire :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
cat ../foo cat ../foo
``` ```
</div> </div>
Mais une fois votre programme `escape` exécuté, vous devriez pouvoir ! Mais une fois votre programme `escape` exécuté, vous devriez pouvoir !
<div lang="en-US"> <div lang="en-US">
```shell ```
./escape (chroot) 42sh# ./escape
cat /path/to/foo bash# cat /path/to/foo
``` ```
</div> </div>

View file

@ -45,8 +45,8 @@ disponibles sur la page d'accueil de <https://kernel.org>.
Dans les sources, on affiche la liste des options avec la commande : Dans les sources, on affiche la liste des options avec la commande :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
make menuconfig make menuconfig
``` ```
</div> </div>

View file

@ -24,13 +24,13 @@ pour chaque exercice) :
<div lang="en-US"> <div lang="en-US">
``` ```
login_x-TP3/escape.c login_x-TP3/escape.c
login_x-TP3/procinfo.sh login_x-TP3/procinfo.sh
login_x-TP3/rev_kdb_leds.sh login_x-TP3/rev_kdb_leds.sh
login_x-TP3/view_caps.c login_x-TP3/view_caps.c
login_x-TP3/monitor.sh login_x-TP3/monitor.sh
login_x-TP3/monitor_init.sh login_x-TP3/monitor_init.sh
login_x-TP3/syscall_filter.c login_x-TP3/syscall_filter.c
``` ```
</div> </div>

View file

@ -16,8 +16,8 @@ montage :
<div lang="en-US"> <div lang="en-US">
``` ```
/dev/sda1 on / type ext4 (rw,relatime,data=ordered) /dev/sda1 on / type ext4 (rw,relatime,data=ordered)
/dev/sda3 on /home type ext4 (rw,relatime,data=ordered) /dev/sda3 on /home type ext4 (rw,relatime,data=ordered)
``` ```
</div> </div>
@ -61,16 +61,20 @@ exemple, pour modifier les paramètres du noyau, on passe par le fichier
La consultation d'un élément se fait généralement à l'aide d'un simple `cat` : La consultation d'un élément se fait généralement à l'aide d'un simple `cat` :
```shell <div lang="en-US">
42sh$ cat /sys/power/state
freeze mem
``` ```
42sh$ cat /sys/power/state
freeze mem
```
</div>
La modification d'un élément se fait avec `echo`, comme ceci : La modification d'un élément se fait avec `echo`, comme ceci :
```shell <div lang="en-US">
42sh# echo mem > /sys/power/state ```bash
42sh# echo mem > /sys/power/state
``` ```
</div>
Vous devriez constater l'effet de cette commande sans plus attendre ! Vous devriez constater l'effet de cette commande sans plus attendre !
@ -84,39 +88,39 @@ afficher des informations sur un processus donné :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ ./procinfo $$ 42sh$ ./procinfo $$
PID: 4242 PID: 4242
Path: /bin/bash Path: /bin/bash
Command line: bash Command line: bash
Working directory: /home/nemunaire/virli/ Working directory: /home/nemunaire/virli/
Root: / Root: /
State: S (sleeping) State: S (sleeping)
Threads: 1 Threads: 1
CGroups CGroups
======= =======
12:pids:/ 12:pids:/
11:net_prio:/ 11:net_prio:/
10:perf_event:/ 10:perf_event:/
9:net_cls:/ 9:net_cls:/
8:freezer:/ 8:freezer:/
7:devices:/ 7:devices:/
6:memory:/ 6:memory:/
5:blkio:/ 5:blkio:/
4:cpuacct:/ 4:cpuacct:/
3:cpu:/ 3:cpu:/
2:cpuset:/ 2:cpuset:/
1:name=openrc:/ 1:name=openrc:/
Namespaces Namespaces
========== ==========
cgroup:[4026531835] cgroup:[4026531835]
ipc:[4026531839] ipc:[4026531839]
mnt:[4026531840] mnt:[4026531840]
net:[4026531969] net:[4026531969]
pid:[4026531836] pid:[4026531836]
user:[4026531837] user:[4026531837]
uts:[4026531838] uts:[4026531838]
``` ```
</div> </div>
@ -147,8 +151,8 @@ Après avoir exécuté le script, nous devrions avoir :
Voici un exemple d'utilisation : Voici un exemple d'utilisation :
<div lang="en-US"> <div lang="en-US">
```shell ```
42sh$ ./rev_kdb_leds.sh input20 42sh$ ./rev_kdb_leds.sh input20
``` ```
</div> </div>
@ -158,23 +162,23 @@ Voici un exemple d'utilisation :
Voici un exemple d'utilisation : Voici un exemple d'utilisation :
<div lang="en-US"> <div lang="en-US">
```shell ```
42sh$ ./batinfo.sh 42sh$ ./batinfo.sh
BAT0 Discharging BAT0 Discharging
==== ====
Capacity: 83% (Normal) Capacity: 83% (Normal)
Voltage: 11.972000 V (minimal: 11.400000 V) Voltage: 11.972000 V (minimal: 11.400000 V)
Energy: 18.290000/21.830000 Wh Energy: 18.290000/21.830000 Wh
Power: 7.937000 W Power: 7.937000 W
Remaining time: 2.304 h Remaining time: 2.304 h
BAT1 Unknown BAT1 Unknown
==== ====
Capacity: 83% (Normal) Capacity: 83% (Normal)
Voltage: 11.972000 V (minimal: 11.400000 V) Voltage: 11.972000 V (minimal: 11.400000 V)
Energy: 18.290000/21.830000 Wh Energy: 18.290000/21.830000 Wh
Power: 0.0 W Power: 0.0 W
Remaining time: N/A Remaining time: N/A
``` ```
</div> </div>
@ -184,21 +188,21 @@ Voici un exemple d'utilisation :
Voici un exemple d'utilisation : Voici un exemple d'utilisation :
<div lang="en-US"> <div lang="en-US">
```shell ```
42sh$ ./cpuinfo.sh 42sh$ ./cpuinfo.sh
cpu0 cpu0
==== ====
Current frequency: 2100384 Hz Current frequency: 2100384 Hz
Current governor: powersave Current governor: powersave
Allowed frequencies: between 500000 - 2100000 Hz Allowed frequencies: between 500000 - 2100000 Hz
Thermal throttle count: 0 Thermal throttle count: 0
cpu1 cpu1
==== ====
Current frequency: 2099871 Hz Current frequency: 2099871 Hz
Current governor: powersave Current governor: powersave
Allowed frequencies: between 500000 - 2100000 Hz Allowed frequencies: between 500000 - 2100000 Hz
Thermal throttle count: 0 Thermal throttle count: 0
``` ```
</div> </div>

View file

@ -43,7 +43,7 @@ ce mode via :
<div lang="en-US"> <div lang="en-US">
```c ```c
prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT); prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
``` ```
</div> </div>
@ -67,25 +67,25 @@ argument de l'appel système :
<div lang="en-US"> <div lang="en-US">
```c ```c
struct sock_filter filter[]; struct sock_filter filter[];
struct sock_fprog prog = { struct sock_fprog prog = {
.len = (unsigned short) (sizeof(filter) / sizeof(filter[0])), .len = (unsigned short) (sizeof(filter) / sizeof(filter[0])),
.filter = filter, .filter = filter,
}; };
seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog); seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
``` ```
</div> </div>
### 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">
``` ```
42sh$ ./syscall_filter sleep 5 42sh$ ./syscall_filter sleep 5
sleep: cannot read realtime clock: Operation not permitted sleep: cannot read realtime clock: Operation not permitted
42sh$ 42sh$
``` ```
</div> </div>

View file

@ -1,22 +1,25 @@
--- ---
title: Virtualisation légère -- TP n^o^ 3 title: Virtualisation légère -- TP n^o^ 3
subtitle: Linux Internals partie 1 subtitle: Linux Internals partie 1
author: Pierre-Olivier *Nemunaire* Mercier author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps}
institute: EPITA institute: EPITA
date: Mercredi 24 octobre 2018 date: Mercredi 24 octobre 2018
abstract: |
Ce premier TP consacré aux Linux Internals va nous permettre
d'appréhender les notions de pseudos systèmes de fichiers, de
cgroups ainsi que de capabilities.
\vspace{1em}
Certains éléments de ce TP sont à rendre à <virli@nemunai.re> au
plus tard le mercredi 7 novembre 2018 à 12 h 42. Consultez la
dernière section de chaque partie pour plus d'information sur les
éléments à rendre.
En tant que personnes sensibilisées à la sécurité des échanges
électroniques, vous devrez m'envoyer vos rendus signés avec votre
clef PGP. Pensez à
[me](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96)
faire signer votre clef et n'hésitez pas à [faire signer votre
clef](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
... ...
Ce premier TP consacré aux Linux Internals va nous permettre d'appréhender les
notions de pseudos systèmes de fichiers, de cgroups ainsi que de capabilities.
Certains éléments de ce TP sont à rendre à <virli@nemunai.re> au plus tard le
mercredi 7 novembre 2018 à 12 h 42. Consultez la dernière section de chaque partie
pour plus d'information sur les éléments à rendre.
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
vous devrez m'envoyer vos rendus signés avec votre clef PGP. Pensez à
[me](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96) faire
signer votre clef et n'hésitez pas à
[faire signer votre clef](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
\tableofcontents

View file

@ -1,22 +1,8 @@
include ../pandoc-opts.mk
SOURCES_TUTO = tutorial.md setup.md cmpns.md docker-exec.md mountns.md rendu.md SOURCES_TUTO = tutorial.md setup.md cmpns.md docker-exec.md mountns.md rendu.md
SOURCES_LESSON = lesson.md mount.md namespaces.md networkns.md pidns.md userns.md SOURCES_LESSON = lesson.md mount.md namespaces.md networkns.md pidns.md userns.md
PANDOCOPTS = --latex-engine=xelatex \
--standalone \
--normalize \
--number-sections \
--smart \
-M lang=fr-FR \
-M fontsize=12pt \
-M papersize=a4paper \
-M mainfont="Linux Libertine O" \
-M monofont="FantasqueSansMono-Regular" \
-M sansfont="Linux Biolinum O" \
-M colorlinks=true \
-M linkcolor="black" \
-M urlcolor="[rgb]{0.2,0.6,0.4}" \
--include-in-header=../header.tex
all: lesson.pdf tutorial.pdf all: lesson.pdf tutorial.pdf

View file

@ -17,7 +17,7 @@ Exemples {.unnumbered}
-------- --------
<div lang="en-US"> <div lang="en-US">
```sh ```
42sh$ ./cmpns $(pgrep influxdb) $(pgrep init) 42sh$ ./cmpns $(pgrep influxdb) $(pgrep init)
- cgroup: differ - cgroup: differ
- ipc: differ - ipc: differ
@ -30,7 +30,7 @@ Exemples {.unnumbered}
</div> </div>
<div lang="en-US"> <div lang="en-US">
```sh ```
42sh$ ./cmpns $(pgrep init) self 42sh$ ./cmpns $(pgrep init) self
- cgroup: same - cgroup: same
- ipc: same - ipc: same
@ -47,7 +47,7 @@ Ici, `self` fait référence au processus actuellement exécuté.
Et pourquoi pas : Et pourquoi pas :
<div lang="en-US"> <div lang="en-US">
```sh ```
42sh$ unshare -m ./cmpns $$ self 42sh$ unshare -m ./cmpns $$ self
- cgroup: same - cgroup: same
- ipc: same - ipc: same

View file

@ -17,33 +17,33 @@ Pour savoir si vous avez réussi, comparez les sorties des commandes :
- ... - ...
Tests {.unnumbered} Tests {-}
----- -----
<div lang="en-US"> <div lang="en-US">
```shell ```
42sh$ docker run --name mywebserver -d -p 80:80 nginx 42sh$ docker run --name mywebserver -d -p 80:80 nginx
d63ceae863956f8312aca60b7a57fbcc1fdf679ae4c90c5d9455405005d4980a d63ceae863956f8312aca60b7a57fbcc1fdf679ae4c90c5d9455405005d4980a
42sh$ docker container inspect --format '{{ .State.Pid }}' mywebserver 42sh$ docker container inspect --format '{{ .State.Pid }}' mywebserver
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 default qlen 1
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 qdisc noqueue state UP group default
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
42sh# hostname 42sh# hostname
koala.zoo.paris koala.zoo.paris
42sh# ./mydocker_exec mywebserver hostname 42sh# ./mydocker_exec mywebserver hostname
d63ceae86395 d63ceae86395
42sh# ./mydocker_exec mywebserver mount 42sh# ./mydocker_exec mywebserver mount
42sh# ./mydocker_exec mywebserver ps aux 42sh# ./mydocker_exec mywebserver ps aux
... ...
``` ```
</div> </div>

View file

@ -1,14 +1,12 @@
--- ---
title: Virtualisation légère -- Linux Internals partie 2 title: Virtualisation légère -- Linux Internals partie 2
subtitle: Support de cours subtitle: Support de cours
author: Pierre-Olivier *nemunaire* Mercier author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps}
institute: EPITA institute: EPITA
date: Mercredi 7 novembre 2018 date: Mercredi 7 novembre 2018
abstract: |
Le but de cette seconde partie sur les mécanismes internes du noyau
va nous permettre d'utiliser les commandes et les appels systèmes
relatifs aux espaces de noms du noyau Linux ainsi que d'appréhender
la complexité des sytèmes de fichiers.
... ...
Le but de cette seconde partie sur les mécanismes internes du noyau va nous
permettre d'utiliser les commandes et les appels systèmes relatifs aux espaces
de noms du noyau Linux ainsi que d'appréhender la complexité des sytèmes de
fichiers.
\tableofcontents

View file

@ -63,8 +63,8 @@ Lorsque l'on souhaite monter à un deuxième endroit (ou plus) une partition, on
utilise le *bind mount* : utilise le *bind mount* :
<div lang="en-US"> <div lang="en-US">
``` ```bash
mount --bind olddir newdir mount --bind olddir newdir
``` ```
</div> </div>
@ -81,11 +81,11 @@ Pour que tout cela fonctionne, nous aurons besoin, au préalable, d'exécuter le
commandes suivantes : commandes suivantes :
<div lang="en-US"> <div lang="en-US">
``` ```bash
cd newroot cd newroot
mount --bind /dev dev mount --bind /dev dev
mount --bind /proc proc mount --bind /proc proc
mount --bind /sys sys mount --bind /sys sys
``` ```
</div> </div>
@ -104,11 +104,11 @@ d'accroche qu'il contient, il faut utiliser `--rbind`. Il serait donc plus
correct de lancer : correct de lancer :
<div lang="en-US"> <div lang="en-US">
``` ```bash
cd newroot cd newroot
mount --rbind /dev dev mount --rbind /dev dev
mount -t proc none proc mount -t proc none proc
mount --rbind /sys sys mount --rbind /sys sys
``` ```
</div> </div>
@ -128,15 +128,15 @@ Dans un montage partagé, une nouvelle accroche sera propagée parmi tous les
systèmes de fichiers de ce partage (on parle de *peer group*). systèmes de fichiers de ce partage (on parle de *peer group*).
<div lang="en-US"> <div lang="en-US">
```shell ```bash
# Création de notre répertoire de travail # Création de notre répertoire de travail
mkdir /mnt/test-shared mkdir /mnt/test-shared
# On s'assure que le dossier que l'on va utiliser pour nos tests utilise bien la politique shared # On s'assure que le dossier que l'on va utiliser pour nos tests utilise bien la politique shared
mount --make-shared /tmp mount --make-shared /tmp
# Duplication de l'accroche, sans s'occuper des éventuels sous-accroches # Duplication de l'accroche, sans s'occuper des éventuels sous-accroches
mount --bind /tmp /mnt/test-shared mount --bind /tmp /mnt/test-shared
``` ```
</div> </div>
@ -144,9 +144,9 @@ Si l'on attache un nouveau point de montage dans `/tmp` ou dans
`/mnt/test-shared`, avec la politique `shared`, l'accroche sera propagée : `/mnt/test-shared`, avec la politique `shared`, l'accroche sera propagée :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
mkdir /mnt/test-shared/toto mkdir /mnt/test-shared/toto
mount -t tmpfs none /mnt/test-shared/toto mount -t tmpfs none /mnt/test-shared/toto
``` ```
</div> </div>
@ -161,33 +161,33 @@ propagera, mais seulement dans un sens. Le point de montage déclaré comme
esclave ne propagera pas ses nouveaux points de montage à son *maître*. esclave ne propagera pas ses nouveaux points de montage à son *maître*.
<div lang="en-US"> <div lang="en-US">
```shell ```bash
# Suite de l'exemple précédent # Suite de l'exemple précédent
cd /mnt/test-slave cd /mnt/test-slave
# Duplication de l'accroche, sans s'occuper des éventuels sous-accroches # Duplication de l'accroche, sans s'occuper des éventuels sous-accroches
mount --bind /mnt/test-shared /mnt/test-slave mount --bind /mnt/test-shared /mnt/test-slave
# On rend notre dossier esclave # On rend notre dossier esclave
mount --make-slave /mnt/test-slave mount --make-slave /mnt/test-slave
``` ```
</div> </div>
Si l'on effectue un montage dans `/mnt/test-shared` : Si l'on effectue un montage dans `/mnt/test-shared` :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
mkdir /mnt/test-shared/foo mkdir /mnt/test-shared/foo
mount -t tmpfs none /mnt/test-shared/foo mount -t tmpfs none /mnt/test-shared/foo
``` ```
</div> </div>
Le point de montage apparaît bien sous `/mnt/test-slave/foo`. Par contre : Le point de montage apparaît bien sous `/mnt/test-slave/foo`. Par contre :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
mkdir /mnt/test-slave/bar mkdir /mnt/test-slave/bar
mount -t tmpfs none /mnt/test-slave/bar mount -t tmpfs none /mnt/test-slave/bar
``` ```
</div> </div>
@ -203,8 +203,8 @@ Pour forcer un point d'accroche à ne pas propager et à ne pas recevoir de
propagation, on utilise l'option suivante : propagation, on utilise l'option suivante :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
mount --make-private mountpoint mount --make-private mountpoint
``` ```
</div> </div>
@ -214,17 +214,17 @@ propagation, on utilise l'option suivante :
Ce mode interdira tout tentative d'attache à un autre endroit. Ce mode interdira tout tentative d'attache à un autre endroit.
<div lang="en-US"> <div lang="en-US">
```shell ```bash
mount --make-unbindable /mnt/test-slave mount --make-unbindable /mnt/test-slave
``` ```
</div> </div>
Il ne sera pas possible de faire : Il ne sera pas possible de faire :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
mkdir /mnt/test-unbindable mkdir /mnt/test-unbindable
mount --bind /mnt/test-slave /mnt/test-unbindable mount --bind /mnt/test-slave /mnt/test-unbindable
``` ```
</div> </div>
@ -236,11 +236,11 @@ existe les mêmes options pour les appliquer en cascade sur les points d'attache
contenus dans leur sous-arbre : contenus dans leur sous-arbre :
<div lang="en-US"> <div lang="en-US">
``` ```bash
mount --make-rshared mountpoint mount --make-rshared mountpoint
mount --make-rslave mountpoint mount --make-rslave mountpoint
mount --make-rprivate mountpoint mount --make-rprivate mountpoint
mount --make-runbindable mountpoint mount --make-runbindable mountpoint
``` ```
</div> </div>
@ -269,16 +269,16 @@ emplacement soient prévenu du changement.
On utilise pour cela l'option `--move` de `mount(8)` : On utilise pour cela l'option `--move` de `mount(8)` :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
mount --move olddir newdir mount --move olddir newdir
``` ```
</div> </div>
Par exemple : Par exemple :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
mount --move /dev /newroot/dev mount --move /dev /newroot/dev
``` ```
</div> </div>
@ -287,7 +287,7 @@ racine de notre système de fichiers : par exemple pour passer de l'*initramfs*
au système démarré, de notre système hôte au système d'un conteneur, ... au système démarré, de notre système hôte au système d'un conteneur, ...
## Aller plus loin ## Aller plus loin {-}
Voici quelques articles qui valent le détour, en lien avec les points de Voici quelques articles qui valent le détour, en lien avec les points de
montage : montage :

View file

@ -17,7 +17,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
@ -39,9 +39,9 @@ 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">
```shell ```bash
42sh# mkdir /mnt/newroot 42sh# mkdir /mnt/newroot
42sh# mount -t tmpfs none /mnt/newroot 42sh# mount -t tmpfs none /mnt/newroot
``` ```
</div> </div>
@ -73,8 +73,8 @@ devoir nous isoler sur :
Isolons-nous : Isolons-nous :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh# unshare -p -m -f --mount-proc 42sh# unshare -p -m -f --mount-proc
``` ```
</div> </div>
@ -89,8 +89,8 @@ Commençons donc par étiqueter tous nos points de montage (de ce *namespace*),
comme esclave : comme esclave :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh# mount --make-rslave / 42sh# mount --make-rslave /
``` ```
</div> </div>
@ -131,7 +131,7 @@ Pour lancer la première commande dans la nouvelle racine, on passe généraleme
par : par :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh# exec chroot / command 42sh# exec chroot / command
``` ```
</div> </div>

View file

@ -44,9 +44,11 @@ notre *namespace* est d'appliquer le type esclave à l'ensemble de nos points de
montage, récursivement, dès que l'on est entré dans notre nouvel espace de montage, récursivement, dès que l'on est entré dans notre nouvel espace de
noms. noms.
```shell <div lang="en-US">
mount --make-rslave / ```bash
mount --make-rslave /
``` ```
</div>
### L'espace de noms `UTS` {#uts-ns} ### L'espace de noms `UTS` {#uts-ns}
@ -148,18 +150,18 @@ 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">
```shell ```
42sh# hostname --fqdn 42sh# hostname --fqdn
koala.zoo.paris koala.zoo.paris
42sh# sudo unshare -u /bin/bash 42sh# sudo unshare -u /bin/bash
bash# hostname --fqdn bash# hostname --fqdn
koala.zoo.paris koala.zoo.paris
bash# hostname lynx.zoo.paris bash# hostname lynx.zoo.paris
bash# hostname --fqdn bash# hostname --fqdn
lynx.zoo.paris lynx.zoo.paris
bash# exit bash# exit
42sh# hostname --fqdn 42sh# hostname --fqdn
koala.zoo.paris koala.zoo.paris
``` ```
</div> </div>
@ -194,17 +196,17 @@ similaire à :
<div lang="en-US"> <div lang="en-US">
```c ```c
#include <sched.h> #include <sched.h>
#define STACKSIZE (1024*1024) #define STACKSIZE (1024*1024)
static char child_stack[STACKSIZE]; static char child_stack[STACKSIZE];
int clone_flags = CLONE_CGROUP | CLONE_NEWNET | SIGCHLD; int clone_flags = CLONE_CGROUP | CLONE_NEWNET | SIGCHLD;
pid_t pid = clone(do_execvp, pid_t pid = clone(do_execvp,
child_stack + STACKSIZE, child_stack + STACKSIZE,
clone_flags, clone_flags,
&args); &args);
``` ```
</div> </div>
@ -220,41 +222,41 @@ auquel on passe le *file descriptor* d'un des liens du dossier
<div lang="en-US"> <div lang="en-US">
```c ```c
#define _GNU_SOURCE #define _GNU_SOURCE
#include <fcntl.h> #include <fcntl.h>
#include <sched.h> #include <sched.h>
#include <stdlib.h> #include <stdlib.h>
// ./a.out /proc/PID/ns/FILE cmd args... // ./a.out /proc/PID/ns/FILE cmd args...
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int fd = open(argv[1], O_RDONLY); int fd = open(argv[1], O_RDONLY);
if (fd == -1) if (fd == -1)
{ {
perror("open"); perror("open");
return EXIT_FAILURE;
}
if (setns(fd, 0) == -1)
{
perror("setns");
return EXIT_FAILURE;
}
execvp(argv[2], &argv[2]);
perror("execve");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (setns(fd, 0) == -1)
{
perror("setns");
return EXIT_FAILURE;
}
execvp(argv[2], &argv[2]);
perror("execve");
return EXIT_FAILURE;
}
``` ```
</div> </div>
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">
```shell ```bash
42sh# nsenter --uts=/proc/42/ns/uts /bin/bash 42sh# nsenter --uts=/proc/42/ns/uts /bin/bash
``` ```
</div> </div>
@ -275,9 +277,9 @@ 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">
```shell ```bash
42sh# touch /tmp/ns/myrefns 42sh# touch /tmp/ns/myrefns
42sh# mount --bind /proc/<PID>/ns/mount /tmp/ns/myrefns 42sh# mount --bind /proc/<PID>/ns/mount /tmp/ns/myrefns
``` ```
</div> </div>
@ -296,7 +298,7 @@ Même en étant attaché à un fichier du disque, il s'agit d'un pointeur vers u
structure du noyau, qui ne persistera pas au redémarrage. structure du noyau, qui ne persistera pas au redémarrage.
## Aller plus loin ## Aller plus loin {-}
Je vous recommande la lecture des *man* suivants : Je vous recommande la lecture des *man* suivants :

View file

@ -13,10 +13,10 @@ En entrant dans un nouvel espace de nom `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">
```shell ```
42sh# unshare -n ip a 42sh# unshare -n ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1
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>
@ -38,8 +38,8 @@ La suite d'outils `iproute2` propose une interface simplifiée pour utiliser le
Nous pouvons tout d'abord créer un nouvel espace de nom : Nous pouvons tout d'abord créer un nouvel espace de nom :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh# ip netns add virli 42sh# ip netns add virli
``` ```
</div> </div>
@ -53,10 +53,10 @@ Maintenant que notre *namespace* est créé, nous pouvons regarder s'il contient
des interfaces : des interfaces :
<div lang="en-US"> <div lang="en-US">
```sh ```
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> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1
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>
@ -67,19 +67,19 @@ 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">
```shell ```bash
42sh# ip netns exec virli ip link set dev lo up 42sh# ip netns exec virli ip link set dev lo up
``` ```
</div> </div>
À ce stade, nous pouvons déjà commencer à lancer un `ping` sur cette interface: À ce stade, nous pouvons déjà commencer à lancer un `ping` sur cette interface:
<div lang="en-US"> <div lang="en-US">
```shell ```
42sh# ip netns exec virli ping 127.0.0.1 42sh# ip netns exec virli ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.038 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.038 ms
... ...
``` ```
</div> </div>
@ -96,7 +96,7 @@ type `veth` :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh# ip link add veth0 type veth peer name veth1 42sh# ip link add veth0 type veth peer name veth1
``` ```
</div> </div>
@ -112,17 +112,17 @@ 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">
```shell ```bash
42sh# ip link set veth1 netns virli 42sh# ip link set veth1 netns 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">
```shell ```bash
42sh# ip netns exec virli ip a add 10.10.10.42/24 dev veth1 42sh# ip netns exec virli ip a add 10.10.10.42/24 dev veth1
42sh# ip a add 10.10.10.41/24 dev veth0 42sh# ip a add 10.10.10.41/24 dev veth0
``` ```
</div> </div>
@ -132,10 +132,10 @@ Dès lors[^linkdown], nous pouvons `ping`er chaque extrêmité :
vethX up`. vethX up`.
<div lang="en-US"> <div lang="en-US">
```shell ```
42sh# ping 10.10.10.42 42sh# ping 10.10.10.42
- et - - et -
42sh# ip netns exec virli ping 10.10.10.41 42sh# ip netns exec virli ping 10.10.10.41
``` ```
</div> </div>
@ -158,9 +158,9 @@ supportant la technologie [802.1q](https://fr.wikipedia.org/wiki/IEEE_802.1Q).
<div lang="en-US"> <div lang="en-US">
``` ```
42sh# ip link add link eth0 name eth0.100 type vlan id 100 42sh# ip link add link eth0 name eth0.100 type vlan id 100
42sh# ip link set dev eth0.100 up 42sh# ip link set dev eth0.100 up
42sh# ip link set eth0.100 netns virli 42sh# ip link set eth0.100 netns virli
``` ```
</div> </div>
@ -192,7 +192,7 @@ Pour construire une nouvelle interface de ce type :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh# ip link add link eth0 mac0 type macvlan mode vepa 42sh# ip link add link eth0 mac0 type macvlan mode vepa
``` ```
</div> </div>
@ -208,7 +208,7 @@ conteneur de la même machine.
<div lang="en-US"> <div lang="en-US">
``` ```
42sh# ip link add link eth0 mac1 type macvlan mode private 42sh# ip link add link eth0 mac1 type macvlan mode private
``` ```
</div> </div>
@ -224,12 +224,12 @@ Pour construire une nouvelle interface de ce type :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh# ip link add link eth0 mac2 type macvlan mode bridge 42sh# ip link add link eth0 mac2 type macvlan mode bridge
``` ```
</div> </div>
## 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 :

View file

@ -23,8 +23,8 @@ trouve.
Première étape s'isoler : Première étape s'isoler :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh# unshare --pid --fork /bin/bash 42sh# unshare --pid --fork /bin/bash
``` ```
</div> </div>
@ -50,8 +50,8 @@ notre système initial. Pour s'en sortir, il est nécessaire de s'isoler du
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">
```shell ```bash
42sh# unshare --pid --mount --fork --mount-proc /bin/bash 42sh# unshare --pid --mount --fork --mount-proc /bin/bash
``` ```
</div> </div>
@ -94,7 +94,7 @@ l'extérieur du conteneur, les propriétés d'`init` sont biens appliquées à
l'intérieur pour conserver un comportement cohérent. 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é à cet espace de N'hésitez pas à jeter un œil à la page de manuel consacré à cet espace de
noms : `pid_namespaces(7)`. noms : `pid_namespaces(7)`.

View file

@ -26,7 +26,7 @@ Voici une arborescence type:
<div lang="en-US"> <div lang="en-US">
``` ```
login_x-mymoulette/README login_x-mymoulette/README
login_x-mymoulette/... login_x-mymoulette/...
``` ```
</div> </div>

View file

@ -37,8 +37,8 @@ Voici une arborescence type :
<div lang="en-US"> <div lang="en-US">
``` ```
login_x-TP4/cmpns.sh login_x-TP4/cmpns.sh
login_x-TP4/mydocker_exec.sh login_x-TP4/mydocker_exec.sh
login_x-TP4/myswitch_root.sh login_x-TP4/myswitch_root.sh
``` ```
</div> </div>

View file

@ -94,9 +94,11 @@ noyau pour adapter le comportement.
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 :
```shell <div lang="en-US">
42sh# sysctl -w kernel.unprivileged_userns_clone=1 ```bash
42sh# sysctl -w kernel.unprivileged_userns_clone=1
``` ```
</div>
### Grsecurity {.unnumbered} ### Grsecurity {.unnumbered}

View file

@ -1,22 +1,24 @@
--- ---
title: Virtualisation légère -- TP n^o^ 4 title: Virtualisation légère -- TP n^o^ 4
subtitle: Linux Internals partie 2 subtitle: Linux Internals partie 2
author: Pierre-Olivier *nemunaire* Mercier author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps}
institute: EPITA institute: EPITA
date: Mercredi 7 novembre 2018 date: Mercredi 7 novembre 2018
abstract: |
Le but de ce second TP sur les mécanismes internes du noyau va nous
permettre d'utiliser les commandes et les appels systèmes relatifs
aux *namespaces* ainsi que d'appréhender la complexité des systèmes
de fichiers.
\vspace{1em}
Tous les exercices de ce TP sont à rendre à <virli@nemunai.re> au
plus tard le mercredi 14 novembre 2017 à 12 h 42.
En tant que personnes sensibilisées à la sécurité des échanges
électroniques, vous devrez m'envoyer vos rendus signés avec votre
clef PGP. Pensez à
[me](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96)
faire signer votre clef et n'hésitez pas à [faire signer votre
clef](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
... ...
Le but de ce second TP sur les mécanismes internes du noyau va nous permettre
d'utiliser les commandes et les appels systèmes relatifs aux *namespaces* ainsi
que d'appréhender la complexité des systèmes de fichiers.
Tous les exercices de ce TP sont à rendre à <virli@nemunai.re> au plus tard le
mercredi 14 novembre 2017 à 12 h 42.
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
vous devrez m'envoyer vos rendus signés avec votre clef PGP. Pensez à
[me](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96) faire
signer votre clef et n'hésitez pas à
[faire signer votre clef](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
\tableofcontents

View file

@ -66,8 +66,8 @@ Par exemple, le *namespace* `user` initial défini la correspondance suivante :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ cat /proc/self/uid_map 42sh$ cat /proc/self/uid_map
0 0 4294967295 0 0 4294967295
``` ```
</div> </div>
@ -79,8 +79,8 @@ Lorsque l'on crée un *namespace* `user`, généralement, la correspondance vaut
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ cat /proc/self/uid_map 42sh$ cat /proc/self/uid_map
0 1000 1 0 1000 1
``` ```
</div> </div>
@ -98,8 +98,8 @@ des groupes au lieu des utilisateurs.
## Utilisation de l'espace de noms ## Utilisation de l'espace de noms
<div lang="en-US"> <div lang="en-US">
```shell ```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 /bin/bash
``` ```
</div> </div>
@ -110,7 +110,7 @@ jeu. L'idée étant que l'on a été désigné root dans son conteneur, on devra
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é à ce *namespace* : N'hésitez pas à jeter un œil à la page du manuel consacré à ce *namespace* :
`user_namespaces(7)`. `user_namespaces(7)`.

View file

@ -1,19 +1,6 @@
include ../pandoc-opts.mk
SOURCES = tutorial.md setup.md what.md manual.md compose.md security.md rendu.md SOURCES = tutorial.md setup.md what.md manual.md compose.md security.md rendu.md
PANDOCOPTS = --latex-engine=xelatex \
--standalone \
--normalize \
--number-sections \
--smart \
-M lang=fr-FR \
-M fontsize=12pt \
-M papersize=a4paper \
-M mainfont="Linux Libertine O" \
-M monofont="FantasqueSansMono-Regular" \
-M sansfont="Linux Biolinum O" \
-M colorlinks=true \
-M linkcolor="black" \
-M urlcolor="[rgb]{0.2,0.6,0.4}" \
--include-in-header=../header.tex
all: tutorial.pdf all: tutorial.pdf

View file

@ -12,19 +12,19 @@ construction).
<div lang="en-US"> <div lang="en-US">
```yaml ```yaml
version: '3' version: '3'
services: services:
influxdb: influxdb:
... ...
chronograf: chronograf:
build: grafana/ build: grafana/
image: nginx image: nginx
ports: ports:
- "3000:3000" - "3000:3000"
volumes: volumes:
- ./:/tmp/toto - ./:/tmp/toto
links: links:
- influxdb - influxdb
``` ```
</div> </div>
@ -61,9 +61,9 @@ suit :
<div lang="en-US"> <div lang="en-US">
```yaml ```yaml
volumes: volumes:
mysql-data: mysql-data:
driver: local driver: local
``` ```
</div> </div>
@ -72,11 +72,11 @@ l'emplacement à partager :
<div lang="en-US"> <div lang="en-US">
```yaml ```yaml
[...]
mysql:
[...] [...]
mysql: volumes:
[...] - mysql-data:/var/lib/mysql
volumes:
- mysql-data:/var/lib/mysql
``` ```
</div> </div>
@ -94,9 +94,9 @@ qui pourront être utilisés par les `services`. On pourrait donc avoir :
<div lang="en-US"> <div lang="en-US">
```yaml ```yaml
networks: networks:
knotdns-slave-net: knotdns-slave-net:
driver: bridge driver: bridge
``` ```
</div> </div>
@ -145,8 +145,8 @@ Une fois le build terminé, nous pouvons lancer la commande suivante et admirer
le résultat : le résultat :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
docker-compose up docker-compose up
``` ```
</div> </div>

View file

@ -26,7 +26,7 @@ allons tâcher d'utiliser ce même port pour tester localement :
<div lang="en-US"> <div lang="en-US">
``` ```
docker container run -p 8086:8086 -d --name mytsdb influxdb docker container run -p 8086:8086 -d --name mytsdb influxdb
``` ```
</div> </div>
@ -35,9 +35,9 @@ notre base de données en appelant :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ curl -f http://localhost:8086/ping 42sh$ curl -f http://localhost:8086/ping
42sh$ echo $? 42sh$ echo $?
0 0
``` ```
</div> </div>
@ -46,15 +46,15 @@ le client fourni :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ docker container run --rm -it --link mytsdb:influxdb \ 42sh$ docker container run --rm -it --link mytsdb:influxdb \
--entrypoint "/usr/bin/influx" influxdb -host influxdb > --entrypoint "/usr/bin/influx" influxdb -host influxdb
Connected to http://influxdb:8086 version 1.6.3 Connected to http://influxdb:8086 version 1.6.3
InfluxDB shell version: 1.6.3 InfluxDB shell version: 1.6.3
> show databases > show databases
name: databases name: databases
name name
--------------- ---------------
_internal _internal
``` ```
</div> </div>
@ -67,7 +67,7 @@ faut utiliser la commande `docker container logs` :
<div lang="en-US"> <div lang="en-US">
``` ```
docker container logs mytsdb docker container logs mytsdb
``` ```
</div> </div>
@ -84,18 +84,18 @@ Tentons maintenant de remplir notre base de données avec les métriques du
système. Pour cela, on commence par télécharger *Telegraf* : système. Pour cela, on commence par télécharger *Telegraf* :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
curl https://dl.influxdata.com/telegraf/releases/telegraf-1.8.1-static_linux_amd64.tar.gz | \ curl https://dl.influxdata.com/telegraf/releases/telegraf-1.8.1-static_linux_amd64.tar.gz | \
tar xzv -C /tmp tar xzv -C /tmp
``` ```
</div> </div>
Puis, lançons *Telegraf* : Puis, lançons *Telegraf* :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
cd /tmp/telegraf cd /tmp/telegraf
./telegraf --config telegraf.conf ./telegraf --config telegraf.conf
``` ```
</div> </div>
@ -107,32 +107,32 @@ rediriger le port de notre conteneur sur notre machine locale (option `-p`).
Et observons ensuite : Et observons ensuite :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
42sh$ docker container run --rm -it --link mytsdb:influxdb \ 42sh$ docker container run --rm -it --link mytsdb:influxdb \
--entrypoint "/usr/bin/influx" influxdb -host influxdb > --entrypoint "/usr/bin/influx" influxdb -host influxdb
InfluxDB shell version: 1.6.3 InfluxDB shell version: 1.6.3
> show databases > show databases
name: databases name: databases
name name
--------------- ---------------
_internal _internal
telegraf telegraf
> use telegraf > use telegraf
Using database telegraf Using database telegraf
> show measurements > show measurements
name: measurements name: measurements
name name
------------------ ------------------
cpu cpu
disk disk
diskio diskio
kernel kernel
mem mem
processes processes
swap swap
system system
``` ```
</div> </div>
@ -142,7 +142,7 @@ lancé, celui-ci va régulièrement envoyer des métriques de cette machine.
## Afficher les données collectées ## Afficher les données collectées
\hspace{2em}**Exercice :** À vous de jouer pour lancer le conteneur **Exercice :** À vous de jouer pour lancer le conteneur
[*Chronograf*](https://store.docker.com/images/chronograf). [*Chronograf*](https://store.docker.com/images/chronograf).
L'interface de *Chronograf* est disponible sur le port 8888. L'interface de *Chronograf* est disponible sur le port 8888.
@ -150,10 +150,9 @@ L'interface de *Chronograf* est disponible sur le port 8888.
Consultez la [documentation du conteneur](https://hub.docker.com/_/chronograf) Consultez la [documentation du conteneur](https://hub.docker.com/_/chronograf)
si besoin. si besoin.
*Attention :* la page d'accueil est vide au démarrage, pour savoir si vous avez **Attention :** la page d'accueil est vide au démarrage, pour savoir si vous avez
réussi, rendez-vous sous l'onglet *Hosts*, le nom de votre machine devrait y réussi, rendez-vous sous l'onglet *Hosts*, le nom de votre machine devrait y
apparaître. En cliquant dessus vous obtiendrez des graphiques similaires à ceux apparaître. En cliquant dessus vous obtiendrez des graphiques similaires à ceux
ci-dessous : ci-dessous :
![Résultat obtenu](chronograf_latest.png) ![Résultat obtenu](chronograf_latest.png)

View file

@ -11,7 +11,7 @@ monitoring, d'un simple :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ docker-compose up 42sh$ docker-compose up
``` ```
</div> </div>
@ -50,10 +50,10 @@ cela dépendra de votre avancée dans le projet) :
<div lang="en-US"> <div lang="en-US">
``` ```
login_x-TP2/ login_x-TP2/
login_x-TP2/tick/ login_x-TP2/tick/
login_x-TP2/tick/docker-compose.yml login_x-TP2/tick/docker-compose.yml
login_x-TP2/tick/... login_x-TP2/tick/...
``` ```
</div> </div>

View file

@ -104,8 +104,8 @@ On peut ensuite l'appliquer à un conteneur Docker :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ docker container run -it --security-opt seccomp=nanosleep.json ubuntu /bin/bash 42sh$ docker container run -it --security-opt seccomp=nanosleep.json ubuntu /bin/bash
(cntnr)$ sleep 42 (cntnr)$ sleep 42
sleep: cannot read realtime clock: Operation not permitted sleep: cannot read realtime clock: Operation not permitted
``` ```
</div> </div>

View file

@ -32,10 +32,10 @@ L'équipe en charge de Docker compose met à disposition un exécutable contenan
tous les scripts. Nous pouvons l'installer en suivant la procédure suivante : tous les scripts. Nous pouvons l'installer en suivant la procédure suivante :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-Linux-x86_64 \ curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-Linux-x86_64 \
> /usr/bin/docker-compose > /usr/bin/docker-compose
chmod +x /usr/bin/docker-compose chmod +x /usr/bin/docker-compose
``` ```
</div> </div>
@ -53,8 +53,8 @@ Comme avec Docker, nous pouvons vérifier le bon fonctionnement de
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ docker-compose --version 42sh$ docker-compose --version
docker-compose version: 1.16.1 docker-compose version: 1.16.1
``` ```
</div> </div>

View file

@ -1,22 +1,23 @@
--- ---
title: Virtualisation légère -- TP n^o^ 2.2 title: Virtualisation légère -- TP n^o^ 2.2
subtitle: Aller plus loin avec Docker subtitle: Aller plus loin avec Docker
author: Pierre-Olivier *Nemunaire* Mercier author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps}
institute: EPITA institute: EPITA
date: Jeudi 18 octobre 2017 date: Jeudi 18 octobre 2017
abstract: |
Dans cette deuxième partie du TP, nous allons approfondir l'utilisation de
Docker !
\vspace{1em}
Tous les éléments de ce TP (exercices et projet) sont à rendre à
<virli@nemunai.re> au plus tard le mercredi 24 octobre 2017 à 0
h 42. Consultez la dernière section de chaque partie pour plus d'information
sur les éléments à rendre.
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
vous devrez m'envoyer vos rendus signés avec votre clef PGP. Pensez à
[me](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96)
faire signer votre clef et n'hésitez pas à [faire signer votre
clef](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
... ...
Dans cette deuxième partie du TP, nous allons approfondir l'utilisation de Docker !
Tous les éléments de ce TP (exercices et projet) sont à rendre à
<virli@nemunai.re> au plus tard le mercredi 24 octobre 2017 à 0 h 42. Consultez la
dernière section de chaque partie pour plus d'information sur les éléments à
rendre.
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
vous devrez m'envoyer vos rendus signés avec votre clef PGP. Pensez à
[me](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96) faire
signer votre clef et n'hésitez pas à
[faire signer votre clef](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
\tableofcontents

View file

@ -1,19 +1,6 @@
include ../pandoc-opts.mk
SOURCES = tutorial.md installation.md what.md first.md cleaning.md ex-flask.md volumes.md linking.md rendu.md SOURCES = tutorial.md installation.md what.md first.md cleaning.md ex-flask.md volumes.md linking.md rendu.md
PANDOCOPTS = --latex-engine=xelatex \
--standalone \
--normalize \
--number-sections \
--smart \
-M lang=fr-FR \
-M fontsize=12pt \
-M papersize=a4paper \
-M mainfont="Linux Libertine O" \
-M monofont="FantasqueSansMono-Regular" \
-M sansfont="Linux Biolinum O" \
-M colorlinks=true \
-M linkcolor="black" \
-M urlcolor="[rgb]{0.2,0.6,0.4}" \
--include-in-header=../header.tex
all: tutorial.pdf all: tutorial.pdf

View file

@ -21,10 +21,10 @@ cours d'exécution, arrêtés, ...) avec la commande suivante :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ docker container ls -a 42sh$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
552d71619723 hello-world "/hello" 4 days ago Exited (0) 4 days ago dreamy_gates 552d71619723 hello-world "/hello" 4 days ago Exited (0) 4 days ago dreamy_gates
0e8bbff6d500 debian "/bin/bash" 2 weeks ago Exited (0) 2 weeks ago cranky_jones 0e8bbff6d500 debian "/bin/bash" 2 weeks ago Exited (0) 2 weeks ago cranky_jones
``` ```
</div> </div>
@ -32,16 +32,16 @@ Il y a de fortes chances pour que vous n'ayez plus besoin de ces vieux
conteneurs. Pour les supprimer, utilisez la commande : conteneurs. Pour les supprimer, utilisez la commande :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container rm 0e8bbff6d500 552d71619723 docker container rm 0e8bbff6d500 552d71619723
``` ```
</div> </div>
ou encore : ou encore :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container rm cranky_jones dreamy_gates docker container rm cranky_jones dreamy_gates
``` ```
</div> </div>
@ -62,6 +62,6 @@ une commande `prune` qui supprimera les objets inutilisés.
## `docker-gc` ## `docker-gc`
Vous pouvez également utiliser l'image <https://github.com/spotify/docker-gc> Vous pouvez également utiliser l'image
pour effectuer le ménage de manière automatique, plus fréquemment. Mais [https://github.com/spotify/docker-gc](`docker-gc`) pour effectuer le ménage de
attention à vos données ! manière automatique, plus fréquemment. Mais attention à vos données !

View file

@ -12,8 +12,8 @@ page : <https://you.p0m.fr/>.
Nous pouvons télécharger et lancer le service grâce à : Nous pouvons télécharger et lancer le service grâce à :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run -i nemunaire/youp0m docker container run -i nemunaire/youp0m
``` ```
</div> </div>
@ -35,8 +35,8 @@ interférer avec son hôte.
Nous pouvons rediriger le port avec l'argument <span lang="en-US">`-p dst_host:src_cntr`</span> : Nous pouvons rediriger le port avec l'argument <span lang="en-US">`-p dst_host:src_cntr`</span> :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run -i -p 8080:8080 nemunaire/youp0m docker container run -i -p 8080:8080 nemunaire/youp0m
``` ```
</div> </div>
@ -46,19 +46,19 @@ Pour le moment, le service ne dispose d'aucune image à afficher, vous pouvez
utiliser cette syntaxe pour ajouter une image : utiliser cette syntaxe pour ajouter une image :
<div lang="en-US"> <div lang="en-US">
``` ```bash
base64 monimage.jpg | curl --data @- http://localhost:8080/api/images/monimage base64 monimage.jpg | curl --data @- http://localhost:8080/api/images/monimage
``` ```
</div> </div>
Si vous n'êtes pas particulièrement inspiré, vous pouvez ajouter ces images : Si vous n'êtes pas particulièrement inspiré, vous pouvez ajouter ces images :
<div lang="en-US"> <div lang="en-US">
``` ```bash
wget -O- https://you.p0m.fr/images/lynx4 | base64 | curl --data @- http://localhost:8080/api/images/lynx wget -O- https://you.p0m.fr/images/lynx4 | base64 | curl --data @- http://localhost:8080/api/images/lynx
wget -O- https://you.p0m.fr/images/otters | base64 | curl --data @- http://localhost:8080/api/images/otters wget -O- https://you.p0m.fr/images/otters | base64 | curl --data @- http://localhost:8080/api/images/otters
wget -O- https://you.p0m.fr/images/DNcrZ6u | base64 | curl --data @- http://localhost:8080/api/images/DNcrZ6u wget -O- https://you.p0m.fr/images/DNcrZ6u | base64 | curl --data @- http://localhost:8080/api/images/DNcrZ6u
wget -O- https://you.p0m.fr/images/raccoons | base64 | curl --data @- http://localhost:8080/api/images/raccoons wget -O- https://you.p0m.fr/images/raccoons | base64 | curl --data @- http://localhost:8080/api/images/raccoons
``` ```
</div> </div>
@ -72,8 +72,8 @@ service ne s'exécutera pas dans notre terminal !
On utilise l'option `-d` pour lancer le conteneur en tâche de fond : On utilise l'option `-d` pour lancer le conteneur en tâche de fond :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run -d -p 8080:8080 nemunaire/youp0m docker container run -d -p 8080:8080 nemunaire/youp0m
``` ```
</div> </div>
@ -82,8 +82,8 @@ obtenir avec un `docker container ls`), nous pouvons consulter les logs du
service (en fait, les sorties standard et d'erreur) : service (en fait, les sorties standard et d'erreur) :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container logs 0123456789abcdef docker container logs 0123456789abcdef
``` ```
</div> </div>
@ -99,8 +99,8 @@ On ne peut pas utiliser le même port sur la machine hôte, mais pour le reste,
il s'agit des mêmes options : il s'agit des mêmes options :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run -d -p 8080:8081 nemunaire/youp0m docker container run -d -p 8080:8081 nemunaire/youp0m
``` ```
</div> </div>
@ -117,8 +117,8 @@ Lorsque l'on souhaite stopper un conteneur lancé en tâche de fond, on utilise
son identifiant dans la commande suivante : son identifiant dans la commande suivante :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container stop 0123456789abcdef docker container stop 0123456789abcdef
``` ```
</div> </div>

View file

@ -4,11 +4,11 @@ Mon premier conteneur
===================== =====================
Afin de tester la bonne marche de notre installation, lançons notre premier Afin de tester la bonne marche de notre installation, lançons notre premier
conteneur avec la commande : conteneur avec la commande\ :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run hello-world docker container run hello-world
``` ```
</div> </div>
@ -26,8 +26,8 @@ Nous pouvons directement utiliser le client pour rechercher une image sur le
*Store*, en utilisant la commande `search` : *Store*, en utilisant la commande `search` :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker search mariadb docker search mariadb
``` ```
</div> </div>
@ -35,8 +35,8 @@ Il est possible de mettre à jour les images locales ou simplement
pré-télécharger des images depuis le Store en utilisant la commande `pull` : pré-télécharger des images depuis le Store en utilisant la commande `pull` :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker image pull ubuntu docker image pull ubuntu
``` ```
</div> </div>
@ -59,8 +59,8 @@ Par exemple, pour consulter la liste des images dont nous disposons localement
nous-même), on utilise la commande `ls` sous le type d'objets `image` : nous-même), on utilise la commande `ls` sous le type d'objets `image` :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker image ls docker image ls
``` ```
</div> </div>
@ -88,8 +88,8 @@ lancer dans le conteneur ainsi que ses éventuels arguments. Essayons d'afficher
un Hello World : un Hello World :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run ubuntu /bin/echo "Hello World" docker container run ubuntu /bin/echo "Hello World"
``` ```
</div> </div>
@ -103,8 +103,8 @@ n'utilisez pas [Alpine Linux](https://www.alpine-linux.org), vous pourriez
tenter d'utiliser son gestionnaire de paquet `apk`, via : tenter d'utiliser son gestionnaire de paquet `apk`, via :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run alpine /sbin/apk stats docker container run alpine /sbin/apk stats
``` ```
</div> </div>
@ -139,16 +139,16 @@ du `run`. En fait, tout comme `git(1)` et ses sous-commandes, chaque niveau de
commande peut prendre des paramètres : commande peut prendre des paramètres :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker DOCKER_PARAMS container run RUN_OPTS image IMAGE_CMD IMAGE_ARGS ... docker DOCKER_PARAMS container run RUN_OPTS image IMAGE_CMD IMAGE_ARGS ...
``` ```
</div> </div>
Par exemple : Par exemple :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker -H unix:///var/run/docker.sock container run -it alpine /bin/ash -c "echo foo" docker -H unix:///var/run/docker.sock container run -it alpine /bin/ash -c "echo foo"
``` ```
</div> </div>
@ -167,10 +167,10 @@ sans quoi `bash` ne se lancera pas en mode interractif[^bashnointer].
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ cat cmd 42sh$ cat cmd
echo foo echo foo
42sh$ cat cmd | docker run -i busybox 42sh$ cat cmd | docker run -i busybox
foo foo
``` ```
</div> </div>
@ -186,9 +186,9 @@ conteneurs en cours d'exécution :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ docker container ls 42sh$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c39fc049cd1 ubuntu "/bin/bash" 6 minutes ago Up 5 minutes suspicious_galileo 4c39fc049cd1 ubuntu "/bin/bash" 6 minutes ago Up 5 minutes suspicious_galileo
``` ```
</div> </div>

View file

@ -18,7 +18,7 @@ Avant de continuer, assurez-vous que votre machine a bien démarré sur un noyau
<div lang="en-US"> <div lang="en-US">
``` ```
x86_64 x86_64
``` ```
</div> </div>
@ -26,7 +26,7 @@ Assurez-vous également d'avoir un noyau récent, avec la commande `uname -r` :
<div lang="en-US"> <div lang="en-US">
``` ```
4.18.11-gentoo 4.18.11-gentoo
``` ```
</div> </div>
@ -82,8 +82,8 @@ un bac à sable dans lequel vous pourrez commencer à faire ce TP.
Vous devriez maintenant être capable de lancer la commande suivante : Vous devriez maintenant être capable de lancer la commande suivante :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker version docker version
``` ```
</div> </div>
@ -91,24 +91,24 @@ Une sortie similaire au bloc suivant devrait apparaître sur votre écran :
<div lang="en-US"> <div lang="en-US">
``` ```
Client: Client:
Version: 18.06.1-ce Version: 18.06.1-ce
API version: 1.38 API version: 1.38
Go version: go1.10.3 Go version: go1.10.3
Git commit: e68fc7a Git commit: e68fc7a
Built: Sun Sep 9 10:14:56 2018 Built: Sun Sep 9 10:14:56 2018
OS/Arch: linux/amd64 OS/Arch: linux/amd64
Experimental: false Experimental: false
Server: Server:
Engine: Engine:
Version: 18.06.1-ce Version: 18.06.1-ce
API version: 1.38 (minimum version 1.12) API version: 1.38 (minimum version 1.12)
Go version: go1.10.3 Go version: go1.10.3
Git commit: e68fc7a Git commit: e68fc7a
Built: Sun Sep 9 10:13:21 2018 Built: Sun Sep 9 10:13:21 2018
OS/Arch: linux/amd64 OS/Arch: linux/amd64
Experimental: true Experimental: true
``` ```
</div> </div>
@ -138,8 +138,8 @@ Si vous avez cette erreur : `dial unix /var/run/docker.sock: no such file or
directory.`, le deamon n'est sans doute pas lancé. Lancez-le : directory.`, le deamon n'est sans doute pas lancé. Lancez-le :
<div lang="en-US"> <div lang="en-US">
``` ```bash
sudo service docker restart sudo service docker restart
``` ```
</div> </div>
@ -151,8 +151,8 @@ denied.`, ajoutez votre utilisateur au groupe `docker` et **relancez votre
session** : session** :
<div lang="en-US"> <div lang="en-US">
``` ```bash
sudo gpasswd -a $USER docker sudo gpasswd -a $USER docker
``` ```
</div> </div>

View file

@ -43,11 +43,11 @@ leur pilote. Pour consulter la liste de réseaux utilisables, lancez :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ docker network ls 42sh$ docker network ls
NETWORK ID NAME DRIVER SCOPE NETWORK ID NAME DRIVER SCOPE
74cedd3ff385 bridge bridge local 74cedd3ff385 bridge bridge local
d5d907add6e2 host host local d5d907add6e2 host host local
16b702ed01a0 none null local 16b702ed01a0 none null local
``` ```
</div> </div>
@ -78,8 +78,8 @@ La création d'un réseau se fait tout simplement au travers des sous-commandes
relatives aux objets Docker `network` : relatives aux objets Docker `network` :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker network create --driver bridge my_fic docker network create --driver bridge my_fic
``` ```
</div> </div>
@ -88,8 +88,8 @@ C'est ensuite ce nom de réseau que vous passerez à l'option `--network` de vos
réseau : réseau :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker network connect NETWORK CONTAINER docker network connect NETWORK CONTAINER
``` ```
</div> </div>
@ -98,7 +98,7 @@ mutuellement se découvrir grâce à un système de résolution de nom basé sur
nom de conteneur. nom de conteneur.
## Exercice ## Exercice {-}
À vous maintenant de connecter une instance de `nemunaire/fic-admin` à sa base À vous maintenant de connecter une instance de `nemunaire/fic-admin` à sa base
de données. de données.
@ -108,8 +108,8 @@ de données avec le nom d'utilisateur et le mot de passe par défaut. Vous les
obtiendrez en lisant l'aide : obtiendrez en lisant l'aide :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run --rm -e MYSQL_HOST="tcp(mysql_cntr_name:3306)" nemunaire/fic-admin -help docker container run --rm -e MYSQL_HOST="tcp(mysql_cntr_name:3306)" nemunaire/fic-admin -help
``` ```
</div> </div>
@ -126,8 +126,8 @@ utilisant :
<div lang="en-US"> <div lang="en-US">
``` ```
42sh$ docker container exec -it ficadmin_cntr_name /bin/bash 42sh$ docker container exec -it ficadmin_cntr_name /bin/bash
(incntnr)# ping mysql_cntr_name (incntnr)# ping mysql_cntr_name
``` ```
</div> </div>

View file

@ -38,13 +38,13 @@ a pu voir durant ce premier cours.
### Exemple d'exécution ### Exemple d'exécution
<div lang="en-US"> <div lang="en-US">
``` ```bash
42sh$ ./mycloud-run.sh 42sh$ ./mycloud-run.sh
http://localhost:12345/ http://localhost:12345/
42sh$ #docker kill db 42sh$ #docker kill db
42sh$ ./mycloud-run.sh # le script relancera une base de données, 42sh$ ./mycloud-run.sh # le script relancera une base de données,
# sans avoir perdu les données # sans avoir perdu les données
http://localhost:12345/ http://localhost:12345/
``` ```
</div> </div>
@ -73,8 +73,8 @@ Voici une arborescence type:
<div lang="en-US"> <div lang="en-US">
``` ```
login_x-TP1/ login_x-TP1/
login_x-TP1/mycloud-run.sh login_x-TP1/mycloud-run.sh
``` ```
</div> </div>
@ -110,12 +110,12 @@ Si vous recevez un rapport avec l'erreur suivante :
<div lang="en-US"> <div lang="en-US">
``` ```
[FAIL] Bad signature. Here is the gnupg output: [FAIL] Bad signature. Here is the gnupg output:
gpg: Signature made Tue Jan 01 16:42:23 2014 CET gpg: Signature made Tue Jan 01 16:42:23 2014 CET
gpg: using RSA key 842807A84573CC96 gpg: using RSA key 842807A84573CC96
gpg: requesting key E2CCD99DD37BD32E from hkp server pool.sks-keyservers.net gpg: requesting key E2CCD99DD37BD32E from hkp server pool.sks-keyservers.net
gpg: Can't check signature: No public key gpg: Can't check signature: No public key
``` ```
</div> </div>
@ -132,7 +132,7 @@ Si vous recevez un rapport avec l'erreur suivante :
<div lang="en-US"> <div lang="en-US">
``` ```
[FAIL] The username of your key is not explicit, I can't find you. [FAIL] The username of your key is not explicit, I can't find you.
``` ```
</div> </div>
@ -147,7 +147,7 @@ Si vous recevez un rapport concluant ainsi :
<div lang="en-US"> <div lang="en-US">
``` ```
After analyzing your e-mail, I've decided to SKIP it. After analyzing your e-mail, I've decided to SKIP it.
``` ```
</div> </div>

View file

@ -1,22 +1,23 @@
--- ---
title: Virtualisation légère -- TP n^o^ 1 title: Virtualisation légère -- TP n^o^ 1
subtitle: Les bases de Docker subtitle: Les bases de Docker
author: Pierre-Olivier *Nemunaire* Mercier author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps}
institute: EPITA institute: EPITA
date: Jeudi 4 octobre 2018 date: Jeudi 4 octobre 2018
abstract: |
Durant ce premier TP, nous allons apprendre à utiliser Docker !
\vspace{1em}
Le TP se termine par un petit projet à rendre à <virli@nemunai.re>
au plus tard le jeudi 18 octobre 2018 à 8 h 42, des questions de
cours sont également à compléter avant cette date sur
Epitaf. Consultez la dernière partie de ce TP pour les modalités.
En tant que personnes sensibilisées à la sécurité des échanges
électroniques, vous devrez m'envoyer vos rendus signés avec votre
clef PGP. Pensez à
[me](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96)
faire signer votre clef et n'hésitez pas à [faire signer la
votre](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
... ...
Durant ce premier TP, nous allons apprendre à utiliser Docker !
Le TP se termine par un petit projet à rendre à <virli@nemunai.re> au plus tard
le jeudi 18 octobre 2018 à 8 h 42, des questions de cours sont également à
compléter avant cette date sur Epitaf. Consultez la dernière partie de ce TP
pour les modalités.
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
vous devrez m'envoyer vos rendus signés avec votre clef PGP. Pensez à
[me](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96) faire
signer votre clef et n'hésitez pas à
[faire signer la votre](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
\tableofcontents

View file

@ -28,8 +28,8 @@ le protocole HTTP, mais sans se casser la tête à installer et configurer un
serveur web : serveur web :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run --rm -p 80:80 -v ~/Downloads:/usr/share/nginx/html:ro -d nginx docker container run --rm -p 80:80 -v ~/Downloads:/usr/share/nginx/html:ro -d nginx
``` ```
</div> </div>
@ -48,26 +48,26 @@ Comme il s'agit d'un objet, la première chose à faire va être de créer notre
volume : volume :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker volume create prod_youp0m docker volume create prod_youp0m
docker volume create prod_foodp0m docker volume create prod_foodp0m
``` ```
</div> </div>
Ensuite, nous pouvons démarrer un conteneur utilisant, par exemple : Ensuite, nous pouvons démarrer un conteneur utilisant, par exemple :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run --mount source=prod_youp0m,target=/srv/images nemunaire/youp0m docker container run --mount source=prod_youp0m,target=/srv/images nemunaire/youp0m
``` ```
</div> </div>
On pourra également faire de même avec un conteneur MySQL : On pourra également faire de même avec un conteneur MySQL :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run --name mydb --mount source=prod_db,target=/var/lib/mysql \ docker container run --name mydb --mount source=prod_db,target=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=my-secret-pw mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql
``` ```
</div> </div>
@ -78,8 +78,8 @@ Si plus tard, vous souhaitez créer un conteneur chargé de faire des
sauvegardes, vous pourriez le lancer comme ceci : sauvegardes, vous pourriez le lancer comme ceci :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run -it --volume-from mydb busybox /bin/bash docker container run -it --volume-from mydb busybox /bin/bash
``` ```
</div> </div>
@ -90,11 +90,11 @@ Lorsque vous n'avez pas besoin de stocker les données et que vous ne désirez
pas qu'elles persistent (des données sensibles par exemple) ou si cela peut pas qu'elles persistent (des données sensibles par exemple) ou si cela peut
améliorer les performances de votre conteneur, il est possible de créer des améliorer les performances de votre conteneur, il est possible de créer des
points de montages utilisant le système de fichiers `tmpfs` et donc résidant points de montages utilisant le système de fichiers `tmpfs` et donc résidant
exclusivement en RAM : exclusivement en RAM\ :
<div lang="en-US"> <div lang="en-US">
``` ```bash
docker container run --mount type=tmpfs,target=/srv/images nemunaire/youp0m docker container run --mount type=tmpfs,target=/srv/images nemunaire/youp0m
``` ```
</div> </div>

View file

@ -1,19 +1,6 @@
include ../pandoc-opts.mk
SOURCES = tutorial.md clair.md oci.md registry.md runc.md linuxkit.md rendu.md SOURCES = tutorial.md clair.md oci.md registry.md runc.md linuxkit.md rendu.md
PANDOCOPTS = --latex-engine=xelatex \
--standalone \
--normalize \
--number-sections \
--smart \
-M lang=fr-FR \
-M fontsize=12pt \
-M papersize=a4paper \
-M mainfont="Linux Libertine O" \
-M monofont="FantasqueSansMono-Regular" \
-M sansfont="Linux Biolinum O" \
-M colorlinks=true \
-M linkcolor="black" \
-M urlcolor="[rgb]{0.2,0.6,0.4}" \
--include-in-header=../header.tex
all: tutorial.pdf all: tutorial.pdf

View file

@ -1,7 +1,7 @@
\newpage \newpage
Une vision plus Clair de la sécurité ? Une vision plus Clair de la sécurité
====================================== ====================================
Nous avons vu, au travers de tous les précédents TP, que Docker nous apportait Nous avons vu, au travers de tous les précédents TP, que Docker nous apportait
un certain degré de sécurité d'emblée au lancement du conteneur. Cela peut sans un certain degré de sécurité d'emblée au lancement du conteneur. Cela peut sans
@ -86,9 +86,9 @@ Une fois lancé, la base nécessite d'être initialisée. L'opération peut pren
plusieurs minutes. Vous pouvez suivre l'avancement de l'ajout : plusieurs minutes. Vous pouvez suivre l'avancement de l'ajout :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
curl http://localhost:6060/v1/namespaces curl http://localhost:6060/v1/namespaces
curl http://localhost:6060/v1/namespaces/debian:9/vulnerabilities?limit=10 curl http://localhost:6060/v1/namespaces/debian:9/vulnerabilities?limit=10
``` ```
</div> </div>
@ -100,8 +100,8 @@ conteneur, nous allons utiliser le programme
[`paclair`](https://github.com/yebinama/paclair) : [`paclair`](https://github.com/yebinama/paclair) :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
pip3 install paclair pip3 install paclair
``` ```
</div> </div>
@ -109,11 +109,11 @@ Il nécessite un fichier de configuration pour être utilisé, essayez :
<div lang="en-US"> <div lang="en-US">
```yml ```yml
General: General:
clair_url: 'http://localhost:6060' clair_url: 'http://localhost:6060'
Plugins: Plugins:
Docker: Docker:
class: paclair.plugins.docker_plugin.DockerPlugin class: paclair.plugins.docker_plugin.DockerPlugin
``` ```
</div> </div>
@ -121,33 +121,33 @@ Pour obtenir un rapport d'analyse, on commence par envoyer les couches de
l'image à `Clair` : l'image à `Clair` :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
paclair --conf conf.yml Docker nemunaire/fic-admin push paclair --conf conf.yml Docker nemunaire/fic-admin push
``` ```
</div> </div>
Puis on lui demande la génération d'un rapport `html` : Puis on lui demande la génération d'un rapport `html` :
<div lang="en-US"> <div lang="en-US">
```shell ```bash
paclair --conf conf.yml Docker nemunaire/fic-admin analyse --output-format html --output-report file paclair --conf conf.yml Docker nemunaire/fic-admin analyse --output-format html --output-report file
``` ```
</div> </div>
Si l'on souhaite uniquement avoir des statisti