本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫。

推荐大家到公众号阅读,那里阅读体验更好,也沉淀了很多篇干货。

前面两篇文章我们总结了 Docker 背后使用的资源隔离技术 Linux namespace。

Docker 基础技术之 Linux namespace 详解

Docker 基础技术之 Linux namespace 源码分析

本篇将讨论另外一个技术——资源限额,这是由 Linux cgroups 来实现的。

cgroups 是 Linux 内核提供的一种机制,这种机制可以根据需求把一系列任务及子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。(来自 《Docker 容器与容器云》)

通俗来说,cgroups 可以限制和记录任务组(进程组或线程组)使用的物理资源(包括 CPU、内存、IO 等)。

为了方便用户(程序员)操作,cgroups 以一个伪文件系统的方式实现,并对外提供 API,用户对文件系统的操作就是对 cgroups 的操作。

从实现上来,cgroups 实际上是给每个执行任务挂了一个钩子,当任务执行过程中涉及到对资源的分配使用时,就会触发钩子上的函数对相应的资源进行检测,从而对资源进行限制和优先级分配。

cgroups 的作用

总结下来,cgroups 提供以下四个功能:

资源限制:cgroups 可以对任务使用的资源总额进行限制,如设定应用运行时使用内存的上限,一旦超过这个配额就发出 OOM(Out of Memory)提示。

优先级分配:通过分配的 CPU 时间片数量和磁盘 IO 带宽大小,实际上就相当于控制了任务运行的优先级。

资源统计:cgroups 可以统计系统的资源使用,如 CPU 使用时长、内存用量等,这个功能非常适用于计费。

任务控制:cgroups 可以对任务执行挂起、恢复等操作。

cgroups 的子系统

cgroups 在设计时根据不同的资源类别分为不同的子系统,一个子系统本质上是一个资源控制器,比如 CPU 资源对应 CPU 子系统,负责控制 CPU 时间片的分配,内存对应内存子系统,负责限制内存的使用量。进一步,一个子系统或多个子系统可以组成一个 cgroup,cgroups 中的资源控制都是以 cgroup 为单位来实现,一个任务(或进程或线程)可以加入某个 cgroup,也可以从一个 cgroup 移动到另一个 cgroup,但这里有一些限制,在此就不再赘述了,详细查阅相关资料了解。

对于我们来说,最关键的是知道怎么用,下面就针对 CPU、内存和 IO 资源来看 Docker 是如何使用的?

对于 CPU,Docker 使用参数 -c 或 --cpu-shares 来设置一个容器使用的 CPU 权重,权重的大小也影响了 CPU 使用的优先级。

如下,启动两个容器,并分配不同的 CPU 权重,最终 CPU 使用率情况:

docker run --name "container_A" -c 1024 ubuntu
docker run --name "container_B" -c 512 ubuntu

当只有一个容器时,即使指定较少的 CPU 权重,它也会占满整个 CPU,说明这个权重只是相对权重,如下将上面的 “container_A” 停止,“container_B” 就分配到全部可用的 CPU。

对于内存,Docker 使用 -m(设置内存的限额)和 --memory-swap(设置内存和 swap 的限额)来控制容器内存的使用量,如下,给容器限制 200M 的内存和 100M 的 swap,然后给容器内的一个工作线程分配 280M 的内存,因为 280M 在容许的 300M 范围内,没有问题。其内存分配过程是不断分配又释放,如下:

如果让工作线程使用内存超过 300M,则出现内存超限的错误,容器退出,如下:

对于 IO 资源,其使用方式与 CPU 一样,使用 --blkio-weight 来设置其使用权重,IO 衡量的两个指标是 bps(byte per second,每秒读写的数据量) 和 iops(io per second, 每秒 IO 的次数),实际使用,一般使用这两个指标来衡量 IO 读写的带宽,几种使用参数如下:

  • --device-read-bps,限制读某个设备的 bps。

  • --device-write-bps,限制写某个设备的 bps。

  • --device-read-iops,限制读某个设备的 iops。

  • --device-write-iops,限制写某个设备的 iops。

假如限制容器对其文件系统 /dev/sda 的 bps 写速率为 30MB/s,则在容器中用 dd 测试其写磁盘的速率如下,可见小于 30MB/s。

如果是正常情况下,我的机器可以达到 56.7MB/s,一般都是超 1G 的。

上面几个资源使用限制的例子,本质上都是调用了 Linux kernel 的 cgroups 机制来实现的,每个容器创建后,Linux 会为每个容器创建一个 cgroup 目录,以容器的 ID 命名,目录在 /sys/fs/cgroup/ 中,针对上面的 CPU 资源限制的例子,我们可以在 /sys/fs/cgroup/cpu/docker 中看到相关信息,如下:

其中,cpu.shares 中保存的就是限制的数值,其他还有很多项,感兴趣可以动手实验看看。

总结

cgroups 的作用,cgroups 的实现,cgroups 的子系统机制,CPU、内存和 IO 的使用方式,以及对应 Linux 的 cgroups 文件目录。


我的公众号 「Linux云计算网络」(id: cloud_dev) ,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。

Docker 基础技术之 Linux cgroups 详解的更多相关文章

  1. Docker 基础技术之 Linux namespace 详解

    Docker 是"新瓶装旧酒"的产物,依赖于 Linux 内核技术 chroot .namespace 和 cgroup.本篇先来看 namespace 技术. Docker 和虚 ...

  2. Docker基础技术:Linux Namespace(下)

    在 Docker基础技术:Linux Namespace(上篇)中我们了解了,UTD.IPC.PID.Mount 四个namespace,我们模仿Docker做了一个相当相当山寨的镜像.在这一篇中,主 ...

  3. Docker 基础技术:Linux Namespace(下)

    导读 在Docker基础技术:Linux Namespace(上篇)中我们了解了,UTD.IPC.PID.Mount 四个namespace,我们模仿Docker做了一个相当相当山寨的镜像.在这一篇中 ...

  4. Docker基础技术:Linux Namespace(上)

    时下最热的技术莫过于Docker了,很多人都觉得Docker是个新技术,其实不然,Docker除了其编程语言用go比较新外,其实它还真不是个新东西,也就是个新瓶装旧酒的东西,所谓的The New “O ...

  5. Docker基础技术:Linux CGroup

    前面,我们介绍了Linux Namespace,但是Namespace解决的问题主要是环境隔离的问题,这只是虚拟化中最最基础的一步,我们还需要解决对计算机资源使用上的隔离.也就是说,虽然你通过Name ...

  6. 『现学现忘』Docker基础 — 34、DockerFile文件详解

    目录 1.DockerFile文件说明 2.Dockerfile构建过程解析 (1)Docker容器构建三步骤 (2)Dockerfile文件的基本结构 (3)Dockerfile注意事项 (4)Do ...

  7. Docker 基础技术之 Linux namespace 源码分析

    上篇我们从进程 clone 的角度,结合代码简单分析了 Linux 提供的 6 种 namespace,本篇从源码上进一步分析 Linux namespace,让你对 Docker namespace ...

  8. Linux Cgroups详解(一)

    [转载]http://blog.chinaunix.net/uid-23253303-id-3999432.html Cgroups是什么? Cgroups是control groups的缩写,是Li ...

  9. Java工程师 基础+实战 完整路线图(详解版)

    Java工程师 基础+实战 完整路线图(详解版)   Java 基础 Java 是一门纯粹的面向对象的编程语言,所以除了基础语法之外,必须得弄懂它的 oop 特性:封装.继承.多态.此外还有泛型.反射 ...

随机推荐

  1. 插件开发之360 DroidPlugin源码分析(四)Activity预注册占坑

    请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52258434 在了解系统的activity,service,broa ...

  2. 安卓java.lang.IllegalStateException: The specified child already has a parent.解决方案

    在使用ViewPager的时候遇到一个错误java.lang.IllegalStateException: The specified child already has a parent. You ...

  3. 浅谈C语言 extern 指针与数组

    /* * d.c * * Created on: Nov 15, 2011 * Author: root */ #include "apue.h" int a[] = {3,2}; ...

  4. Request中Attribute 和 Parameter 的区别

    Attribute 和 Parameter 的区别 (1)HttpServletRequest类有setAttribute()方法,而没有setParameter()方法 (2)当两个Web组件之间为 ...

  5. popupwindow和listview

    在使用PopupWindow的时候,有一个不好的地方就是不太好设置弹出窗体的大小.如果指定绝对大小,那么对于不同分辨率不同尺寸的手机来说,显示出来效果会不同,从而导致用户体验不佳. 为了达到Popup ...

  6. [GitHub]第三讲:简单分支操作

    Git 最核心的操作对象是版本( commit ),最核心的操作技巧就是分支. 什么是分支? 仓库创建后,一旦有了新 commit,默认就会放到一个分支上,名字叫 master.前面咱们一直看到的多个 ...

  7. xpath技术解析xml以及案例模拟用户登录效果

    问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦!!! xpath就在此情况下产生了--主要是用于快速获取所需的[节点对象]. 在dom4j中如何使用xPath技术 1) ...

  8. Java Web 高性能开发,第 1 部分: 前端的高性能

    Web 发展的速度让许多人叹为观止,层出不穷的组件.技术,只需要合理的组合.恰当的设置,就可以让 Web 程序性能不断飞跃.所有 Web 的思想都是通用的,它们也可以运用到 Java Web.这一系列 ...

  9. eclipse导入已有工程

    eclipse不同的版本,导致导入已有工程的方法不同.老版本中使用的是新建java工程,然后选择根据已经存在的project创建,就可以了. 但我的是version: Helios Service R ...

  10. 海量数据挖掘MMDS week2: Association Rules关联规则与频繁项集挖掘

    http://blog.csdn.net/pipisorry/article/details/48894977 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...