《自己动手写Docker》书摘之一: Linux Namespace.doc

《自己动手写Docker》书摘之一: Linux Namespace.doc

  1. 1、本文档共11页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
《自己动手写Docker》书摘之一: Linux Namespace

《自己动手写Docker》书摘之一: Linux Namespace Linux Namespace 介绍 我们经常听到说Docker 是一个使用了Linux Namespace 和 Cgroups 的虚拟化工具,但是什么是Linux Namespace 它在Docker内是怎么被使用的,说到这里很多人就会迷茫,下面我们就先介绍一下Linux Namespace 以及它们是如何在容器里面使用的。 概念 Linux Namespace 是kernel 的一个功能,它可以隔离一系列系统的资源,比如PID(Process ID),User ID, Network等等。一般看到这里,很多人会想到一个命令chroot,就像chroot允许把当前目录变成根目录一样(被隔离开来的),Namesapce也可以在一些资源上,将进程隔离起来,这些资源包括进程树,网络接口,挂载点等等。 比如一家公司向外界出售自己的计算资源。公司有一台性能还不错的服务器,每个用户买到一个tomcat实例用来运行它们自己的应用。有些调皮的客户可能不小心进入了别人的tomcat实例,修改或者关闭了其中的某些资源,这样就会导致各个客户之间互相干扰。也许你会说,我们可以限制不同用户的权限,让用户只能访问自己名下的tomcat,但是有些操作可能需要系统级别的权限,比如root。我们不可能给每个用户都授予root权限,也不可能给每个用户都提供一台全新的物理主机让他们互相隔离,因此这里Linux Namespace就派上了用场。使用Namespace, 我们就可以做到UID级别的隔离,也就是说,我们可以以UID为n的用户,虚拟化出来一个namespace,在这个namespace里面,用户是具有root权限的。但是在真实的物理机器上,他还是那个UID为n的用户,这样就解决了用户之间隔离的问题。当然这个只是Namespace其中一个简单的功能。 除了User Namespace ,PID也是可以被虚拟的。命名空间建立系统的不同视图, 对于每一个命名空间,从用户看起来,应该像一台单独的Linux计算机一样,有自己的init进程(PID为1),其他进程的PID依次递增,A和B空间都有PID为1的init进程,子容器的进程映射到父容器的进程上,父容器可以知道每一个子容器的运行状态,而子容器与子容器之间是隔离的。从图中我们可以看到,进程3在父命名空间里面PID 为3,但是在子命名空间内,他就是1.也就是说用户从子命名空间 A 内看进程3就像 init 进程一样,以为这个进程是自己的初始化进程,但是从整个 host 来看,他其实只是3号进程虚拟化出来的一个空间而已。 当前Linux一共实现六种不同类型的namespace。 Namesapce 的API主要使用三个系统调用 clone() - 创建新进程。根据系统调用参数来判断哪种类型的namespace被创建,而且它们的子进程也会被包含到namespace中 unshare() - 将进程移出某个namespace setns() - 将进程加入到namesp中 UTS Namespace UTS namespace 主要隔离nodename和domainname两个系统标识。在UTS namespace里面,每个 namespace 允许有自己的hostname。 下面我们将使用Go来做一个UTS Namespace 的例子。其实对于 Namespace 这种系统调用,使用 C 语言来描述是最好的,但是本书的目的是去实现 docker,由于 docker 就是使用 Go 开发的,那么我们就整体使用 Go 来讲解。先来看一下代码,非常简单: 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) } } 解释一下代码,exec.Command(sh) 是去指定当前命令的执行环境,我们默认使用sh来执行。下面的就是设置系统调用参数,像我们前面讲到的一样,使用CLONE_NEWUTS这个标识符去创建一个UTS Namespace。G

文档评论(0)

shuwkb + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档