浅析docker实现思想

从虚拟化的种类和层级说起

  • cpu虚拟化:可以模拟不同CPU,例如bochs
  • 完全虚拟化:只能模拟同样CPU,但是可以执行不同系统,例如vmware
  • 半虚拟化
  • 硬件虚拟化:可以当作获得硬件加速的完全虚拟化
  • 系统虚拟化:host和guest共享一样的内核,例如Openvz
  • 语言沙盒:只能在语言的范围内使用

虚拟化的级别越偏底层,速度越慢,用户越难察觉到虚拟化的存在。 虚拟化的级别越偏上层,速度越快,用户越容易感知。也就是虚拟幻的包装,如何一个虚拟化完全包装底层,呈现给用户一个新的操作系统,那么用户会知道他用的什么吗?

  • cpu虚拟化和完全虚拟化时,用户几乎可以阿不察觉到虚拟化的存在
  • 半虚拟化时,guest内核必须存在补丁
    • 系统虚拟化时,用户不能控制自己的内核
    • 语言沙盒时,用户没有使用api的自由

docker的原理

  • doceker实现结构
    –>lxc
    –>namespace: 仅沙盒隔离,不限制资源。
    –>cgroup: 仅限制资源,不沙盒隔离。
    –>aufs
    –>image管理
  • 底层技术

    Docker使用Go语言编写,并且使用了一系列Linux内核提供的性能来实现我们已经看到的这些功能。

  • lxc

    LXC是Linux containers的简称,是一种基于容器的操作系统层级的虚拟化技术,linux原生支持的容器.

    • XC可以在操作系统层次上为进程提供的虚拟的执行环境,一个虚拟的执行环境就是一个容器。可以为容器绑定特定的cpu和memory节点,分配特定比例的cpu时间、IO时间,限制可以使用的内存大小(包括内存和是swap空间),提供device访问控制,提供独立的namespace(网络、pid、ipc、mnt、uts)。
  • 命名空间(Namespaces)
    • Docker充分利用了一项称为namespaces的技术来提供隔离的工作空间,我们称之为 container(容器)。当你运行一个容器的时候,Docker为该容器创建了一个命名空间集合。其实我们在c++也见过类似的namespace
    • 这样提供了一个隔离层,每一个应用在它们自己的命名空间中运行而且不会访问到命名空间之外。
      通俗来讲,就是给将每一个应用放在小房子的,也就是容器,使不同应用不会冲突。

    一些Docker使用到的命名空间有:

    • pid命名空间: 使用在进程隔离(PID: Process ID)。
    • net命名空间: 使用在管理网络接口(NET: Networking
    • ipc命名空间: 使用在管理进程间通信资源 (IPC: InterProcess Communication)
    • mnt命名空间: 使用在管理挂载点 (MNT: Mount)。
    • uts命名空间: 使用在隔离内核和版本标识 (UTS: Unix Timesharing System)。
  • 群组控制(cgroup)

    Docker还使用到了cgroups技术来管理群组。使应用隔离运行的关键是让它们只使用你想要的资源。这样可以确保在机器上运行的容器都是良民(good multi-tenant citizens)。群组控制允许Docker分享或者限制容器使用硬件资源。例如,限制指定的容器的内容使用

  • 联合文件系统(UnionFS)

    联合文件系统(UnionFS)是用来操作创建层的,使它们轻巧快速。Docker使用UnionFS提供容器的构造块。Docker可以使用很多种类的UnionFS包括AUFS, btrfs, vfs, and DeviceMapper。

结语

  • 为什么使用go语言实现docker
    部署简单,依赖性小,开发效率高(相比C/C++),性能好(相比JAVA)
  • docker与LXC的联系
    在我理解,docker是LXC的一个高速引擎
  • 为什么我只解析了docker实现思想
    我不会go语言,也不了解LXC,我只是一个使用者,只是在自己的理解下探讨docker实现了什么。