Linux的命名空间如何理解

56次阅读
没有评论

共计 5664 个字符,预计需要花费 15 分钟才能阅读完成。

丸趣 TV 小编今天带大家了解 Linux 的命名空间如何理解,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着丸趣 TV 小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着丸趣 TV 小编一起深入学习“Linux 的命名空间如何理解”的知识吧。

一、基本概念

  命名空间(Linux namespace)是 linux 内核针对实现容器虚拟化映入的一个特性。我们创建的每个容器都有自己的命名空间,运行在其中的应用都像是在独立的操作系统中运行一样,命名空间保证了容器之间互不影响。

  Linux 的命名空间机制提供了一种资源隔离的解决方案。PID,IPC,Network 等系统资源不再是全局性的,而是属于特定的 Namespace。Namespace 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前 namespace 里的进程,对其他 namespace 中的进程没有影响。

  传统上,在 Linux 以及其他衍生的 UNIX 变体中,许多资源是全局管理的。例如,系统中的所有进程按照惯例是通过 PID 标识的,这意味着内核必须管理一个全局的 PID 列表。而且,所有调用者通过 uname 系统调用返回的系统相关信息(包括系统名称和有关内核的一些信息)都是相同的。用户 ID 的管理方式类似,即各个用户是通过一个全局唯一的 UID 号标识。

  全局 ID 使得内核可以有选择地允许或拒绝某些特权。虽然 UID 为 0 的 root 用户基本上允许做任何事,但其他用户 ID 则会受到限制。例如 UID 为 n 的用户,不允许杀死属于用户 m 的进程(m≠ n)。但这不能防止用户看到彼此,即用户 n 可以看到另一个用户 m 也在计算机上活动。只要用户只能操纵他们自己的进程,这就没什么问题,因为没有理由不允许用户看到其他用户的进程。

  但有些情况下,这种效果可能是不想要的。如果提供 Web 主机的供应商打算向用户提供 Linux 计算机的全部访问权限,包括 root 权限在内。传统上,这需要为每个用户准备一台计算机,代价太高。使用 KVM 或 VMWare 提供的虚拟化环境是一种解决问题的方法,但资源分配做得不是非常好。计算机的各个用户都需要一个独立的内核,以及一份完全安装好的配套的用户层应用。

  命名空间提供了一种不同的解决方案,所需资源较少。在虚拟化的系统中,一台物理计算机可以运行多个内核,可能是并行的多个不同的操作系统。而命名空间则只使用一个内核在一台物理计算机上运作,前述的所有全局资源都通过命名空间抽象起来。这使得可以将一组进程放置到容器中,各个容器彼此隔离。隔离可以使容器的成员与其他容器毫无关系。但也可以通过允许容器进行一定的共享,来降低容器之间的分隔。例如,容器可以设置为使用自身的 PID 集合,但仍然与其他容器共享部分文件系统。

二、实现

  命名空间的实现需要两个部分:每个子系统的命名空间结构,将此前所有的全局组件包装到命名空间中;将给定进程关联到所属各个命名空间的机制。

  子系统此前的全局属性现在封装到命名空间中,每个进程关联到一个选定的命名空间。每个可以感知命名空间的内核子系统都必须提供一个数据结构,将所有通过命名空间形式提供的对象集中起来。struct nsproxy 用于汇集指向特定于子系统的命名空间包装器的指针。在文件 nsproxy.h 中有:

/*
 * 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;};

  当前内核的以下范围可以感知到命名空间

  1、UTS 命名空间包含了运行内核的名称、版本、底层体系结构类型等信息。UTS 是 UNIXTimesharing System 的简称。

  2、保存在 struct ipc_namespace 中的所有与进程间通信(IPC)有关的信息。

  3、已经装载的文件系统的视图,在 struct mnt_namespace 中给出。

  4、有关进程 ID 的信息,由 struct pid_namespace 提供。

  5、struct user_namespace 保存的用于限制每个用户资源使用的信息。

  6、struct net_ns 包含所有网络相关的命名空间参数。

  当我讨论相应的子系统时,会介绍各个命名空间容器的内容。在由于在创建新进程时可使用 fork 建立一个新的命名空间,因此必须提供控制该行为的适当的标志。每个命名空间都有一个对应的标志,在 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 */

  不同类型的命名空间的作用:

  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 命名空间

  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 系统

Linux 是一种免费使用和自由传播的类 UNIX 操作系统,是一个基于 POSIX 的多用户、多任务、支持多线程和多 CPU 的操作系统,使用 Linux 能运行主要的 Unix 工具软件、应用程序和网络协议。

感谢大家的阅读,以上就是“Linux 的命名空间如何理解”的全部内容了,学会的朋友赶紧操作起来吧。相信丸趣 TV 丸趣 TV 小编一定会给大家带来更优质的文章。谢谢大家对丸趣 TV 网站的支持!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-03发表,共计5664字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)