zoukankan      html  css  js  c++  java
  • linux中的namespace

         本文将就namespace这个知识点,进行简单的归纳总结,力求通俗易通。在资料汇总的过程中,参考了许多网上的博客资料,在文章尾部给出相关链接。

         namespace,命名空间,从名字上看,应该是类似于包含许多名字的空间,打个比方,三年一班的小明和三年二班的小明,虽说他们名字是一样的,但是所在班级不一样,那么,在全年级排行榜上面,即使出现两个名字一样的小明,也会通过各自的学号来区分。对于学校来说,每个班级就相当于是一个命名空间,这个空间的名称是班级号。班级号用于描述逻辑上的学生分组信息,至于什么学生分配到1班,什么学生分配到2班,那就由学校层面来统一调度。大致应该就是这么个意思,恩。

    C++中的命名空间

         命名空间这个概念不仅仅在kernel中有使用,在其他语言中也有所体现。例如在C++中,标准C++库中所包含的所有内容(包括常量、变量、结构、类和函数)都被定义在命名空间std中。我们可以定义有名命名空间,也可以定义无名命名空间,命名空间可以嵌套定义,

       1:  有名的命名空间:
       2:   
       3:         namespace 命名空间名 {
       4:   
       5:                声明序列可选
       6:   
       7:         }
       8:   
       9:  无名的命名空间:
      10:   
      11:         namespace {
      12:   
      13:                声明序列可选
      14:   
      15:         }
      16:   

        在C++中,如果代码的最前面没有使用 using namespace std 的话,对于输入输出流,就必须指定所在的命名空间(std::cout <<),否则编译器会找不到他们的具体实现。可以这么说,命名空间是对全局作用域的细分。

    Linux中的namespace

        在Linux系统中,可以同时存在多用户多进程,那么对他们的运行协调管理,通过进程调度和进度管理可以解决,但是,整体资源是有限的,怎么把有限的资源(进程号、通信资源、网络资源等等)合理分配给各个用户所在的进程?Linux中提出了namespace机制,这是一种轻量级的虚拟化形式。再次之前,Linux中很多资源是全局管理的,例如,系统中所有进程,都是通过PID来标识的,就像每个学生的学号一样,在整个学校范围内,肯定是唯一标识这个学生的。用户的ID管理,各个用户通过全局为UID来标识,每个学校的校长也只有有一个,它的UID为0,权利最大,可以对学校内全部老师和学生发起命令。每个学生可以看到其他学生的活动,但是无权把他们赶出学校,这是可以理解的。这种集中统一的管理方式,很适合大规模人群的管理。

        随着大数据、虚拟化的兴起,Linux为了提供更加精细的资源分配管理机制,给出了namespace机制解决方法。

    image

    命名空间建立系统的不同视图, 对于每一个命名空间,从用户看起来,应该像一台单独的Linux计算机一样,有自己的init进程(PID为0),其他进程的PID依次递增,A和B空间都有PID为0的init进程,子容器的进程映射到父容器的进程上,父容器可以知道每一个子容器的运行状态,而子容器与子容器之间是隔离的。

        Linux中有chroot的系统调用,该方法将进程限制到文件系统的某一部分,是一种简单的命名空间机制。

        在task_struct结构体中,有struct nsproxy *nsproxy 这个成员变量,

       1:  /*
       2:   * A structure to contain pointers to all per-process
       3:   * namespaces - fs (mount), uts, network, sysvipc, etc.
       4:   *
       5:   * 'count' is the number of tasks holding a reference.
       6:   * The count for each namespace, then, will be the number
       7:   * of nsproxies pointing to it, not the number of tasks.
       8:   *
       9:   * The nsproxy is shared by tasks which share all namespaces.
      10:   * As soon as a single namespace is cloned or unshared, the
      11:   * nsproxy is copied.
      12:   */
      13:  struct nsproxy {
      14:      atomic_t count;
      15:      spinlock_t nslock;
      16:      struct uts_namespace *uts_ns;
      17:      struct ipc_namespace *ipc_ns;
      18:      struct mnt_namespace *mnt_ns;
      19:      struct pid_namespace *pid_ns;
      20:  };

    uts_ns:UTS为Unix Timesharing System的简称,包含内存名称、版本、底层体系结构等信息。

    ipc_ns:保存所有与进程间通讯(IPC)有关的信息。

    mnt_ns: 当前装载的文件系统

    pid_ns: 有关进程ID的信息

    在高级版本上,还有net_ns的网络信息,user_ns的资源配额的信息等。

    下面以uts命名空间为例子,介绍如何创建用户空间。

    从上面的框架图可以看出,所谓的子空间,就是父进程fork一个子进程出来,然后子进程与父进程不共享某些资源,那么,就可以说,这个子进程在它自己的那个命名空间内。

    要达到这种效果,就必须对fork的行为进行精确控制,内核提供的如下参数来设置:

    image

    UTS命名空间没有层次结构,所有信息都汇集到如下结构:

    image ,kref是引用计数器,用于跟踪内核中有多少地方使用uts_namespace的实例。它提供的属性信息如下:

    image ,从名字上,可以得知uts包含系统名称、版本号、机器名称等等。使用uname -a可以查看这些信息。

    系统初始默认值保持在init/version.c 中的init_uts_ns全局变量中,在系统初始化task时,配置init_task。

    用户可以在fork时,传入CLONE_NEWUTS标准,创建新的UTS命名空间。执行此操作,会生成先前uts_namespace的一份副本,当前进程内部的nsproxy指向此副本,然后就可以修改了。父子进程对nx_prosy的修改不会相互影响。

        由于最初的父命名空间需要掌握所有子命名空间的所有pid信息,所有,在各级层次的命名空间的fork中,pid的分配是需要统一协调控制,对于各级子命名空间中的task_struct来说,同一个pid在不同命名空间看到的是不一样的。 

       同一个进程可以属于多个namespace,多个进程可以使用同一个namespace,

    参考链接:

    C++中的namespace

    PID namespace浅分析

    PID namespcae浅分析 续

    Linux内核的namespace机制分析

    Technorati 标签:
  • 相关阅读:
    JavaScript学习(五)
    浏览器输入地址到返回页面
    session cookie
    springboot 运行jar包
    mysql:The user specified as a definer ('root'@'%') does not exist
    easyUI
    json
    json fastjson
    springboot:because it is a JDK dynamic proxy that implements:
    git 提示错误:(non-fast-forward)
  • 原文地址:https://www.cnblogs.com/cherishui/p/4237883.html
Copyright © 2011-2022 走看看