GNU/Linux >> Tutoriels Linux >  >> Linux

Construire des conteneurs à la main :l'espace de noms PID

Poursuivant avec la série des espaces de noms, cet article couvre le PID espace de noms. Si vous voulez un aperçu général de tous les espaces de noms, consultez le premier article. Auparavant, vous avez créé un nouveau mnt espace de noms. Fait intéressant, comme vous l'avez découvert, même après avoir créé un nouveau mnt l'espace de noms, vous avez toujours accès aux ID de processus (PID) de l'hôte d'origine. Lorsque vous avez essayé de monter le fichier /proc espace de noms, vous avez reçu la plutôt déroutante autorisation refusée erreur, comme indiqué ci-dessous :

root@new-mnt$ mount -t proc proc /proc
mount: permission denied (are you root?)

root@new-mnt$ whoami
root

Bien que vous puissiez créer toutes sortes de montages dans le nouvel espace de noms de montage, vous ne pouviez pas interagir ou modifier /proc . Dans cet article, je passe en revue le PID l'espace de noms et montrez comment vous pouvez l'utiliser, ainsi que le mnt espace de noms, pour sécuriser davantage votre conteneur naissant.

[ Les lecteurs ont également aimé : Comment les espaces de noms Linux PID fonctionnent avec les conteneurs ]

Que sont les ID de processus ?

Avant de sauter directement dans le PID espace de noms, je pense que c'est une bonne idée de fournir un peu de contexte pour expliquer pourquoi cet espace de noms est important.

Lorsqu'un processus est créé sur la plupart des systèmes d'exploitation de type Unix, il reçoit un identifiant numérique spécifique appelé ID de processus (PID). Ce PID permet d'identifier un processus de manière unique même s'il existe deux processus qui partagent le même nom lisible par l'homme. Par exemple, si plusieurs sessions ssh sont actives sur un système et que vous devez fermer une connexion spécifique, le PID permet à l'administrateur de s'assurer que la bonne session est fermée.

Tous ces processus sont suivis dans un système de fichiers spécial appelé procfs . Bien que ce système de fichiers puisse techniquement être monté n'importe où, la plupart des outils (et conventions) attendent le procfs à monter sous /proc . Si vous faites une liste de /proc , vous verrez un dossier pour chaque processus en cours d'exécution sur votre système. À l'intérieur de ce dossier se trouvent toutes sortes de fichiers spéciaux utilisés pour suivre divers aspects du processus. Pour les besoins de cet article, ces fichiers ne sont pas importants. Il suffit de savoir que /proc est l'endroit où la plupart des systèmes de type Unix stockent des informations concernant les processus sur un système en cours d'exécution.

L'espace de noms PID

L'une des principales raisons du PID namespace est de permettre l'isolation des processus. Plus précisément, comme le dit la page de manuel :

Les espaces de noms PID isolent l'espace des numéros d'ID de processus, ce qui signifie que les processus dans différents espaces de noms PID peuvent avoir le même PID.

Ceci est important car cela signifie que les processus peuvent être assurés de ne pas avoir de PID en conflit avec un autre processus. Lorsque l'on considère un seul système, bien sûr, il n'y a aucune chance que les PID soient en conflit car le système incrémente continuellement le numéro d'identification du processus et n'attribue jamais le même numéro deux fois. Lorsqu'il s'agit de conteneurs sur plusieurs machines, ce problème devient plus important. Comme décrit dans la page de manuel :

Les espaces de noms PID permettent aux conteneurs de fournir des fonctionnalités telles que la suspension/reprise de l'ensemble des processus dans le conteneur et la migration du conteneur vers un nouvel hôte tandis que les processus à l'intérieur du conteneur conservent les mêmes PID.

Mis à part l'isolement, le système PID fonctionne presque identique à celui en dehors de l'espace de noms. Les ID de processus à l'intérieur du nouvel espace de noms commencent à 1 , avec le premier processus considéré comme init processus. L'initialisation processus est géré très différemment de tous les autres PID sur un hôte. Cela a des implications particulières pour le système en cours d'exécution qui sortent du cadre de cette série. Si vous souhaitez plus d'informations, consultez la section "Les signaux et le processus d'initialisation" de l'article Espaces de noms LWN.

Ce qui est à noter, cependant, c'est que quel que soit le processus qui a le PID 1 est vital pour la longévité des espaces de noms. Si PID 1 est terminé pour une raison quelconque, le noyau enverra un SIGKILL à tous les processus restants dans l'espace de noms, fermant efficacement cet espace de noms.

Explorer les espaces de noms PID

Si vous vous demandez, comme moi, si vous pouvez imbriquer PID espaces de noms, la réponse est oui. En fait, le noyau fait de la place pour jusqu'à 32 PID imbriqués espaces de noms. Ceci est considéré comme une relation à sens unique. Cela signifie que le parent peut voir les PID des enfants, petits-enfants, etc. Cependant, il ne peut voir aucun des PID de ses ancêtres. Considérez ce qui suit :

[user@localhost ~] sudo unshare -fp /bin/bash
[root@localhost ~] sleep 90000 &

[root@localhost ~] ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
[truncated ]
.....
root       11627   11620  0 09:16 pts/0    00:00:00 sudo unshare -fp /bin/bash
root       11633   11627  0 09:17 pts/0    00:00:00 unshare -fp /bin/bash
root       11634   11633  0 09:17 pts/0    00:00:00 /bin/bash
root       11639   11634  0 09:17 pts/0    00:00:00 sleep 90000
root       11641   11634  0 09:17 pts/0    00:00:00 ps -ef

[root@localhost ~] sudo unshare -fp /bin/bash
[root@localhost ~] sleep 8000 &

[root@localhost ~] ps -ef
[truncated ]
.....

UID          PID    PPID  C STIME TTY          TIME CMD
root       11650   11634  0 09:17 pts/0    00:00:00 sudo unshare -fp /bin/bash
root       11654   11650  0 09:17 pts/0    00:00:00 unshare -fp /bin/bash
root       11655   11654  0 09:17 pts/0    00:00:00 /bin/bash
root       11661   11655  0 09:17 pts/0    00:00:00 sleep 8000
root       11671   11655  0 09:17 pts/0    00:00:00 ps -ef

Vous remarquerez que j'ai tronqué la sortie car le PID l'espace de noms apparaît pour avoir un accès complet à tous les PID dans /proc . Observez ce qui se passe si vous essayez d'arrêter un processus qui se trouve dans un ancêtre :

[root@localhost ~] kill -9 11361
bash: kill: (11361) - No such process

Pourquoi est-ce? En termes simples, des outils traditionnels comme ps ne sont pas conscients de l'espace de noms et lisent réellement à partir de /proc annuaire. Si vous avez fait un ls /proc , vous verrez toujours tous les dossiers et fichiers d'avant car, comme indiqué dans le dernier article, le PID l'espace de noms hérite tous les mnt montages d'espace de noms. J'aborde cette situation plus tard. Pour l'instant, revenez à l'exemple actuel.

Dans un autre shell, identifiez les processus en veille :

[user@localhost ~] ps -ef |grep sleep
root       11639   11634  0 09:17 pts/0    00:00:00 sleep 90000
root       11661   11655  0 09:17 pts/0    00:00:00 sleep 8000

Si vous voulez vérifier que ces processus sont dans des espaces de noms différents, vous devrez trouver le bash processus PID. N'oubliez pas que depuis que vous avez exécuté sudo unshare -fp /bin/bash , le bash le processus est init processus dans le nouvel espace de noms. C'est donc le PID qui sera lié à l'ID de l'espace de noms. Prenons les PID :

[root@localhost ~] ps -ef |grep bash
root       11627   11620  0 09:16 pts/0    00:00:00 sudo unshare -fp /bin/bash
root       11633   11627  0 09:17 pts/0    00:00:00 unshare -fp /bin/bash
root       11634   11633  0 09:17 pts/0    00:00:00 /bin/bash
root       11650   11634  0 09:17 pts/0    00:00:00 sudo unshare -fp /bin/bash
root       11654   11650  0 09:17 pts/0    00:00:00 unshare -fp /bin/bash
root       11655   11654  0 09:17 pts/0    00:00:00 /bin/bash

Vous pouvez voir les PID 11634 et 11655 dans la sortie. Si vous comparez cela à la sortie de lsns (répertorier les espaces de noms), vous verrez ce qui suit :

[root@localhost ~] lsns |grep bash
        NS TYPE   NPROCS    PID USER             COMMAND
4026532952 pid         4 11634 root             /bin/bash
4026532954 pid         4 11655 root             /bin/bash

Comme vous pouvez le voir, les ID d'espace de noms sont différents, et donc les processus sont dans des espaces de noms différents.

Maintenant que vous avez établi que les espaces de noms sont effectivement différents, regardons l'ascendance PID mentionnée précédemment. Vous pouvez le faire en identifiant le NSpid attribut d'un PID donné dans le /proc répertoire, comme indiqué ci-dessous :

sudo cat /proc/11655/status |grep NSpid
NSpid:    11655    6    1

Les colonnes se lisent de gauche à droite et indiquent le PID dans leurs espaces de noms respectifs. Le PID le plus à gauche est l'espace de noms principal ou racine. Dans ce cas, il a un PID de 11655 , un PID secondaire de 6 , et un PID tertiaire de 1 . Étant donné que les espaces de noms possèdent chaque PID descendant espace de noms, vous pouvez le penser comme ceci :

  • Sur l'hôte, le bash processus exécutant le sleep 8000 la commande a un PID de 11655 .
  • À l'intérieur du premier "conteneur", le bash processus exécutant le sleep 8000 la commande a un PID de 6 .
  • À l'intérieur du deuxième "conteneur" imbriqué, le PID est 1 . Il s'agit du conteneur qui a réellement lancé le processus.

Chacun de ces bash commandes a été créée dans son propre espace de noms mais est visible par le parent (dans ce cas, la racine espace de noms).

/proc, PID et utilisateurs non privilégiés

Le lecteur avisé aurait remarqué que, dans les deux derniers articles, un utilisateur régulier pouvait créer à la fois utilisateur et mnt espaces de noms. Dans cet article, j'ai utilisé le sudo commande. C'est parce que vous ne pouvez pas créer un PID espace de noms seul avec un utilisateur non privilégié. La réponse à cela est de combiner plusieurs créations d'espaces de noms en un seul événement. Il existe plusieurs solutions différentes pour monter /proc en tant qu'utilisateur non privilégié.

Si vous essayez simplement de créer un nouvel utilisateur namespace, vous obtiendrez un résultat étrange :

[ user@localhost ~] unshare -Urp
-bash: fork: Cannot allocate memory
-bash-5.1# ps -ef
-bash: fork: Cannot allocate memory
-bash-5.1# ls
-bash: fork: Cannot allocate memory

Que se passe-t-il ici? Rappelez-vous comment le premier processus à l'intérieur d'un nouveau PID l'espace de noms devient init processus? Dans ce cas, le shell actuel ne peut pas déplacer les espaces de noms. Il existe dans la racine espace de noms et lorsque vous avez créé un nouveau PID espace de noms, le système ne savait pas comment le gérer. La solution à cela est d'avoir le processus lui-même. Cela permet au shell actuel de devenir un processus enfant de unshare commande. Utiliser le -f flag entraîne la création de l'espace de noms :

[ user@localhost ~] unshare -Urfp
[ root@localhost ~]

Cependant, vous voyez toujours la contamination du /proc point de montage. Il existe deux solutions à cela. Tout d'abord, vous pouvez créer un nouveau mnt namespace puis remontez /proc vous-même :

[ user@localhost  ~]$ unshare -Urpmf
[ root@localhost ~]# mount -t proc proc /proc
[ root@localhost ~]# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 09:31 pts/0    00:00:00 -bash
root          10       1  0 09:31 pts/0    00:00:00 ps -ef

En effet, pendant de nombreuses années, c'était la seule option mais, un indicateur --mount-proc a été créé il y a quelque temps pour le faire en une seule étape. La page de manuel indique :

Juste avant d'exécuter le programme, montez le système de fichiers proc au point de montage (la valeur par défaut est /proc). Ceci est utile lors de la création d'un nouvel espace de noms PID. Cela implique également la création d'un nouvel espace de noms de montage car le montage /proc gâcherait autrement les programmes existants sur le système. Le nouveau système de fichiers proc est explicitement monté en tant que privé (avec MS_PRIVATE|MS_REC).

Ainsi, par conséquent, vous pouvez voir des références à la commande suivante :

unshare -Urpf --mount-proc

Cela crée un nouveau mnt espace de noms lors du montage de /proc pour vous.

Saisie d'un espace de noms

Pour réduire la complexité, j'ai quitté les espaces de noms créés précédemment. J'ai créé un nouvel espace de noms avec la commande suivante :

unshare -Urfp --mount-proc

J'ai également créé un différent sleep processus juste pour aider à identifier l'espace de noms. Comme je n'ai qu'un seul nouvel espace de noms, je peux utiliser le lsns commande pour déterminer le bon PID :

[ user@localhost  ~]$ lsns |grep bash
4026532965 pid         2 13142 user -bash

Ensuite, exécutez le nsenter commande :

sudo nsenter -t 13142 -a

Le -a flag indique au nsenter pour entrer tous les espaces de noms de ce PID. sudo est requis avec le -a flag, sinon vous ne pourrez pas passer à tous les espaces de noms appropriés. Vous devriez maintenant pouvoir lister tous les PIDS de ce NS :

[ root@localhost  ~]$ ps -ef

UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 09:54 pts/0    00:00:00 -bash
root           8       1  0 09:54 pts/0    00:00:00 sleep 99999
root          25       0  0 10:15 pts/1    00:00:00 -bash
root          31      25  0 10:15 pts/1    00:00:00 ps -ef

[ Apprenez les bases de l'utilisation de Kubernetes dans cet aide-mémoire gratuit. ] 

Conclusion

Le PID L'espace de noms est important lorsqu'il s'agit de créer des environnements isolés. Il permet aux processus d'avoir leurs propres PID quel que soit le système hôte. Dans un monde où plusieurs hôtes peuvent être impliqués dans l'orchestration d'environnements isolés (conteneurs), il devient crucial de disposer d'une installation garantissant des PID uniques lors du gel et de la migration des processus. De plus, pour des raisons de sécurité, si vous exécutez des espaces de noms pour l'isolation des applications, le PID L'espace de noms est essentiel pour empêcher les fuites d'informations par le biais des processus qu'un hôte peut exécuter.

Lorsqu'il est combiné avec l'utilisateur et mnt espaces de noms, le PID L'espace de noms fournit une grande protection sans nécessiter de privilèges root. Les navigateurs modernes tels que Firefox et Vivaldi utilisent des espaces de noms pour fournir un bac à sable du navigateur. Dans le prochain article, je vais vous montrer le net namespace et voyez comment vous pouvez continuer à construire votre conteneur à la main en ajoutant des composants réseau discrets.


Linux
  1. La valeur maximale de l'ID de processus ?

  2. Linux - Trouver le pid du processus à l'aide d'un port spécifique ?

  3. Quel processus a le Pid 0 ?

  4. Construire le nuage fiscal

  5. Comment calculer l'utilisation CPU d'un processus par PID sous Linux à partir de C ?

Construire un conteneur à la main à l'aide d'espaces de noms :l'espace de noms de montage

Comment trouver le PID et le PPID d'un processus sous Linux

Comment trouver l'ID de processus dans Ubuntu ?

Un PID de processus est-il garanti de rester le même tant que le processus ne meurt pas ?

Si je connais le numéro PID d'un processus, comment puis-je obtenir son nom ?

Comment trouver le fichier .pid pour un processus donné