Electronic Joint Business

Solution for E-Business

container

为 Windows containers 实现资源控制 (一) 作业对象

Windows 可以按容器或者按资源来实施资源控制。默认情况下, 运行的容器受 Windows 资源管理的约束, 以公平分配为原则, 但通过资源控制,开发人员或管理员可以限制或影响资源的使用。可控制的资源包括: CPU/处理器、内存/RAM、磁盘/存储、和网络/吞吐量等等。

Windows 容器利用作业对象(job objects)来对每个容器相关联的进程进行分组和跟踪。资源控制则在与容器关联的父作业对象上实施。 在 Hyper-V 隔离的情况下,系统同时对虚拟机和在虚拟机中运行的容器的作业对象进行自动资源控制,这样即使容器中运行的进程绕过了或逃脱了作业对象控制,虚拟机也会确保其无法越过定义的资源控制。

作业对象
Windows提供一个作业(job)内核对象,它允许我们将进程组合在一起并创建一个“沙箱”来限制进程能够做什么。作业对象允许将进程组作为一个单元进行管理。作业对象是可命名的(namable)、安全的、共享的对象, 可控制与之关联的进程的属性。对作业对象执行的操作会影响和作业对象相关联的所有进程。比如对工作集大小、进程优先级进行强制限制,或终止与作业关联的所有进程。你可以将作业对象想象成一个进程容器。但是,创建只包含一个进程的作业同样非常有用,因为这样可以对进程施加平时不能施加的限制。

作业对象 VS Linux 控制组 cgroups
Linux 的 cgroups 不等同于 Windows 和 VMS 的作业, 它缺乏作业机制的真正功能。这些年来人们一直在抱怨 Systemd 的这个问题,他们非常期待 cgroups 2.0 能提供真正的作业机制,因为现阶段的 Systemd 存在严重的错误,它无法自动终止控制组中的所有内容。

相反,提供“作业”抽象的操作系统内核一般都会提供了能取消/终止整个“作业”的方法,比如 Windows 的 TerminateJobObject()。而对于 Systemd,当其终止 cgroup 中的所有进程时, 它无法执行类似“终止作业”的系统调用,因为根本不存在这种机制。作为替代,Systemd 在应用模式下的某段循环代码中反复扫描 cgroup 中的所有进程 id,它重读一个 PID 列表文件, 并将信号发送到未列其中的新进程。这会带来几个问题:

>>> 阅读全文

 

, , ,

初窥 Windows Container 和 Docker

抽象地说所有的计算都是在一系列物理资源上(包括处理器、 内存、 磁盘、 网络等)运行某些”功能”以达成特定任务,这些计算可以是简单的数学运算,比如“1+1”,也可以是跨越多台机器的复杂应用比如 Exchange。随着时代的进步,物理资源越来越强大,结果应用程序常常只利用了物理机所提供的资源的一小部分。因而,工程师们通过创建“虚拟”资源来模拟底层物理硬件,从而使得多个应用可以并发运行 — — 每个应用使用同一物理机器的部分物理资源。

通常这些模拟技术被称为虚拟化。“虚拟化”一词会让很多人联想到虚拟机。不过“虚拟机”只是虚拟化的一种实现,而容器是另一种类型的虚拟化,也称为操作系统虚拟化。以 Linux 容器为例:在一个 Linux 操作系统中可以创建多个容器,对于运行在容器中的应用程序来说,该 Linux 容器就是一个完全隔离且独立的“操作系统”,它的磁盘就像保存原始 OS 文件的副本,内存驻留的文件和数据也和正常启动的操作系统没什么区别。要实现要做到这一点,创建容器的”宿主”机要实现一系列技术。1

首先是名称空间隔离。名称空间包含了应用程序可交互的一切资源,包括文件、 网络端口和活跃进程的列表。通过名称空间隔离,宿主可以为每个容器分配一个虚拟名称空间,其中包含只对该容器可见的资源。在此受限视图中,无论容器运行在什么权限上,它都无法访问其名称空间之外的文件,就是因为这些文件对容器不可见。容器也无法查看该容器外的应用,当然也无法与之交互,所以容器中的应用就会错认为自己独占了整个系统(其实同一时刻还可能还有成十上百个应用在运行)。

出于效率考虑,宿主操作系统的许多文件、目录以及运行服务都被不同容器所共享,并被投影到每个容器的名称空间中。只有当应用程序改动到其容器,容器才会从底层主机操作系统获得一个独立副本 — 但只是包含被改动的那部分文件。这就是 “Docker” 的“copy-on-write”优化。通过共享单个主机可以高效地部署多个容器。

其次需要宿主管控可供容器使用的主机资源。管控诸如 CPU、 RAM和网络带宽等等资源,可以确保容器获得其预期的资源且不影响主机上其他容器的性能。例可以约束某个容器使得它的 CPU 占用率不得超过 10%。这意味着即使应用程序努力尝试,它也不能获得其他 90% CPU 占用,这部分 CPU 主机可以将分配给其他容器或供自己使用。Linux 使用称为 “cgroups” 的技术来实现这种管控。当然如果同一主机上的不同容器之间是相互协作的,并允许主机根据应用的实际需求变化不断动态调整资源分配,此时就无需资源管控。

>>> 阅读全文

 

, ,