Linux系统管理员对cgroup的介绍

2020-11-07 11:18:52

在第一篇文章中定义cgroup以及它们如何帮助进行资源管理和性能调优,这是介绍cgroup和资源管理的由四部分组成的系列文章的开始。

所以你一定听说过这种叫cgroup的东西,而且你有兴趣了解更多。也许你是在听一个关于集装箱化的演讲时听到有人提到它的。也许您正在研究Linux性能调优,或者您只是碰巧在某一天遍历文件系统时发现了/sys/fs/cgroup。无论哪种方式,您都想更多地了解内核中已经包含了很长一段时间的这一功能。所以,坐下来,拿点爆米花,准备(希望)学到一些你以前可能不知道的东西。

韦伯斯特词典将群组定义为……。开个玩笑。我总是讨厌听那些从无聊的字典定义开始的演讲。取而代之的是,我将尝试将cgroup的技术定义提炼成一些易于理解的东西。

Cgroup是一个巨大的话题。我把这个讨论分成四个部分。第一部分,也就是这篇文章,涵盖了群组的基本概念。第二部分更深入地研究了CPUShare。第三部分名为《艰难地做cgroup》,介绍了cgroup的管理任务。最后,第四部分介绍了由systemd管理的cgroup。

您可能知道,也可能不知道,Linux内核负责系统上所有硬件的可靠交互。这意味着,除了使操作系统(OS)能够理解硬件的代码(驱动程序)位之外,它还对特定程序可以从系统要求的资源数量设置了限制。当谈到系统必须在计算机可能执行的所有应用程序之间划分的内存量(RAM)时,这是最容易理解的。在其最基本的形式中,Linux系统被允许不受限制地运行大多数应用程序。如果所有应用程序都能很好地协同工作,这对于一般计算来说是非常好的。但是,如果程序中存在错误,并且开始消耗所有可用内存,会发生什么情况呢?内核有一个名为内存不足(OOM)杀手的工具。它的工作是暂停应用程序,以便释放足够的RAM,以便操作系统可以继续运行而不会崩溃。

你会说,这太棒了,但这和Cgroup有什么关系呢?在你的系统崩溃之前,OOM过程就像是最后一道防线。它在一定程度上是有用的,但由于内核可以控制哪些进程必须在OOM中存活下来,它还可以确定哪些应用程序一开始就不能消耗太多RAM。

因此,Cgroup是内核中内置的工具,允许管理员对操作系统上的任何进程设置资源利用率限制。一般而言,cgroup控制:

这些网络分组被标识为相同类型,以便另一应用可以实施网络流量规则。

除了这些,还有更多方面,但这些是大多数管理员关心的主要类别。

控制组(Cgroup)是一种Linux内核机制,用于对资源进行细粒度控制。Cgroup最初是由谷歌工程师在2006年提出的,大约在2007年左右最终并入了Linux内核。虽然目前有两个版本的cgroup,但大多数发行版和机制都使用版本1,因为它从2.6.24开始就在内核中。就像主线内核中添加的大多数东西一样,一开始并没有很高的采用率。版本2延续了这一趋势,已经存在了近五年,但仍未得到广泛部署。

困扰cgroup采用的一个问题是对它的存在及其在现代Linux系统中的作用缺乏了解。低意识和低采用率通常意味着与内核接口的交互是笨重的、令人费解的,或者仅仅是一个完全手动的过程。最初,cgroup就是这样的情况。当然,创建一次性团体并不难。例如,如果要模拟cgroup工具开发之前的早期,可以创建一组目录,挂载cgroup文件系统,然后开始手动配置所有内容。但在我们开始讨论这一切之前,让我们先来谈谈为什么Cgroup在当今的Linux生态系统中至关重要。

Cgroup有四个彼此密切相关的主要特性,这使得它们在现代系统中非常重要,特别是当您运行的是集装箱化的工作负载时。

如前所述,cgroup允许管理员确保系统上运行的程序保持在CPU、RAM、块设备I/O和设备组的某些可接受边界内。

注意:设备组cgroup可能是系统全面安全策略中的关键组件。设备组包括控制读取、写入和mKNOD操作的权限。读/写操作非常简单,所以让我们花点时间来看看Linux系统中的mnowd功能。Mnowd最初的设计目的是填充/dev/中显示的所有内容。这些设备包括硬盘驱动器、Arduino、ESP8266微控制器等设备的USB接口,或者系统中可能存在的其他设备。大多数现代Linux系统使用udev来用内核检测到的东西自动填充这个虚拟文件系统。此外,通过创建命名管道,umnowd还允许多个程序相互通信。这个概念超出了本解释的范围,但只要理解这一点就足够了,这有助于将信息从一个程序传递到另一个程序。无论如何,在受控环境中的mculd是管理员应该密切关注的限制。

优先化与资源限制略有不同,因为您不一定要限制进程。相反,您只是说无论有多少资源可用,进程X在系统上的时间总是比进程Y多。

由于额外的资源利用,对于大多数Linux企业版本,默认情况下关闭记帐,但为特定的树打开资源利用真的很有帮助(稍后将对此进行更多介绍)。因此,您可以看到哪个cgroup中的哪些进程正在消耗哪些类型或资源。

在群组里有一家叫做冰柜的设施。虽然对此功能的深入理解超出了本文的范围,但您可以将Freezer看作是拍摄特定进程的快照并移动它的能力。有关更深入的理解,请参阅内核文档。

好吧,那么这一切意味着什么呢?嗯,从系统管理员的角度来看,这意味着几件事。

首先,即使不深入研究容器技术,这也意味着您可以通过仔细管理工作负载类型、应用程序和它们所需的资源,在单个服务器上实现更高的密度。

其次,它大大增强了你的安全姿态。虽然典型的Linux安装在默认情况下使用cgroup,但它不会对进程施加任何限制。如果您愿意,您可以在默认情况下施加限制。您还可以限制特定用户、组或进程对特定设备的访问,这进一步有助于锁定系统。

最后,您可以通过cgroup进行大量的性能调优。与Tuned结合使用,意味着您可以创建一个专门针对您的个人工作负载进行调整的环境。无论是在规模上,还是在对延迟敏感的环境中,这些调整可能意味着是否满足您的服务级别协议(SLA)。

出于本讨论的目的,我们讨论的是cgroup V1。虽然版本2在Red Hat Enterprise Linux 8(RHEL 8)中可用,但默认情况下它是禁用的。大多数容器技术(如Kubernetes、OpenShift、Docker等)仍然依赖于cgroup版本1。

我们已经讨论过cgroup是一种控制内核中某些子系统的机制。这些子系统(如设备、CPU、RAM、网络访问等)在cgroup术语中称为控制器。

每种类型的控制器(CPU、blkio、内存等)。被细分为树状结构。每根树枝或树叶都有自己的重量或限制。控制组有多个与之关联的进程,从而使资源利用率变得精细且易于微调。

注意:每个子代都会继承,并受到父代cgroup上设置的限制的限制。

在上图中,您可以看到在内存、磁盘I/O和CPU控制组中可以使用PID1。Cgroup是按资源类型创建的,并且彼此之间没有关联。这意味着您可以拥有一个与所有控制器相关联的数据库组,但这些组是单独处理的。与GID类似,这些组在创建时会被分配一个数字值,而不是友好名称。在幕后,内核使用这些值来确定资源分配。换一种方式考虑,假设每个cgroup名称在附加到控制器后都被重命名为控制器的名称加上您选择的名称。因此,内存控制器中名为DATABASE的组实际上可以被认为是内存数据库。因此,与控制器CPU相关联的数据库组没有关系,因为友好名称可以被认为是CPU-DATABASE。

注意:这是一个粗略的简化,如果您想要了解底层的cgroup代码,在技术上是不准确的。以上解释是为了澄清理解。

现在,您已经了解了什么是cgroup,以及它们可以如何帮助您进行性能调优和安全性。您还可以更好地理解Cgroup如何与控制器交互。

本文不是对cgroup中存在的所有控制器类型的细分。这种规模的事情需要一整本书才能解释清楚。在下一篇文章中,我将介绍CPUShares,因为它们相对复杂,并且在系统的整体健康中发挥着重要作用。其他控制器的功能类似。因此,您应该能够从CPU控制器中吸取经验教训,并将其应用于大多数剩余的cgroup控制器。

不要忘记,在第三部分中,我们将研究管理任务,在第四部分中,我们将总结system d如何与cgroup交互。

[容器入门?看看这门免费的课程吧。部署容器化应用程序:技术概述。]