专栏首页aCloudDeveloperDocker 基础技术之 Linux cgroups 详解

Docker 基础技术之 Linux cgroups 详解

前面两篇文章我们总结了 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 文件目录。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 雾计算简史

    欢迎关注我的个人公众号 aCloudDeveloper,打造云计算干货分享平台,你值得拥有。 在我看来,雾计算和云计算的本质是一样的——都是充分利用「闲置的资...

    CloudDeveloper
  • 初识云计算:历史、服务、架构

    我们主要从用户对云计算的认知角度来谈云计算的发展史,至于它从提出到发扬光大的那些大事件,网上搜下就知道了,而且我觉得去谈那些发展事件意义也不大,倒不如说说我们对...

    CloudDeveloper
  • 一文掌握 Linux 性能分析之内存篇

    这个文件记录着比较详细的内存配置信息,使用 cat /proc/meminfo 查看。

    CloudDeveloper
  • 性能工具之linux监控之top、vmstat、iostat复习

    Ø d 指定每两次屏幕信息刷新之间的时间间隔。当然用户可以使用s交互命令来改变之。

    高楼Zee
  • 性能测试-cpu负载和cpu利用率

    CPU使用率指的是程序在运行期间实时占用的CPU百分比,这是对一个时间段内CPU使用状况的统计。

    飞天小子
  • 数据结构:链表

    工程代码 Github: Data_Structures_C_Implemention -- Link List

    半纸渊
  • 请你讲讲数组(Array)和列表(ArrayList)的区别?什么时候应该使用Array而不是ArrayList?

    ③ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。

    剑走天涯
  • 操作系统之内存管理内存管理3.1 内存管理的概念3.2 内存覆盖与内存交换3.3 内存连续分配管理方式3.4 内存非连续分配管理方式

    JavaEdge
  • kubelet cpu 管理策略

    默认情况使用CFS(完全公平的调度程序),CFS情况下指定进程的运行时间计算方式如下,

    有点技术
  • Redis开发与运维学习笔记---(12)

    Redis是典型的单线程架构,所有的读写都是在一条主线程中完成的,在高并发场景中,一旦这条主线程出现了阻塞,哪怕是很短的时间,对于应用的影响都是巨大的。

    AsiaYe

扫码关注云+社区

领取腾讯云代金券