\newpage Les espaces de noms -- *namespaces* {#namespaces} =================================== ## Introduction Les espaces de noms du noyau, les *namespaces*, permettent de dupliquer certaines structures, habituellement considérées uniques pour le noyau, dans le but de les isoler d'un groupe de processus à un autre. On en dénombre sept depuis Linux 4.6 : `cgroup`, `IPC`, `network`, `mount`, `PID`, `user` et `UTS`. La notion d'espace de noms est relativement nouvelle et a été intégrée progressivement au sein du noyau Linux. Aussi, toutes les structures ne sont pas encore *containerisables* : [le document fondateur](https://www.kernel.org/doc/ols/2006/ols2006v1-pages-101-112.pdf) parle ainsi d'isoler les périphériques, ou encore l'horloge. Pour ce dernier, [un patch a même déjà été proposé](https://lwn.net/Articles/179825/). ### L'espace de noms `mount` {#mount-ns} Depuis Linux 2.4.19. Cet espace de noms isole la liste des points de montage. Chaque processus appartenant à un *namespace* différent peut monter, démonter et réorganiser à sa guise les points de montage, sans que cela n'ait d'impact sur les processus hors de cet espace de noms. Une partition ne sera donc pas nécessairement démontée après un appel à `umount(2)`, elle le sera lorsqu'elle aura effectivement été démontée de chaque *namespace* dans lequel elle était montée. Attention il convient cependant de prendre garde aux types de liaison existant entre vos points de montage (voir la partie sur [les particularités des points de montage](#mount)), car les montages et démontages pourraient alors être répercutés dans l'espace de noms parent. Une manière rapide pour s'assurer que nos modifications ne sortiront pas de 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 noms. ```shell mount --make-rslave / ``` ### L'espace de noms `UTS` {#uts-ns} Depuis Linux 2.6.19. Cet espace de noms isole le nom de machine et son domaine NIS. ### L'espace de noms `IPC` {#ipc-ns} Depuis Linux 2.6.19. Cet espace de noms isole les objets IPC et les files de messages POSIX. Une fois le *namespace* attaché à un processus, il ne peut alors plus parler qu'avec les autres processus de son espace de noms (lorsque ceux-ci passent par l'API IPC du noyau). ### L'espace de noms `PID` Depuis Linux 2.6.24. Cet espace de noms isole la liste des processus et virtualise leurs numéros. Une fois dans un espace, le processus ne voit que le sous-arbre de processus également attachés à son espace. Il s'agit d'un sous-ensemble de l'arbre global de PID : les processus de tous les PID *namespaces* apparaissent donc dans l'arbre initial. Pour chaque nouvel espace de noms de processus, une nouvelle numérotation est initiée. Ainsi, le premier processus de cet espace porte le numéro 1 et aura les mêmes propriétés que le processus `init` usuel ; entre autre, si un processus est rendu orphelin dans ce *namespace*, il devient un fils de ce processus, et non un fils de l'`init` de l'arbre global. ### L'espace de nom `network` Depuis Linux 2.6.29. Cet espace de noms fournit une isolation pour toutes les ressources associées aux réseaux : les interfaces, les piles protocolaires IPv4 et IPv6, les tables de routage, règles pare-feu, ports numérotés, etc. Une interface réseau (`eth0`, `wlan0`, ...) ne peut se trouver que dans un seul espace de noms à la fois. Il est par contre possible de les déplacer. Lorsque le *namespace* est libéré (généralement lorsque le dernier processus attaché à cet espace de noms se termine), les interfaces qui le composent sont ramenées dans l'espace initial (et non pas dans l'espace parent, en cas d'imbrication). ### L'espace de noms `user` Depuis Linux 3.8. Cet espace de noms isole la liste des utilisateurs, des groupes, leurs identifiants, les *capabilities*, la racine et le trousseau de clefs du noyau. La principale caractéristique est que les identifiants d'utilisateur et de groupe pour un processus peuvent être différents entre l'intérieur et l'extérieur de l'espace de noms. Il est donc possible, alors que l'on est un simple utilisateur à l'extérieur du *namespace*, d'avoir l'UID 0 dans le conteneur. ### L'espace de noms `cgroup` {#cgroup-ns} Depuis Linux 4.6. Cet espace de noms filtre l'arborescence des *Control Group* en changeant la racine de l'arborescence des cgroups. Au sein d'un *namespace*, la racine vue correspond en fait à un sous-groupe de l'arborescence globale. Ainsi, un processus dans un `CGroup` *namespace* ne peut pas voir le contenu des sous-groupes parents (pouvant laisser fuiter des informations sur le reste du système). Cela peut également permettre de faciliter la migration de processus (d'un système à un autre) : l'arborescence des cgroups n'a alors plus d'importance car le processus ne voit que son groupe. ## S'isoler dans un nouveau *namespace* ### Avec son coquillage 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 nécessaire pour lancer l'appel système `unshare(2)`, puis, tout comme `chroot(1)`, exécuter le programme passé en paramètre. En fonction des options qui lui sont passées, `unshare(1)` va créer le/les nouveaux *namespaces* et placer le processus dedans. Par exemple, nous pouvons modifier sans crainte le nom de notre machine, si nous sommes passés dans un autre *namespace* `UTS` :