《Docker容器与容器云》读书笔记

谁都会走 提交于 2020-04-26 23:38:19

云计算平台

云计算是一种资源的服务模式,该模式可以实现随时随地、便捷按需地从可配置计算资源共享池中获取所需资源(如网络、服务器、存储、应用及服务),资源能够快速供应并释放,大大减少了资源管理工作开销。

 

Docker

Docker是以Docker容器为资源分割和调度的基本单位,封装整个软件运行时环境,为开发者和系统管理员设计的,用于构建、发布和运行分布式应用的平台。它是一个跨平台、可移植并且简单易用的容器解决方案。Docker的源代码托管在GitHub上,基于Go语言开发并遵从Apache 2.0协议。Docker可在容器内部快速自动化地部署应用,并通过操作系统内核技术(namespacecgroups等)为容器提供资源隔离与安全保障。

 

  • 持续部署与测试:开发人员使用镜像镜像实现标准开发环境的构建,开发完成后通过封装着完整环境和应用的镜像进行迁移。

  • 跨平台支持

  • 环境标准化和版本控制

  • 高资源利用率与隔离:容器没有管理程序的额外开销,与底层共享操作系统,系统负载更低

  • 容器跨平台性与镜像:构建一次,到处运行

  • 易于理解且易用

  • 应用镜像仓库

 

容器云

容器云以容器为资源分割和调度的基本单位,封装整个软件运行时环境,为开发者和系统管理员提供用于构建、发布和运行分布式应用的平台。当容器云专注于资源共享与隔离、容器编排与部署时,它更接近传统的IaaS;当容器云渗透到应用支持与运行时环境使,它更接近传统的PaaS

 

namespace资源隔离


  Docker容器本质上是宿主机上的进程。Docker通过namespace实现了资源隔离,通过cgroups实现了资源限制,通过写时复制机制(copy-on-write)实现了高效的文件操作

    Docker的namespace一般有以下几种。如果两个进程指向的namespace编号相同,就说明它们在同一个namespace下,否则便在不同的namespace里面

  Linux内核实现namespace的一个主要目的就是实现轻量级虚拟化容器服务,在同一个namespace下的进程可以感知彼此的变化,而对外界的进程一无所知,以达到独立和隔离的目的。

root@ht:~# ls -l /proc/$$/ns
total 0
lrwxrwxrwx 1 root root 0 7月   9 20:00 cgroup -> cgroup:[4026531835]
lrwxrwxrwx 1 root root 0 7月   9 20:00 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 7月   9 20:00 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 7月   9 20:00 net -> net:[4026531957]
lrwxrwxrwx 1 root root 0 7月   9 20:00 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 7月   9 20:00 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 7月   9 20:00 uts -> uts:[4026531838]

  1)UTS namespace

UTS(UNIX Time-sharing System)namespace提供了主机名和域名的隔离,这样每个Docker容器就可以拥有独立的主机名和域名了,在网络上可以被视为一个独立的节点。

  2)IPC namespace

进程间通信(Inte-process Communication,IPC)涉及的IPC资源包括常见的信号量、消息队列和共享内存。申请IPC资源就申请了一个全局唯一的32位ID,所以IPC namespace中实际上包含了系统IPC标识符以及实现POSIX消息队列的文件系统。在同一个IPC namespace下的进程彼此可见,不同IPC namespace下的进程则互相不可见。

Docker当前使用IPC namespace实现了容器与宿主机、容器与容器之间的IPC隔离  

  3)PID namespace

PID namespace对进程PID重新标号,即两个不同namespace下的进程可以有相同的PID。每个PID namespace都有自己的计数程序。内核为所有的PID namespace维护了一个树状结构,最顶层的是系统初始时创建的,被称为root namespace。它创建的新PID namespace被称为child namespace,而原先的PID namespace就新创建的PID namespace的parent namespace。通过这种方式,不同的PID namespace会形成一个层次体系。所属的父节点可以看到子节点的进程,并可以通过信号等方式对子节点中的进程产生影响,但子节点却不能看到夫节点PID namespace中的任何内容。

  4)mount namespace

mount namespace通过隔离文件系统挂载点对隔离文件系统提供支持。隔离后不同mount namespace中的文件结构发生变化也互不影响。进程在创建mount namespace时,会把当前的文件结构复制给新的namespace。新namespace中的所有mount操作都只影响自身的文件系统。

    共享关系:如果两个挂载对象具有共享关系,那么一个挂载对象中的挂载事件会传播到另一个挂载对象,反之亦然

    从属关系:如果两个挂载对象形成从属关系,那么一个挂载对象中的挂载事件会传播到另一个挂载对象,但是反之不行。从属对象是事件的接收者。

   5)network namespace

network namespace主要提供关于网络资源的隔离,包括网络设备、IPv4和IPv6协议栈、IP路由表、防火墙、、socket等。一个物理的网络设备最多存在于一个network namespace中,可以通过创建veth pair(虚拟网络设备对:有两端,类似通道)在不同的network namespace间创建通道,以达到通信目的。

  6)user namespace

user namespace主要隔离了安全相关的标志符(identifier)和属性(attribute),包括用户ID,用户组ID,root目录,密钥及特殊权限。一个普通用户的进程通过clone()创建的新进程在新user namespace中可以拥有不同的用户和用户组。这意味着一个进程在容器外属于一个没有特权的普通用户,但是它创建的容器进程却属于拥有所有权限的超级用户 

 

cgroups资源限制

  cgroups是linux内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。通俗地说,cgroups可以限制、记录任务组所使用的物理资源(包括CPU,Memory,IO等)。本质上来说,cgroups是内核附加在程序上的一系列钩子(hook),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。

  cgroups有如下四个特点:

    1)cgroups的API以一个伪文件系统的方式实现,用户态的程序可以通过文件操作实现cgroups的组织管理

    2)cgroups的组织管理操作单元可以细粒度到线程级别,另外用户可以创建和销毁cgroup,从而实现资源再分配和管理

    3)所有资源管理的功能都以子系统的方式实现,接口统一

    4)子任务创建之初与其父任务处于同一个cgroups的控制组

 

  cgroups有以下四大功能:

    1)资源限制:对任务使用的资源总额进行限制

    2)优先级分配:控制分配的CPU时间片数及磁盘IO带宽的大小

    3)资源统计:统计系统的资源使用量

    4)任务控制:对任务执行挂起、恢复等操作

 

  cgroups术语

    task(任务):表示系统的一个进程或线程

    cgroup(控制组):表示按某种资源控制标准划分而成的任务组。包含一个或多个子系统。一个任务可以加入某个cgroup,也可以从某个cgroup迁移到另外一个cgroup.

    subsystem(子系统):资源调度控制器

    hierarchy(层级):层级由一系列cgroup以树状结构排列而成,每个层级通过绑定对应的子系统进行资源控制。层级中的cgroup节点可以包含零或多个子节点,子节点继承夫节点挂载的子系统。整个操作系统可以有多个层级。

 

Docker总体架构

  

Docker daemond

  从图中可以看出Docker daemon是Docker最核心的后台进程,它负责响应来自Docker client的请求,然后将这些请求翻译成系统调用完成容器管理操作。该进程会在后台启动一个API Server,负责接收由Docker client发送的请求;接收到的请求将通过Docker daemon分发调度,再由具体的函数来执行请求。

  execdriver是对Linux操作系统的namespace、cgroups、apparmor等容器运行所需的系统进行的一层二次封装。execdriver的默认实现是Docker官方编写的libcontainer库

  network由libnetwork库独立维护。libnetwork库抽象出了一个容器网络模型(Container Network Model, CNM),并给调用者提供一个统一的抽象接口,

  graphdriver是所有与容器镜像相关操作的最终执行者。graphdriver会在Docker工作目录下维护一组与镜像层对应的目录,并记下镜像层之间的关系以及与具体的graphdriver实现相关的元数据。这样用户对镜像的操作最终会被映射成对这些目录文件以及元数据的增删查改,从而屏蔽掉不同文件存储实现对于上层调用者的影响。

Docker client

  Docker client是一个泛称,用来向Docker daemon发起请求,执行相应的容器管理操作。它既可以是命令行工具Docker,也可以是任何遵循了Docker API的客户端

镜像管理

  distribution负责与Docker registry交互,上传下载镜像以及存储与v2 registry有关的元数据

  registry模块负责与Docker registry有关的身份验证、镜像查找、镜像验证以及管理registry mirror等交互操作

  image模块负责与镜像元数据有关的存储、查找,镜像层的索引、查找以及镜像tar包有关的导入导出等操作。

  reference负责存储本地所有镜像的repository和tag名,并维护与镜像ID之间的映射关系

  layer模块负责与镜像层和容器元数据有关的增删查改,并负责将镜像层的增删查改操作映射到实际存储镜像层文件系统的graphdriver模块

volumedriver是volume数据卷存储操作的最终执行者,负责volume的增删查改,屏蔽不同的驱动实现的区别,为上层调用者提供一个统一的接口。Docker中作为默认实现的volumedriver是local,默认将文件存储在Docker根目录的volume文件夹里。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!