【期末复习】Docker(2)

Docker期末复习-2

  • 2-1.容器
  • 2-2.容器虚拟化技术(namespace:隔离加作用;Cgroup:资源限制)
  • 2-3.Namespace
  • 2-4.Cgroup定义,作用,术语表,关系(4个规则)

2-1.容器

定义:容器就是一个认为只有其本身在运行状态的linux程序,只服从用户指定的命令,是一个独立的运行环境,对应用程序和关联性进行隔离,构建一套可以随时运行的自容纳系统。

  1. 容器程序有自己的IP地址
  2. 一个可访问网络的独立设备

2-2.容器虚拟化技术(namespace:隔离加作用;Cgroup:资源限制)

容器虚拟化技术的内核:Namespace+Cgroup

  1. Namespace
    程序运行环境的隔离
    基本原理:将内核中的全局变量改为per-namespace变量
  2. Cgroup
    计算资源的QoS:CPU、内存、磁盘IO、网络IO

容器与虚拟机对比:
【期末复习】Docker(2)_第1张图片

Docker(容器虚拟化技术)与传统虚拟化技术对比:
【期末复习】Docker(2)_第2张图片

2-3.Namespace

Linux Namespace是Linux提供的一种内核级别环境隔离的方法。
[以前的Unix有一个叫chroot(change root dictionary)的系统调用(通过修改根目录把用户jail到一个特定目录下),chroot提供了一种简单的隔离模式:chroot内部的文件系统无法访问外部的内容。]
Linux Namespace在chroot基础上,提供了对UTS、IPC、mount、PID、network、User等的隔离机制。
【期末复习】Docker(2)_第3张图片
它可以隔离一系列系统的资源,比如PID(Process ID),User,ID, Network等等
在linux内核2.6之前,PID,UID等系统资源是全局性的。
在linux内核2.6之后,PID,UID等系统资源是属于特定Namespace的。
【期末复习】Docker(2)_第4张图片

  • Namespace的六项隔离
类型 隔离内容
MNT Namespace 挂载点(文件系统)
IPC Namespqce 进程间通信(信号量、消息队列和共享内存)
NET Namespace 网络设备、网络栈、端口等等
UTS Namespace 主机名与域名
PID Namespace 进程编号
USER Namespace 用户和用户组
  1. MNT Namespace
    共享挂载(shared mount):传播事件的挂载对象
    从属挂载(slave mount):接收传播事件的挂载对象
    共享/从属挂载(shared and slave):同时兼有前述两者特征的挂载对象
    私有挂载(private mount):既不传播也不接收传播事件的挂载对象
    不可绑定的挂载(unbindable mount):与私有挂载相似,但是不允许执行绑定挂载,即创建mount namespace时这块文件对象不可被复制。
    通过下图可以更好地了解它们的状态变化:
    【期末复习】Docker(2)_第5张图片

  2. IPC Namespace
    进程间通信(Inter-Process Communication,IPC)涉及到的IPC资源包括常见的信号量、消息队列和共享内存。然而与虚拟机不同的是,容器内部进程间通信对宿主机来说,实际上是具有相同PID namespace中的进程间通信,因此需要一个唯一的标识符来进行区别。申请IPC资源就是申请了一个全局唯一的32位ID,所以IPC namespace中实际上包含了系统IPC标识符以及实现POSIX消息队列的文件系统。在同一个IPC namespace下的进程彼此可见,不同IPC namespace下的进程则互相不可见
    【期末复习】Docker(2)_第6张图片

  3. NET Namespace:提供独立的网络栈
    NET Namespace主要提供了关于网络资源的隔离,包括网络设备、IPv4和IPv6协议栈、IP路由表、防火墙、/proc/net目录、/sys/class/net目录、套接字(socket)等等。
    【期末复习】Docker(2)_第7张图片

  4. UTS Namespace UTS(UNIX Time-sharing System)
    提供了主机名(hostname)和域名(domainname)的隔离,这样每个Docker容器就可以拥有独立的主机名和域名,在网络上可以被视作一个独立的节点,而非宿主机上的一个进程。
    在Docker中,每个镜像基本都以自身所提供的服务名称来命名镜像的hostname,且不会对宿主机产生任何影响,其原理就是利用了UTS namespace。
    【期末复习】Docker(2)_第8张图片

  5. PID Namespace
    PID namespace隔离非常实用,它对进程PID重新标号,即两个不同namespace下的进程可以有同一个PID。每个PID namespace都有自己的计数程序。内核为所有的PID namespace维护了一个树状结构,最顶层的是系统初始时创建的,被称为root namespace。它创建的新PID namespace就称为child namespace(树的子节点),而原先的PID namespace就是新创建的PID namespace的parent namespace(树的父节点)。通过这种方式,不同的PID namespaces会形成一个层级体系。所属的父节点可以看到子节点中的进程,并可以通过信号等方式对子节点中的进程产生影响。反过来,子节点不能看到父节点PID namespace中的任何内容,由此产生如下结论:
    ① 每个PID namespace中的第一个进程“PID 1”,都会像传统Linux中的init进程一样拥有特权,起特殊作用。
    ② 一个namespace中的进程,不可能通过kill或ptrace影响父节点或者兄弟节点中的进程,因为其他节点的PID在这个namespace中没有任何意义。
    ③ 如果你在新的PID namespace中重新挂载/proc文件系统,会发现其下只显示同属一个PID namespace中的其他进程。
    ④ 在root namespace中可以看到所有的进程,并且递归包含所有子节点中的进程。【期末复习】Docker(2)_第9张图片

  6. USER Namespace
    USER Namespace主要隔离了安全相关的标识符(identifiers)和属性(attributes),包括用户ID、用户组ID、root目录、key(指密钥)以及特殊权限。
    通俗地讲,一个普通用户的进程通过clone()创建的新进程在新user namespace中可以拥有不同的用户和用户组。这意味着一个进程在容器外属于一个没有特权的普通用户,但是他创建的容器进程却属于拥有所有权限的超级用户,这个技术为容器提供了极大的自由。
    Linux中,特权用户的user ID就是0。
    【期末复习】Docker(2)_第10张图片【期末复习】Docker(2)_第11张图片

  • 小结
    namespace从进程、网络、IPC、文件系统、UTS和用户角度的隔离,一个container就可以对外展现出一个独立计算机的能力, 并且不同container从OS层面实现了隔离。 然而不同namespace之间资源还是相互竞争的,仍然需要类似ulimit来管理每个container所能使用的资源。
    【期末复习】Docker(2)_第12张图片
    分类:6种类型
    主要目的:实现轻量级的虚拟化(容器)服务
    表现:同一个namespace进程感知彼此存在,之外的一无所知

2-4.Cgroup定义,作用,术语表,关系(4个规则)

  1. 定义
  • 任务放到一个组里面统一加以控制。
  • 官方定义:Linux内核提供的一种机制,根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内。为系统资源管理提供一个统一的框架。
  1. 作用
    ① 资源限制:cgroups可以对任务使用的资源总额进行限制。如设定应用运行时使用内存的上限,一旦超过这个配额就发出OOM(Out of Memory)。
    ② 优先级分配:通过分配的CPU时间片数量及硬盘IO带宽大小。实际上就相当于控制了任务运行的优先级。
    ③ 资源统计:统计系统的资源使用量,如CPU使用时长、内存用量等等。这个功能非常适用于计费。
    ④ 任务控制:对任务执行挂起、恢复等操作。
  2. 术语表
    task(任务):表示系统的一个进程或线程。
    control group(控制族群):表示按某种资源控制标准划分而成的任务组 ,包含一个或多个子系统。cgroups 中的资源控制都以cgroup为单位实现,一个任务可以加入某个cgroup,也可以从某个cgroup迁移到另外一个cgroup。
    subsystem(子系统):就是资源调度控制器。比如CPU子系统可以控制CPU时间分配,内存子系统可以限制cgroup内存使用量。
    hierarchy(层级):层级,由一系列cgroup以一个树状结构排列而成,每个层级通过绑定对应的子系统进行资源控制。层级中的cgroup节点可以包含零或多个子节点,每个节点都是一个cgroup,子节点继承父节点挂载的属性。整个系统可以有多个层级。
  3. 关系(选择题)
    规则1: 同一个层级可以附加一个或多个子系统。如下图,CPU和Memory的子系统附加到了一个层级。
    【期末复习】Docker(2)_第13张图片
    规则2: 一个子系统可以附加到多个层级,当且仅当这些层级只有这唯一一个子系统时。如下图所示,小圈中的数字表示子系统附加的时间顺序,CPU 子系统附加到层级A的同时不能再附加到层级B,因为层级B已经附加了内存子系统。如果层级B没有附加过内存子系统,那么CPU 子系统同时附加到两个层级是允许的。

【期末复习】Docker(2)_第14张图片
规则3: 系统每次新建一个层级时,该系统上的所有任务默认构成了这个新建的层级的初始化cgroup,这个cgroup也称为root cgroup。对于创建的每个层级,任务只能存在于其中一个cgroup中,即一个任务不能存在于同一个层级的不同cgroup中,但是一个任务可以存在在不同层级中的多个cgroup中。如果操作时把一个任务添加到同一个层级中的另一个cgroup中,则会从第一个cgroup中移除。在下图中可以看到,httpd进程已经加入到层级 A中的/cg1而不能加入同一个层级中的/cg2,但是可以加入层级B中的/cg3。
【期末复习】Docker(2)_第15张图片
规则4: 任务在fork/clone自身时创建的子任务默认与原任务在同一个cgroup中,但是子任务允许被移动到不同的cgroup中。即fork/clone完成后,父子任务间在cgroup方面是互不影响的。下图中小圈中的数字表示任务出现的时间顺序,当httpd刚fork出另一个httpd时,两者在同一个层级中的同一个cgroup中。但是随后如果PID为4840的httpd需要移动到其他cgroup也是可以的,因为父子任务间已经独立。总结起来就是:初始化时子任务与父任务在同一个cgroup,但是这种关系随后可以改变。
【期末复习】Docker(2)_第16张图片
5. 子系统简介
子系统实际上就是cgroups的资源控制系统,每种子系统独立地控制一种资源,目前Docker使用如下九种子系统,其中,net_cls任务子系统在内核中已经广泛实现,但是Docker尚未使用。以下是它们的用途:

  • blkio:设置限制每个块设备的输入/输出控制,比如物理驱动设备(包括磁盘、固态硬盘、USB等)。
  • cpu:使用调度程序为cgroup任务提供CPU的访问。
  • cpuacct:自动生成cgroup中任务对CPU资源使用情况的报告。
  • cpuset:可以为cgroup中的任务分配独立的CPU(此处针对多处理器系统)和内存。
  • devices:可以开启或关闭cgroup中任务对设备的访问。
  • freezer:可以挂起(暂停)或恢复cgroup中的任务。
  • memory:可以设定cgroup中任务对内存使用量的限定,并且自动生成这些任务对内存资源使用情况的报告。
  • perfevent:使用后使cgroup中的任务可以进行统一的性能测试。增加了对每个cgroup中的任务的检测跟踪能力。
  • net_cls:标记每个网络包以供cgroup方便使用。Docker没有直接使用它,它通过使用等级识别符(classid)标记网络数据包,从而允许Linux流量控制程序(Traffic Controller,TC)识别从具体cgroup中生成的数据包。

参考链接:
Docker基础技术 Linux Namespace(上)
Docker基础技术 Linux Namespace(下)
Docker背后的内核知识(一)namespace资源隔离
Docker背后的内核知识(一)cgroups资源限制

你可能感兴趣的:(期末复习)