Linux虚拟化:使用cGroup限制资源

在里面 Linux虚拟化——Chroot监狱 在本文中,我们讨论了内核名称空间和进程监禁。要理解这篇文章,您可能不需要阅读前面的一篇,但我强烈建议您在深入研究资源节流之前先阅读一次。它应该对理解正在发生的事情有很大帮助。

null

什么是cGroup?

cgroups(缩写为control groups)是一种Linux内核功能,它限制、解释并隔离一组进程的资源使用(CPU、内存、磁盘I/O、网络等)。 该功能最初由谷歌的两名工程师开发,名为“进程容器”,但后来以“cgroups”的名称并入Linux内核主线。

为什么需要它?

cgroups的设计目标之一是为许多不同的用例提供统一的接口,从控制单个进程(例如通过使用nice)到整个操作系统级别的虚拟化。简而言之,cgroups提供:

  • 资源限制: 可以将组设置为不超过配置的内存限制,该限制还包括文件系统缓存。
  • 优先顺序—— 一些组可能会获得更大的CPU利用率或磁盘I/O吞吐量份额。
  • 会计- 衡量一个组的资源使用情况,例如,可能用于计费目的。
  • 控制—— 冻结进程组、它们的检查点和重新启动。

它们是如何直接或间接使用的?

控制组可以以多种方式使用:

  1. 通过手动访问cgroup虚拟文件系统。
  2. 通过使用cgcreate、cgexec和cgclassify(来自libcgroup)等工具动态创建和管理组。
  3. 通过“规则引擎守护进程”,它可以自动将特定用户、组或命令的进程移动到其配置中指定的cGroup。
  4. 通过其他使用cgroups的软件,如Docker、Linux容器(LXC)虚拟化、libvirt、systemd、Open Grid Scheduler/Grid Engine和谷歌的lmctfy,间接实现。

你可能会感到惊讶,但这个无声的守护进程在你的在线体验中占了很大一部分,因为相当多的网站使用容器/虚拟化来托管多个服务器或网站,包括NetFlix、heruko和reddit。

安装cGroup: 有些Linux版本预装了cgroups。要检查它们是否已安装/安装,请检查以下各项的输出:

$ mount | grep "^cgroup"

如果在/sys/fs/cgroup/上看到挂载的文件,那么可以直接跳到下一个主题,跳过安装部分。 第二个命令安装cgroup工具,使控制和监视控制组更容易。在本教程中,我们将使用相同的命令。我们将使用iotop实用程序监控磁盘I/O速率。

$ sudo apt-get install cgroup-bin cgroup-lite libcgroup1 cgroup-lite$ sudo apt-get install cgroup-tools$ sudo apt-get install iotop

如果您安装了cgroup,但在/sys/fs/cgroup上看不到它们,请使用以下命令:,

$ mount -t tmpfs cgroup_root /sys/fs/cgroup$ mkdir /sys/fs/cgroup/blkio$ mount -t cgroup -o blkio none /sys/fs/cgroup/blkio

例1: 我们将创建一个磁盘控制组,这样我们可以在有限的磁盘读/写可用量下运行任何进程。i、 e.我们希望限制一个进程或一组进程的读写操作。

第一步: 要创建cgroup,只需在/sys/fs/cgroup中创建一个目录,或者如果您有cgroup工具设置,那么我们可以在子系统的适当目录中使用它们。内核会自动用设置文件节点填充cgroup的目录。不过,建议使用cgroup tools API,

# Switch to root for the rest of the commands$ sudo su                    $ cgcreate -g blkio:myapp  OR  mkdir /sys/fs/cgroup/blkio/myapp

此命令将在“blkio”系统下创建一个子组“myapp”。块I/O(blkio)子系统通过CGroup中的任务控制和监视对块设备上I/O的访问。将值写入这些文件可以控制对各种资源的访问。您可以通过运行lscgroup命令来检查是否创建了组,该命令列出了所有控制组。

$ lscgroup | grep blkio:/myappblkio:/myapp

重要事项: 这些文件不是磁盘上的普通文件。这些是伪文件,内核直接使用它们来读取和修改配置。不要在文本编辑器中打开它们并尝试保存它们。始终使用“echo”命令对其进行写入。

在深入讨论简单内容之前,让我们先看看新创建的组的目录结构。以下是我们在本教程中了解cgroup如何工作所需的一些重要文件。(图中突出显示了最重要的部分)

linuxvirtualization

第二步: 我们创建了两个终端,并将它们一个置于另一个之下。成为两个终端的root用户。在顶部终端中,我们运行iotop实用程序来监控磁盘I/O,

$ sudo su$ iotop -o 

在下面的终端上,我们使用“dd”命令创建一个512MB的临时文件

$ sudo su$ dd if=/dev/zero of=~/test_if bs=1M count=512 

在dd命令中,“if”表示输入文件,“of”表示输出文件,“bs”表示块大小,“count”表示写入块的次数。一旦命令结束, ~/temp\u如果 创建的大小为512 MB。您可以在顶部的终端窗口中看到实时I/O速率。

第三步: 现在,为了下一个实验,我们需要确保已经将所有文件系统缓冲区刷新到磁盘,并删除所有缓存,以便它们不会干扰我们的结果。

$ free -m$ sync$ echo 3 > /proc/sys/vm/drop_caches$ free -m 

现在,您应该看到可用RAM的增加和缓存大小的减小。

第三步: 现在,为了设置节流限制,我们使用以下命令。比方说,我们希望为一个进程设置5MB的读/写限制。从内核文档中,你会发现,blkio。掐死阅读bps设备和blkio。掐死写入_bps _设备接受格式的条目,

哪里 专业 少数的 是特定设备的值,我们希望对其进行速率限制。 每秒速率 是该组流程可以达到的最大速率。

获取主要和次要数字很容易。我正在使用的机器只有一个磁盘/dev/sda,所以运行命令ls-l/dev/sda*我可以得到主要和次要的数字。

linuxvirtualzation2

突出显示的值是my/dev/sda磁盘的主次号。

现在,我们写入以下值,将读取速率限制为5 Mb/秒

$ echo "8:0 5242880" > /sys/fs/cgroup/blkio/myapp/blkio.throttle.read_bps_device$ cat /sys/fs/cgroup/blkip/myapp/blkio.throttle.read_bps_device 

在运行受控进程之前,我们必须了解在没有任何节流的情况下的读取速度。通过在底部终端中运行此命令,读取我们之前创建的文件。

$ dd if=~/test_if of=/dev/null 

第5步: 您可以在顶部终端中看到实时读取速率。文件创建完成后,还可以看到平均速率,该速率由dd命令显示。如前所示,将数据刷新到磁盘并删除所有缓存,以避免结果中出现任何歧义。

要在节流模式下运行此命令,我们使用cgexec

$ cgexec -g blkio:/myapp dd if=~/test_if of=/dev/null 

在这里,我们为-g参数提供:name,在本例中,它是“blkio:myapp”。顶部终端中的速率应该与此类似。

linuxvirtualzation3

有趣的是,我们可以使用任何没有内置速率限制的应用程序,我们可以根据需要对其进行限制。

linuxvirtualzation4

上面的图是在读取2个文件时绘制的,这些文件的进程属于同一个cgroup,读取限制为50 Mb/秒。正如您最初看到的,读取速率跳到了最大值,但一旦第二次读取开始,它就会达到平衡,达到预期的50MB/s。一旦“文件abc”的读取结束,速率将再次跳至最大值。

您可以通过在中回显新值来实时更改速率 布莱基奥。掐死 文件夹。内核将自动更新配置。

例2: 我们按照类似的步骤创建一个内存受限的应用程序。我将跳过解释,因为大部分内容都是相同的,直接跳到命令。

第一步: 我创建了一个简单的c程序,在每次迭代中分配1MB,并运行总共50次迭代,分配总共50MB。

// a simple c-program that allocates 1MB in each// iteration and run for a total of 50 iterations,// allocating a total of 50 MB#include <stdio.h>#include <stdlib.h>#include <string.h>int main(void){    int i;    char *p;    for (i = 0; i < 50; ++i)    {        // Allocate 1 MB each time.        if ((p = malloc(1<<20)) == NULL)        {            printf("Malloc failed at %d MB", i);            return 0;        }        memset(p, 0, (1<<20));        printf("Allocated %d to %d MB", i, i+1);    }    printf("Done!");    return 0;}
$ sudo su         # Switch to root for the rest of the commands$ cgcreate -g memory:myapp_mem  OR  mkdir /sys/fs/cgroup/memory/myapp_mem$ cd /sys/fs/cgroup/memory/myapp_mem$ lscgroup        # To check if the group was created successfully. 

现在,可以从内核文档中获得内存节流配置的格式。(参考文献中的链接)

$ echo "5242880" > memory.limit_in_bytes 

在运行代码之前,我们需要禁用交换。如果程序无法从RAM获得内存(因为我们的内存有限),它将尝试在交换时分配内存,这在我们的情况下是不可取的。

$ sudo swapoff -a # Disable swap 

linuxvirtualzation5

交换状态必须与上面显示的类似。

$ gcc mem_limit.c -o mem_limit 

首先,在没有任何内存限制的情况下运行代码,

$ ./mem_limit 

现在,比较从受控cgroup中运行时的输出,

$ cgexec -g memory:myapp_mem /root/mem_limit 

您可以查看各种资源记帐信息,如当前内存使用量、最大内存使用量、内存限制等,

$ cat memory.usage_in_bytes$ cat memory.max_usage_in_bytes$ cat memory.limit_in_bytes 

有更多的参数,你可以探索,例如,记忆。失败,记忆。kmem.*还有记忆。科姆。tcp* 你读的文档越多,你的理解就会越好。

我们可以扩展此方法并创建受限制的应用程序。这种方法创建于很久以前,但最近才被广泛应用于许多应用中。虚拟机、容器等使用它来强制执行资源限制。 了解cgroups的目的是了解容器中实际如何进行资源节流。下一个要探讨的主题是容器。我们将在下一篇文章中详细讨论它。

参考资料:

关于作者: 平克什·巴贾提亚 来自印度海得拉巴。他本质上是个极客,有很多值得寻找的项目。他的项目工作可见一斑 在这里 如果你也想在这里展示你的博客,请参见 吉微博 在Geeksforgek上写客博。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享