Maison > Article > Opération et maintenance > Ce que vous devez savoir sur les espaces de noms Linux
Cet article vous apporte des connaissances pertinentes sur les espaces de noms Linux. Les espaces de noms fournissent une forme légère de virtualisation, nous permettant de visualiser les propriétés globales du système en cours d'exécution sous différents aspects. J'espère qu'il sera utile à tout le monde.
- Namespace (espace de noms Linux) est une fonctionnalité du noyau Linux permettant d'implémenter la virtualisation de conteneurs. Chaque conteneur que nous créons possède son propre espace de noms et les applications qui y sont exécutées sont comme si elles s'exécutaient dans un système d'exploitation indépendant. L'espace de noms garantit que les conteneurs ne s'affectent pas les uns les autres.
Le mécanisme d'espace de noms de Linux fournit une solution pour l'isolation des ressources. Les ressources système telles que PID, IPC et Réseau ne sont plus globales, mais appartiennent à un espace de noms spécifique. L'espace de noms est une sorte d'encapsulation et d'isolation des ressources système globales, de sorte que les processus dans différents espaces de noms disposent de ressources système globales indépendantes. La modification des ressources système dans un espace de noms n'affectera que les processus de l'espace de noms actuel et n'aura aucun impact sur les processus des autres espaces de noms.
Traditionnellement, sous Linux et autres dérivés d'UNIX, de nombreuses ressources sont gérées globalement. Par exemple, tous les processus du système sont classiquement identifiés par PID, ce qui signifie que le noyau doit gérer une liste globale de PID. De plus, les informations relatives au système (y compris le nom du système et certaines informations sur le noyau) renvoyées par tous les appelants via l'appel système uname sont les mêmes. Les ID utilisateur sont gérés de la même manière, c'est-à-dire que chaque utilisateur est identifié par un numéro UID unique au monde.
Global ID permet au noyau d'autoriser ou de refuser sélectivement certains privilèges. Alors que l'utilisateur root avec l'UID 0 est autorisé à faire pratiquement n'importe quoi, les autres ID utilisateur sont restreints. Par exemple, l'utilisateur avec l'UID n n'est pas autorisé à tuer le processus appartenant à l'utilisateur m (m≠ n). Mais cela n'empêche pas les utilisateurs de se voir, c'est-à-dire que l'utilisateur n peut voir qu'un autre utilisateur m est également actif sur l'ordinateur. Tant que les utilisateurs ne peuvent manipuler que leurs propres processus, c'est très bien, car il n'y a aucune raison pour que les utilisateurs ne soient pas autorisés à voir les processus des autres utilisateurs.
Mais il existe des situations où cet effet peut être indésirable. Si le fournisseur d'hébergement Web a l'intention de fournir aux utilisateurs un accès complet à un ordinateur Linux, y compris les privilèges root. Traditionnellement, cela nécessitait un ordinateur pour chaque utilisateur, ce qui était d'un coût prohibitif. L'utilisation de l'environnement de virtualisation fourni par KVM ou VMWare est un moyen de résoudre le problème, mais l'allocation des ressources n'est pas très bonne. Chaque utilisateur de l'ordinateur nécessite un noyau distinct et un ensemble entièrement installé d'applications de support au niveau utilisateur.
Les espaces de noms offrent une solution différente qui nécessite moins de ressources. Dans un système virtualisé, un ordinateur physique peut exécuter plusieurs cœurs, éventuellement plusieurs systèmes d'exploitation différents en parallèle. L'espace de noms n'utilise qu'un seul noyau pour fonctionner sur un ordinateur physique, et toutes les ressources globales susmentionnées sont extraites via l'espace de noms. Cela permet de placer un ensemble de processus dans des conteneurs isolés les uns des autres. L'isolement permet aux membres d'un conteneur de n'avoir aucune relation avec d'autres conteneurs. Mais vous pouvez également réduire la séparation entre les conteneurs en leur permettant de partager certaines quantités d'informations. Par exemple, un conteneur peut être configuré pour utiliser son propre ensemble de PID tout en partageant des parties du système de fichiers avec d'autres conteneurs.
L'implémentation de l'espace de noms nécessite deux parties : la structure de l'espace de noms de chaque sous-système, qui enveloppe tous les composants globaux précédents dans l'espace de noms ; et le mécanisme qui associe un processus donné à chaque espace de noms auquel il appartient ;
Les propriétés globales précédentes des sous-systèmes sont désormais encapsulées dans des espaces de noms et chaque processus est associé à un espace de noms sélectionné. Chaque sous-système du noyau prenant en charge les espaces de noms doit fournir une structure de données qui collecte tous les objets fournis en tant qu'espaces de noms. struct nsproxy est utilisé pour assembler des pointeurs vers des wrappers d'espace de noms spécifiques au sous-système. Dans le fichier nsproxy.h, il y a :
/* * A structure to contain pointers to all per-process * namespaces - fs (mount), uts, network, sysvipc, etc. * * The pid namespace is an exception -- it's accessed using * task_active_pid_ns. The pid namespace here is the * namespace that children will use. * * 'count' is the number of tasks holding a reference. * The count for each namespace, then, will be the number * of nsproxies pointing to it, not the number of tasks. * * The nsproxy is shared by tasks which share all namespaces. * As soon as a single namespace is cloned or unshared, the * nsproxy is copied. */struct nsproxy { atomic_t count; struct uts_namespace *uts_ns; struct ipc_namespace *ipc_ns; struct mnt_namespace *mnt_ns; struct pid_namespace *pid_ns_for_children; struct net *net_ns; struct time_namespace *time_ns; struct time_namespace *time_ns_for_children; struct cgroup_namespace *cgroup_ns;};
Les portées suivantes du noyau actuel peuvent détecter l'espace de noms
1. L'espace de noms UTS contient le nom, la version, le type d'architecture sous-jacente et d'autres informations du noyau en cours d'exécution. UTS est l'abréviation de UNIX Timesharing System.
2. Toutes les informations liées à la communication inter-processus (IPC) stockées dans la struct ipc_namespace.
3. La vue du système de fichiers monté est donnée dans struct mnt_namespace.
4. Les informations sur l'ID du processus sont fournies par la structure pid_namespace.
5. Les informations enregistrées par struct user_namespace sont utilisées pour limiter l'utilisation des ressources de chaque utilisateur.
6. struct net_ns contient tous les paramètres d'espace de noms liés au réseau.
Lorsque je discuterai du sous-système correspondant, je présenterai le contenu de chaque conteneur d'espace de noms. Étant donné que fork peut être utilisé pour établir un nouvel espace de noms lors de la création d'un nouveau processus, des indicateurs appropriés doivent être fournis pour contrôler ce comportement. Chaque espace de noms a un indicateur correspondant, qui se trouve dans le fichier sched.h :
#define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace */ #define CLONE_NEWUTS 0x04000000 /* New utsname namespace */ #define CLONE_NEWIPC 0x08000000 /* New ipc namespace */ #define CLONE_NEWUSER 0x10000000 /* New user namespace */ #define CLONE_NEWPID 0x20000000 /* New pid namespace */ #define CLONE_NEWNET 0x40000000 /* New network namespace */
Les fonctions des différents types d'espaces de noms :
IPC:用于隔离进程间通讯所需的资源( System V IPC, POSIX message queues),PID命名空间和IPC命名空间可以组合起来用,同一个IPC名字空间内的进程可以彼此看见,允许进行交互,不同空间进程无法交互
Network:Network Namespace为进程提供了一个完全独立的网络协议栈的视图。包括网络设备接口,IPv4和IPv6协议栈,IP路由表,防火墙规则,sockets等等。一个Network Namespace提供了一份独立的网络环境,就跟一个独立的系统一样。
Mount:每个进程都存在于一个mount Namespace里面, mount Namespace为进程提供了一个文件层次视图。如果不设定这个flag,子进程和父进程将共享一个mount Namespace,其后子进程调用mount或umount将会影响到所有该Namespace内的进程。如果子进程在一个独立的mount Namespace里面,就可以调用mount或umount建立一份新的文件层次视图。
PID::linux通过命名空间管理进程号,同一个进程,在不同的命名空间进程号不同!进程命名空间是一个父子结构,子空间对于父空间可见。
User:用于隔离用户
UTS:用于隔离主机名
每个进程都关联到自身的命名空间视图,在任务定义的结构体task_struct中有如下定义:
struct task_struct {.../* 命名空间 */struct nsproxy *nsproxy;...}
因为使用了指针,多个进程可以共享一组子命名空间。这样,修改给定的命名空间,对所有属于该命名空间的进程都是可见的。
init_nsproxy定义了初始的全局命名空间,其中维护了指向各子系统初始的命名空间对象的指针。在kernel/nsproxy.c文件内有
struct nsproxy init_nsproxy = { .count = ATOMIC_INIT(1), .uts_ns = &init_uts_ns,#if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC) .ipc_ns = &init_ipc_ns,#endif .mnt_ns = NULL, .pid_ns_for_children = &init_pid_ns,#ifdef CONFIG_NET .net_ns = &init_net,#endif#ifdef CONFIG_CGROUPS .cgroup_ns = &init_cgroup_ns,#endif#ifdef CONFIG_TIME_NS .time_ns = &init_time_ns, .time_ns_for_children = &init_time_ns,#endif};
UTS命名空间几乎不需要特别的处理,因为它只需要简单量,没有层次组织。所有相关信息都汇集到下列结构的一个实例中。在utsname.h文件内:
struct uts_namespace { struct new_utsname name; struct user_namespace *user_ns; struct ucounts *ucounts; struct ns_common ns;} __randomize_layout;
uts_namespace所提供的属性信息本身包含在struct new_utsname中:
struct oldold_utsname { char sysname[9]; char nodename[9]; char release[9]; char version[9]; char machine[9];};#define __NEW_UTS_LEN 64struct old_utsname { char sysname[65]; char nodename[65]; char release[65]; char version[65]; char machine[65];};struct new_utsname { char sysname[__NEW_UTS_LEN + 1]; char nodename[__NEW_UTS_LEN + 1]; char release[__NEW_UTS_LEN + 1]; char version[__NEW_UTS_LEN + 1]; char machine[__NEW_UTS_LEN + 1]; char domainname[__NEW_UTS_LEN + 1];}
各个字符串分别存储了系统的名称( Linux…)、内核发布版本、机器名,等等。使用uname工具可以取得这些属性的当前值,也可以在/proc/sys/kernel/中看到
z@z-virtual-machine:~$ cat /proc/sys/kernel/ostype Linux z@z-virtual-machine:~$ cat /proc/sys/kernel/osrelease5.3.0-40-generic
初始设置保存在init_uts_ns中,在init/version.c文件内:
struct uts_namespace init_uts_ns = { .ns.count = REFCOUNT_INIT(2), .name = { .sysname = UTS_SYSNAME, .nodename = UTS_NODENAME, .release = UTS_RELEASE, .version = UTS_VERSION, .machine = UTS_MACHINE, .domainname = UTS_DOMAINNAME, }, .user_ns = &init_user_ns, .ns.inum = PROC_UTS_INIT_INO,#ifdef CONFIG_UTS_NS .ns.ops = &utsns_operations,#endif};
相关推荐:《Linux视频教程》
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!