Use lang en-US for samples
This commit is contained in:
parent
f2f93440a7
commit
13dadd8c59
33 changed files with 318 additions and 0 deletions
|
@ -44,12 +44,14 @@ intégralité : vous ne pourrez pas monter les partitions indiquées par le
|
|||
Pour que tout cela fonctionne, vous avez besoin au préalable d'exécuter les
|
||||
commandes suivantes :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
cd newroot
|
||||
mount --bind /dev dev
|
||||
mount --bind /proc proc
|
||||
mount --bind /sys sys
|
||||
```
|
||||
</div>
|
||||
|
||||
En se `chroot`ant à nouveau dans cette nouvelle racine, nous voyons que tous
|
||||
nos outils fonctionnent comme prévu.
|
||||
|
@ -65,12 +67,14 @@ monter au nouvel emplacement le système de fichier ainsi que tous les points
|
|||
d'accroche qu'il contient, il faut utiliser `--rbind`. Il serait donc plus
|
||||
correct de lancer :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
cd newroot
|
||||
mount --rbind /dev dev
|
||||
mount -t proc none proc
|
||||
mount --rbind /sys sys
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
## Les montages parfumés
|
||||
|
@ -89,6 +93,7 @@ partage (on parle de *peer group*).
|
|||
|
||||
Essayons de voir à quoi cela correspond avec l'exemple suivant :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
# Création de nos répertoires de travail
|
||||
cd /mnt
|
||||
|
@ -100,14 +105,17 @@ mount --make-shared /tmp
|
|||
# Duplication de l'accroche, sans s'occuper des éventuels sous-accroches
|
||||
mount --bind /tmp /mnt/test-shared
|
||||
```
|
||||
</div>
|
||||
|
||||
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 :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
mkdir /mnt/test-shared/toto
|
||||
mount -t tmpfs none /mnt/test-shared/toto
|
||||
```
|
||||
</div>
|
||||
|
||||
Un coup de `findmnt` nous montre l'existence de deux nouveaux points de
|
||||
montages. À `/mnt/test-shared/toto`, mais également à `/tmp/toto`.
|
||||
|
@ -119,6 +127,7 @@ De la même manière que lorsque la propagation est partagée, cette politique
|
|||
propagera, mais seulement dans un sens. Le point de montage déclaré comme
|
||||
esclave ne propagera pas ses nouveaux points de montage.
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
# Suite de l'exemple précédent
|
||||
cd /mnt
|
||||
|
@ -130,20 +139,25 @@ mount --bind /mnt/test-shared /mnt/test-slave
|
|||
# On rend notre dossier esclave
|
||||
mount --make-slave /mnt/test-slave
|
||||
```
|
||||
</div>
|
||||
|
||||
Si l'on effectue un montage dans `/mnt/test-shared` :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
mkdir /mnt/test-shared/foo
|
||||
mount -t tmpfs none /mnt/test-shared/foo
|
||||
```
|
||||
</div>
|
||||
|
||||
Le point de montage apparaît bien sous `/mnt/test-slave/foo`. Par contre :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
mkdir /mnt/test-slave/bar
|
||||
mount -t tmpfs none /mnt/test-slave/bar
|
||||
```
|
||||
</div>
|
||||
|
||||
Le nouveau point de montage n'est pas propagé dans `/mnt/test-shared/bar`.
|
||||
|
||||
|
@ -155,25 +169,31 @@ C'est le mode le plus simple : ici les points de montage ne sont pas propagés.
|
|||
Pour forcer un point d'accroche a ne pas propager et à ne pas recevoir de
|
||||
propagation, on utilise l'option suivante :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
mount --make-private mountpoint
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### non-attachable -- *unbindable mount*
|
||||
|
||||
Ce mode interdira tout tentative d'attache à un autre endroit.
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
mount --make-unbindable /mnt/test-slave
|
||||
```
|
||||
</div>
|
||||
|
||||
Il ne sera pas possible de faire :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
mkdir /mnt/test-unbindable
|
||||
mount --bind /mnt/test-slave /mnt/test-unbindable
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### Parfums récursifs
|
||||
|
@ -182,12 +202,14 @@ Les options que nous venons de voir s'applique sur un point de montage. Il
|
|||
existe les mêmes options pour les appliquer en cascade sur les points d'attache
|
||||
contenu dans le sous-arbre :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
mount --make-rshared mountpoint
|
||||
mount --make-rslave mountpoint
|
||||
mount --make-rprivate mountpoint
|
||||
mount --make-runbindable mountpoint
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
## `bind` de dossiers et de fichiers
|
||||
|
@ -212,15 +234,19 @@ emplacement soit prévenu du changement.
|
|||
|
||||
On utilise pour cela l'option `--move` de `mount(8)` :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
mount --move olddir newdir
|
||||
```
|
||||
</div>
|
||||
|
||||
Par exemple :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
mount --move /dev /newroot/dev
|
||||
```
|
||||
</div>
|
||||
|
||||
Il est courant de faire appel à cette option lorsque l'on souhaite changer la
|
||||
racine de notre système de fichier : passer de l'initramfs au système au
|
||||
|
|
|
@ -40,10 +40,12 @@ 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` :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
mkdir /mnt/newroot
|
||||
mount -t tmpfs none /mnt/newroot
|
||||
```
|
||||
</div>
|
||||
|
||||
Placez ensuite dans cette nouvelle racine le système de votre choix (cf. le TP
|
||||
précédent pour les différentes méthodes et liens).
|
||||
|
@ -72,9 +74,11 @@ devoir nous isoler sur :
|
|||
|
||||
Isolons-nous :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
unshare -p -m -f --mount-proc
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### Dissocier la propagation des démontages
|
||||
|
@ -86,9 +90,11 @@ mount*.
|
|||
Commençons donc par étiqueter tous nos points de montage (de ce *namespace*),
|
||||
comme esclave :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
mount --make-rslave /
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### Démonter tout !
|
||||
|
@ -125,6 +131,8 @@ 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
|
||||
par :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
exec chroot / command
|
||||
```
|
||||
</div>
|
||||
|
|
|
@ -121,6 +121,7 @@ nouveaux *namespaces* et placer le processus dedans.
|
|||
Par exemple, nous pouvons modifier sans crainte le nom de notre machine, si
|
||||
nous sommes passé dans un autre *namespace* `UTS` :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh# hostname --fqdn
|
||||
koala.zoo.paris
|
||||
|
@ -134,6 +135,7 @@ bash# exit
|
|||
42sh# hostname --fqdn
|
||||
koala.zoo.paris
|
||||
```
|
||||
</div>
|
||||
|
||||
Nous avons pu ici modifier le nom de machine, sans que cela n'affecte notre
|
||||
machine hôte.
|
||||
|
@ -167,6 +169,7 @@ Les mêmes `flags` sont utilisés lors des appels à `unshare(2)` ou `setns(2)`.
|
|||
Pour créer un nouveau processus qui sera à la fois dans un nouvel *namespace*
|
||||
réseau et dans un nouveau *namespace* CGroup, on écrirait un code similaire à :
|
||||
|
||||
<div lang="en-US">
|
||||
```c
|
||||
#include <sched.h>
|
||||
|
||||
|
@ -180,6 +183,7 @@ pid_t pid = clone(do_execvp,
|
|||
clone_flags,
|
||||
&args);
|
||||
```
|
||||
</div>
|
||||
|
||||
Le premier argument est un pointeur sur fonction. Il s'agit de la fonction qui
|
||||
sera appelée par le nouveau processus.
|
||||
|
@ -198,6 +202,7 @@ programmes s'exécutent dans les mêmes *namespaces*.
|
|||
|
||||
### Exemples
|
||||
|
||||
<div lang="en-US">
|
||||
```sh
|
||||
42sh$ ./cmpns $(pgrep influxdb) $(pgrep init)
|
||||
- cgroup: differ
|
||||
|
@ -208,7 +213,9 @@ programmes s'exécutent dans les mêmes *namespaces*.
|
|||
- user: same
|
||||
- uts: same
|
||||
```
|
||||
</div>
|
||||
|
||||
<div lang="en-US">
|
||||
```sh
|
||||
42sh$ ./cmpns $(pgrep init) self
|
||||
- cgroup: same
|
||||
|
@ -219,11 +226,13 @@ programmes s'exécutent dans les mêmes *namespaces*.
|
|||
- user: same
|
||||
- uts: same
|
||||
```
|
||||
</div>
|
||||
|
||||
Ici, `self` fait référence au processus actuellement exécuté.
|
||||
|
||||
Et pourquoi pas :
|
||||
|
||||
<div lang="en-US">
|
||||
```sh
|
||||
42sh$ unshare -m ./cmpns $$ self
|
||||
- cgroup: same
|
||||
|
@ -234,6 +243,7 @@ Et pourquoi pas :
|
|||
- user: same
|
||||
- uts: same
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
## Rejoindre un *namespace*
|
||||
|
@ -242,6 +252,7 @@ Rejoindre un *namespace* se fait en utilisant l'appel système `setns(2)`,
|
|||
auquel on passe le *file descriptor* d'un des liens du dossier
|
||||
`/proc/<PID>/ns/` :
|
||||
|
||||
<div lang="en-US">
|
||||
```c
|
||||
#define _GNU_SOURCE
|
||||
#include <fcntl.h>
|
||||
|
@ -271,12 +282,15 @@ int main(int argc, char *argv[])
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
```
|
||||
</div>
|
||||
|
||||
Dans un shell, on utilisera la commande `nsenter(1)` :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh# nsenter --uts=/proc/42/ns/uts /bin/bash
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### `docker exec`
|
||||
|
@ -310,10 +324,12 @@ termine.
|
|||
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` :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh# touch /tmp/ns/myrefns
|
||||
42sh# mount --bind /proc/<PID>/ns/mount /tmp/ns/myrefns
|
||||
```
|
||||
</div>
|
||||
|
||||
De cette manière, même si le lien initial n'existe plus (si le `<PID>` s'est
|
||||
terminé), `/tmp/ns/myrefns` pointera toujours au bon endroit.
|
||||
|
|
|
@ -12,11 +12,13 @@ règles de filtrage, etc.
|
|||
En entrant dans un nouvel espace de nom `network`, on se retrouve dans un
|
||||
environnement qui n'a plus que l'interface de loopback :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh# unshare -n ip a
|
||||
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
|
||||
```
|
||||
</div>
|
||||
|
||||
Qui dit nouvelle pile réseau, dit également que les ports qui étaient assignés
|
||||
dans l'espace principal, ne le sont plus dans le conteneur : il est donc
|
||||
|
@ -31,9 +33,11 @@ La suite d'outils `iproute2` propose une interface simplifiée pour utiliser le
|
|||
|
||||
Tout d'abord, nous allons créer un nouvel espace de nom :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh$ ip netns add virli
|
||||
```
|
||||
</div>
|
||||
|
||||
La technique utilisée ici pour avoir des *namespaces* nommés est la même que
|
||||
celle que nous avons vu dans la première partie sur les *namespaces* : via un
|
||||
|
@ -42,9 +46,11 @@ persister le namespace malgré le fait que plus aucun processus ne s'y exécute.
|
|||
|
||||
Maintenant que notre *namespace* est créé, voyons s'il contient des interfaces :
|
||||
|
||||
<div lang="en-US">
|
||||
```sh
|
||||
42sh$ ip netns exec virli ip link
|
||||
```
|
||||
</div>
|
||||
|
||||
Cette commande ne devrait vous montrer que l'interface de *loopback*, car nous
|
||||
n'avons pour l'instant pas encore attaché la moindre interface.
|
||||
|
@ -52,16 +58,20 @@ n'avons pour l'instant pas encore attaché la moindre interface.
|
|||
D'ailleurs, cette interface est rapportée comme étant désactivée, activons-là
|
||||
via la commande :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh$ ip netns exec virli ip link set dev lo up
|
||||
```
|
||||
</div>
|
||||
|
||||
Si tout se passe bien, vous devriez maintenant pouvoir lancer un `ping` sur
|
||||
cette interface :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh$ ip netns exec virli ping 127.0.0.1
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
## *Virtual Ethernet*
|
||||
|
@ -74,9 +84,11 @@ centaines de conteneurs à gérer.
|
|||
Une technique couramment employée consiste à créer une interface virtuelle de
|
||||
type `veth` :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
ip link add veth0 type veth peer name veth1
|
||||
```
|
||||
</div>
|
||||
|
||||
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
|
||||
|
@ -89,24 +101,30 @@ devient alors possible de réaliser un échange de paquet entre les deux.
|
|||
|
||||
Pour déplacer `veth1` dans notre *namespace* `virli` :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh# ip link set veth1 netns virli
|
||||
```
|
||||
</div>
|
||||
|
||||
Il ne reste plus maintenant qu'à assigner une IP à chacune des interfaces :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
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
|
||||
```
|
||||
</div>
|
||||
|
||||
Testons maintenant que la communication entre les deux passe bient :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh# ping 10.10.10.42
|
||||
- et -
|
||||
42sh# ip netns exec virli ping 10.10.10.41
|
||||
```
|
||||
</div>
|
||||
|
||||
Il ne reste donc pas grand chose à faire pour fournir Internet à notre
|
||||
conteneur, via un peu de NAT ou grâce à un pont Ethernet.
|
||||
|
@ -125,11 +143,13 @@ gourmande.
|
|||
Il est possible d'attribuer juste une interface de VLAN, si l'on a switch les
|
||||
supportant.
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
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 eth0.100 netns virli
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### MACVLAN
|
||||
|
@ -149,9 +169,11 @@ l'équipement réseau derrière la machine de rerouter le paquet vers la machine
|
|||
|
||||
Pour construire une nouvelle interface de ce type :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
ip link add link eth0 mac0 type macvlan mode vepa
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
#### *Bridge*
|
||||
|
@ -163,9 +185,11 @@ sortie.
|
|||
|
||||
Pour construire une nouvelle interface de ce type :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
ip link add link eth0 mac1 type macvlan mode bridge
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
## Aller plus loin
|
||||
|
|
|
@ -22,9 +22,11 @@ se trouve).
|
|||
|
||||
Première étape s'isoler :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
unshare --pid --fork /bin/bash
|
||||
```
|
||||
</div>
|
||||
|
||||
Nous utilisons ici l'option `-f`, pour que le passage dans le nouvel espace de
|
||||
noms des PID soit effectif (cf. Introduction).
|
||||
|
@ -47,9 +49,11 @@ système initial. Pour s'en sortir, il est nécessaire de s'isoler du *namespace
|
|||
|
||||
Voici la nouvelle ligne de commande que l'on va utiliser :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
unshare --pid --mount --fork --mount-proc /bin/bash
|
||||
```
|
||||
</div>
|
||||
|
||||
Avec l'option `--mount-proc`, `unshare` va s'occuper de monter le nouveau
|
||||
`/proc`.
|
||||
|
|
|
@ -40,6 +40,7 @@ Astuce : `pivot_root(2)`, `umount(2)`.
|
|||
|
||||
Partant d'une liste d'interfaces sur la machine hôte similaire à :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
42sh$ ip link
|
||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
|
||||
|
@ -47,9 +48,11 @@ Partant d'une liste d'interfaces sur la machine hôte similaire à :
|
|||
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
|
||||
link/ether 90:2b:34:5e:fa:a7 brd ff:ff:ff:ff:ff:ff
|
||||
```
|
||||
</div>
|
||||
|
||||
Vous devrez pouvoir `ping` votre conteneur depuis votre hôte :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
42sh$ ip address
|
||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
|
||||
|
@ -69,6 +72,7 @@ PING 10.10.10.42 (10.10.10.42) 56(84) bytes of data.
|
|||
2 packets transmitted, 2 received, 0% packet loss, time 1003ms
|
||||
rtt min/avg/max/mdev = 3.789/3.847/3.906/0.085 ms
|
||||
```
|
||||
</div>
|
||||
|
||||
Dans l'exemple ci-dessus, l'interface dans le conteneur a l'IP `10.10.10.42`,
|
||||
tandis que la machine hôte a l'IP `10.10.10.41`.
|
||||
|
|
|
@ -17,7 +17,9 @@ ZIP, RAR, ...).
|
|||
|
||||
Voici une arborescence type:
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
login_x-mymoulette/README
|
||||
login_x-mymoulette/...
|
||||
```
|
||||
</div>
|
||||
|
|
|
@ -61,9 +61,11 @@ Sur chaque ligne, on doit indiquer :
|
|||
|
||||
Par exemple, le *namespace* `user` initial défini le correspondance suivante :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
0 0 4294967295
|
||||
```
|
||||
</div>
|
||||
|
||||
Cela signifie que les utilisateurs dont l'identifiant court de 0 à -2 inclu,
|
||||
dans cet espace de noms, correspond aux utilisateurs allant de 0 à -1 inclu,
|
||||
|
@ -71,9 +73,11 @@ pour le processus affichant ce fichier.
|
|||
|
||||
Lorsque l'on crée un *namespace* `user`, généralement, la correspondance vaut :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
0 1000 1
|
||||
```
|
||||
</div>
|
||||
|
||||
Dans cette situation, on comprend que notre processus considère que
|
||||
l'utilisateur root, dans le conteneur équivaut à l'utilisateur 1000 hors de
|
||||
|
@ -88,9 +92,11 @@ des groupes au lieu des utilisateurs.
|
|||
|
||||
## Utilisation de l'espace de noms
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh$ unshare --mount --pid --mount-proc --fork --net --user --map-root-user /bin/bash
|
||||
```
|
||||
</div>
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue