tuto4 ready
This commit is contained in:
parent
b5de41662b
commit
e928733d61
17 changed files with 789 additions and 203 deletions
|
|
@ -1,28 +1,27 @@
|
|||
\newpage
|
||||
|
||||
Utiliser les *namespace*s
|
||||
-------------------------
|
||||
|
||||
### S'isoler dans un nouveau *namespace*
|
||||
|
||||
Si l'on voit l'isolation procurée par les *namespace*s en parallèle avec les
|
||||
machines virtuelles, on peut se dire qu'il suffit d'exécuter un appel système
|
||||
pour arriver dans un conteneur bien isolé. Cependant, le choix fait par les
|
||||
développeurs de Linux a été de laisser le choix des espaces de noms dont on veut
|
||||
se dissocier.
|
||||
Si l'on voit l'isolation procurée par les *namespace*s comme des machines
|
||||
virtuelles, on peut se dire qu'il suffit d'exécuter un appel système pour
|
||||
arriver dans un conteneur bien isolé. Cependant, le choix fait par les
|
||||
développeurs de Linux a été de laisser le choix des espaces de noms dont on
|
||||
veut se dissocier.
|
||||
|
||||
L'intérêt principal de cette approche, exploitée bien après la mise en avant du
|
||||
concept, est que l'utilisation des *namespace*s ne se limite pas seulement à
|
||||
des machines virtuelles légères. On retrouve ainsi dans Google Chrome de
|
||||
nombreuses utilisations des *namespace*s dans le simple but d'accroître la
|
||||
sécurité de leur navigateur. Ainsi, les threads de rendu n'ont pas accès au
|
||||
réseau et sont cloisonnés de manière transparente pour l'utilisateur.
|
||||
des machines virtuelles légères. On retrouve ainsi dans Google Chrome et
|
||||
Firefox de nombreuses utilisations des *namespace*s dans le simple but
|
||||
d'accroître la sécurité de leur navigateur. Ainsi, les *threads* de rendu n'ont
|
||||
pas accès au réseau et sont cloisonnés de manière transparente pour
|
||||
l'utilisateur.
|
||||
|
||||
Nous allons voir dans cette partie plusieurs méthodes pour utiliser ces espaces
|
||||
de noms.
|
||||
|
||||
|
||||
#### Dans son shell
|
||||
#### Dans son shell\
|
||||
|
||||
De la même manière que l'on peut utiliser l'appel système `chroot(2)` depuis un
|
||||
shell via la commande `chroot(1)`, la commande `unshare(1)` permet de faire le
|
||||
|
|
@ -55,16 +54,16 @@ Nous avons pu ici modifier le nom de la machine, sans que cela n'affecte notre
|
|||
machine hôte.
|
||||
|
||||
|
||||
#### Les appels système
|
||||
#### Les appels système\
|
||||
|
||||
L'appel système par excellence pour contrôler l'isolation d'un nouveau
|
||||
processus est `clone(2)`.
|
||||
|
||||
Ce *syscall*, propre à Linux, crée habituellement un nouveau processus (mais
|
||||
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
|
||||
paramètres. L'isolement ou non du processus se fait en fonction des *flags* qui
|
||||
sont passés :
|
||||
Ce *syscall*, propre à Linux, crée habituellement un nouveau processus enfant
|
||||
de notre processus courant (mais il peut aussi créer des *threads*, on va voir
|
||||
qu'il fait beaucoup de choses), comme `fork(2)` (qui lui est un appel système
|
||||
POSIX). Mais il prend en plus de nombreux paramètres. L'isolement ou non du
|
||||
processus se fait en fonction des *flags* qui sont passés. On retrouve donc :
|
||||
|
||||
* `CLONE_NEWNS`,
|
||||
* `CLONE_NEWUTS`,
|
||||
|
|
@ -75,12 +74,29 @@ sont passés :
|
|||
* `CLONE_NEWCGROUP`,
|
||||
* `CLONE_NEWTIME`.
|
||||
|
||||
::::: {.more}
|
||||
|
||||
Le nom du *flag* `CLONE_NEWNS` est historique et assez peu explicite
|
||||
contrairement aux autres : il désigne en fait l'espace de nom `mount`.
|
||||
|
||||
Au départ, les *namespace*s ont étés pensés pour former un tout : une couche
|
||||
d'isolation complète pour les processus. Mais lors des développements suivants,
|
||||
il s'est avéré pratique de pouvoir choisir finement de quels aspects on
|
||||
souhaitait se dissocier.
|
||||
|
||||
C'est ainsi que pour chaque nouveau *namespace*, un nouveau *flag* est
|
||||
introduit.
|
||||
|
||||
:::::
|
||||
|
||||
On peut bien entendu cumuler un ou plusieurs de ces *flags*, et les combiner
|
||||
avec d'autres attendus par `clone(2)`.
|
||||
|
||||
Ces mêmes *flags* sont utilisés lors des appels à `unshare(2)` ou `setns(2)`,
|
||||
que nous verrons plus tard.
|
||||
|
||||
::::: {.code}
|
||||
|
||||
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
|
||||
semblable à :
|
||||
|
|
@ -105,21 +121,34 @@ pid_t pid = clone(do_execvp, // First function executed by child
|
|||
Dans cet exemple, le processus fils créé disposera d'un nouvel espace de noms
|
||||
pour les *CGroups* et disposera d'une nouvelle pile réseau.
|
||||
|
||||
Un exemple complet d'utilisation de `clone(2)` et du *namespace* `UTS` est
|
||||
donné dans le `man` de l'appel système.
|
||||
::::: {.question}
|
||||
|
||||
#### Quel est le rôle du *flag* `SIGCHLD` ? {-}
|
||||
\
|
||||
|
||||
Lorsque l'on crée un nouveau processus, on ajoute l'option `SIGCHLD` afin
|
||||
d'être notifié par signal lorsque notre processus fil a terminé son
|
||||
exécution. Cela permet d'être réveillé de notre `wait(2)`.
|
||||
|
||||
:::::
|
||||
|
||||
:::::
|
||||
|
||||
L'appel système `clone(2)` va donc créer un nouveau processus, ou un nouveau
|
||||
*thread*, mais parfois on souhaite juste isoler notre processus actuel.
|
||||
|
||||
|
||||
##### `unshare`\
|
||||
|
||||
L'appel système `clone(2)` va créer un nouveau processus, ou un nouveau
|
||||
thread. Parfois, on souhaite faire entrer notre processus ou thread en cours
|
||||
dans un nouvel espace de noms. Dans ce cas, on utilisera l'appel système
|
||||
Lorsque l'on souhaite faire entrer notre processus courant ou notre *thread*
|
||||
dans un nouvel espace de noms, on peut utiliser l'appel système
|
||||
`unshare(2)`. Celui-ci prend uniquement en argument une liste de *flags* des
|
||||
*namespace*s dont on souhaite se dissocier.
|
||||
|
||||
::::: {.warning}
|
||||
Le comportement de `unshare(2)` (ou `unshare(3)`) avec les *namespace*s *PID*
|
||||
et *Time* n'est pas celui que l'on peut attendre !
|
||||
|
||||
**Le comportement de `unshare(2)` (ou `unshare(3)`) avec les *namespace*s *PID*
|
||||
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
|
||||
son *namespace* *Time* ou *PID* d'origine, seuls ses enfants (après un appel à
|
||||
|
|
@ -135,4 +164,8 @@ peuvent être différents dans le dossier `/proc/<PID>/ns`.
|
|||
On ne remarque pas cette bizarrerie avec `clone(2)`, car il crée déjà un
|
||||
nouveau processus, son PID et sa `CLOCK_MONOTONIC` sont directement à la bonne
|
||||
valeur dès l'exécution de la fonction `fn`.
|
||||
|
||||
:::::
|
||||
|
||||
Nous avons vu comment créer et nous dissocier d'un espace de nom. Maintenant
|
||||
voyons comment en rejoindre un déjà existant.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue