Docker学习笔记一 Linux NameSpace

917 阅读3分钟

Linux NameSpace是什么

Linux Namespace 是kernel 的一个功能,它可以隔离一系列系统的资源,目前Linux中提供了六类系统资源的隔离机制,分别是:

  • Mount: 隔离文件系统挂载点
  • UTS: 隔离主机名和域名信息
  • IPC: 隔离进程间通信
  • PID: 隔离进程的ID
  • Network: 隔离网络资源
  • User: 隔离用户和用户组的ID

每个Namespace下的这些资源对于其他Namespace是不可见的。

kernel是什么


linux kernel 大致分为上图五大部分。 

  1.  进程管理 负责进程的创建和销毁,进程的调度。
  2.  内存管理 负责内存的分配和回收,记录哪些内存被哪些进程使用,管理虚拟内存,将内存的物理地址和逻辑地址做一个映射,主要由MMU进行转换,页表的方式。 
  3.  文件系统 这里的文件系统不仅仅只是硬盘的抽象管理,它也可以是某些io口的抽象;文件系统屏蔽了底层的细节,为上层提供统一的接口;linux中一切皆文件。 
  4.  设备管理 设备管理功能主要由驱动程序提供,主要任务是控制设备完成输入或输出操作;linux把设备看作是特殊的文件,系统通过处理文件的接口(虚拟文件系统VFS)来管理和控制各种设备。 
  5.  网络功能 网络功能值的是除了驱动程序提供的基本硬件操作外,还有系统提供的机制和功能,比如TCP协议,地址解析等。
  6. Linux Kernel、Namespace、Process之间的关系可以用下图描述。


当前Linux一共实现六种不同类型的namespace。

Namespace类型系统调用参数内核版本
Mount namespacesCLONE_NEWNS2.4.19
UTS namespacesCLONE_NEWUTS2.6.19
IPC namespacesCLONE_NEWIPC2.6.19
PID namespacesCLONE_NEWPID2.6.24
Network namespacesCLONE_NEWNET2.6.29
User namespacesCLONE_NEWUSER3.8

Namesapce 的API主要使用三个系统调用

  • clone() - 创建新进程。根据系统调用参数来判断哪种类型的namespace被创建,而且它们的子进程也会被包含到namespace中
  • unshare() - 将进程移出某个namespace
  • setns() - 将进程加入到namespace中

UTS Namespace

UTS Namespace提供了主机名和域名的隔离,也就是struct utsname里的nodename和domainname两个字段。不同Namespace中可以拥有独立的主机名和域名。

那么为什么需要对主机名和域名进行隔离呢?因为主机名和域名可以用来代替IP地址,如果没有这一层隔离,同一主机上不同的容器的网络访问就可能出问题。

IPC Namespace

IPC Namespace是对进程间通信的隔离,进程间通信常见的方法有信号量、消息队列和共享内存。IPC Namespace主要针对的是SystemV IPC和Posix消息队列,这些IPC机制都会用到标识符,比如用标识符来区分不同的消息队列,IPC Namespace要达到的目标是相同的标识符在不同的Namepspace中代表不同的通信介质(比如信号量、消息队列和共享内存)。


简单实现一个UTS Namespace的例子-《自己动手写docker》

package main

import (
    "os/exec"
    "syscall"
    "os"
    "log"
)

func main() {
    cmd := exec.Command("sh")//指定当前命令的执行环境
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags: syscall.CLONE_NEWUTS,
    //  
    }
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }
}