玩轉 Cgroup 系列之一: Cgroup 的起源、重要性和基本工作原理

小猿姐聊技術發表於2023-12-27

概述

Cgroup 是一個龐大的主題。我們將關於 Cgroup 的討論分成了四個部分。本文是第一部分,介紹了 Cgroup 的基本概念。第二部分深入探討了 CPU 份額。第三部分名為“以困難的方式使用 Cgroup”,介紹 Cgroup 的管理任務。第四部分會討論由 systemd 管理的 Cgroup。下面,我們就開始介紹 Cgroup 的定義以及它如何幫助資源管理和效能調優。

Cgroup 對於領域之內的人不是陌生的主題,你可能在參加有關容器化的演講時聽到有人提到了它,也許你在研究 Linux 效能調優時看到了它,又也許你只是在某一天遍歷你的檔案系統時發現了  /sys/fs/cgroups。但是如果你想要更加了解這個已經在核心中存在了很長時間的功能,就可以耐心地讀完這四篇文章,或許就能學到一些你之前不知道的東西。

什麼是 Cgroup?

Webster 的詞典將 Cgroup 定義為……開個玩笑。我一直討厭那些以無聊的詞典定義開始的演講。相反,我將嘗試將 Cgroup 的技術定義簡化為容易理解的東西。

Linux 核心負責系統上所有硬體的可靠互動。這意味著,除了使作業系統(OS)能夠理解硬體的程式碼位(驅動程式)之外,它還限制了特定程式可以從系統中獲取多少資源。系統必須將系統記憶體分配給計算機可能執行的所有應用程式。在最基本的形式中,Linux 系統可以無限制地執行大多數應用程式。在所有應用程式都能很好地相互配合的時候,是沒有任何問題的。但是,如果某個程式中存在錯誤,並且它開始佔用所有可用記憶體,會怎麼樣呢?核心有一個叫做 OOM(Out Of Memory) Killer 的功能。它能在系統崩潰之前停止應用程式以釋放足夠的 RAM,以使作業系統能夠繼續正常執行。因此,OOM 程式在系統崩潰之前充當了最後一道防線,有時很有用。但是由於核心可以控制哪些程式能夠倖免於 OOM,它也可以確定哪些應用程式從一開始就不應消耗過多的記憶體。

而 Cgroup 是核心內建的一種設施,允許管理員在系統上設定任何程式的資源利用限制。一般來說,Cgroup 主要控制:

  • 每個程式的 CPU 份額數量。

  • 每個程式的記憶體限制。

  • 每個程式的塊裝置 I/O。

  • 哪些網路資料包被識別為同一型別,以便其他應用程式可以強制執行網路流量規則。

Cgroup 還能控制別的,但以上四個是大多數管理員關心的主要類別。

Cgroup 的起源

Cgroup 最初由 Google 工程師在 2006 年提出,是用於細粒度資源控制的 Linux 核心機制。Cgroup 於 2007 年合併到 Linux 核心中。雖然目前有兩個版本的 Cgroup,但多數發行版和機制仍在使用版本 1,因為它從 2.6.24 核心開始就已經存在了。與大多數新增到主線核心中的功能一樣,它起初並沒有太高的採用率。版本 2 繼續延續這一趨勢,雖然已經存在了將近五年,但仍未廣泛部署。

影響 Cgroup 採用率的一個問題是人們對其存在及其在現代 Linux 系統中的作用缺乏瞭解。低意識度和採用率通常意味著與核心介面的互動方式很笨拙、複雜或者完全是一個手動過程。Cgroup 最初就是如此。當然,建立一個臨時的 Cgroup 並不難。例如,如果你想模擬在 Cgroup 工具開發之前的早期情況,你可以建立一堆目錄,掛載  cgroup 檔案系統,然後手動開始配置所有內容。但在深入討論這些內容之前,讓我們先談談 Cgroup 在當今 Linux 生態系統中的重要性。

Cgroup 的重要性

當你執行容器化工作負載時,現代系統中有四個與 Cgroup 密切相關的主要特性。

1. 資源限制

正如之前提到的,Cgroup 允許管理員確保系統上執行的程式在 CPU、RAM、塊裝置 I/O 和裝置組等方面保持在可接受的範圍內。

注意: 裝置組 Cgroup 可以成為系統全面安全策略的關鍵元件。裝置組包括控制對讀取、寫入和  mknod 操作的許可權。讀寫操作是相當容易理解的。

而  mknod 最初是用來填充出現在  /dev/ 中的所有裝置的。它們包括硬碟、用於 Arduino、ESP8266 微控制器等裝置的 USB 介面,或者系統上可能存在的其他裝置。大多數現代 Linux 系統使用  udev 來自動將核心檢測到的裝置填充到這個虛擬檔案系統中。 mknod 還允許多個程式透過建立一個命名管道來相互通訊。這個概念超出了本文的範圍,但你只要理解它有助於把資訊從一個程式傳遞到另一個程式即可。不管怎樣,在受控環境中,管理員應該密切關注限制  mknod 的操作。

2. 優先順序

優先順序與資源限制略有不同,因為你不一定是限制程式。相反,你只是在說無論有多少資源可用,程式  X 在系統上總是比程式  Y 有更多的時間。

3. 記賬

雖然預設情況下大多數企業版 Linux 都關閉了記賬功能,因為它會增加額外的資源利用,但開啟特定樹的資源利用,可以檢視在哪個 Cgroup 內的程式正在使用哪些型別的資源,這個功能非常有幫助。

4. 程式控制

Cgroup 中有一個稱為冷凍器(freezer)的功能。雖然深入理解這個功能超出了本文的範圍,但你可以將冷凍器視為對特定程式進行快照並移動的能力。

好的,那這一切意味著什麼呢?從系統管理員的角度來看,它意味著:

  • 首先,即使不深入研究容器技術,透過仔細管理工作負載型別、應用程式和資源要求,你可以在單個伺服器上實現更高的密度。

  • 其次,它在很大程度上增強了系統的安全性。雖然典型的 Linux 安裝預設使用 Cgroup,但它沒有對程式施加任何限制。你按照實際情況預設強制施加限制,還可以限制特定使用者、組或程式對特定裝置的訪問許可權,進一步加固系統安全。

  • 最後,你可以透過 Cgroup 進行大量的效能調優。結合 tuned,建立一個專門調整為你的個體工作負載的環境。在大規模或對延遲敏感的環境中,這些調整可能是是否能夠達到服務級別協議(SLA)的差異所在。

Cgroup 是如何工作的?

本文中,我們討論的是  Cgroup V1。雖然  Cgroup V2 在 Red Hat Enterprise Linux 8(RHEL 8)中可用,但預設情況下已禁用。大多數容器技術如 Kubernetes、OpenShift、Docker 等仍依賴於  Cgroup V1

Cgroup 是一種控制核心中某些子系統的機制。這些子系統,如裝置、CPU、RAM、網路訪問等,被稱為 Cgroup 術語中的控制器。每種型別的控制器( cpublkiomemory等)都被細分為一個類似樹形結構。每個分支或葉子都有自己的權重或限制。一個控制組有多個與之關聯的程式,使得資源利用可以細粒度調整,易於微調。

注意:每個子程式都繼承並受到父 Cgroup 設定的限制。

在上面的圖表中,你可以看到一個程式(PID 1)可以屬於  memorydisk i/o 和 cpu 控制組。Cgroup 是按資源型別建立的,彼此之間沒有關聯。所以你可以在所有控制器中關聯一個  database 組,但這些組是相互獨立的。就像 GID 一樣,這些組在建立時被分配到一個數字值,而不是友好名稱。在核心中,這些值用於確定資源分配。換句話說,假設每個附加到控制器的 Cgroup 名稱在附加後被重新命名為控制器的名稱加上你選擇的名稱。那麼在  memory 控制器中的  database 組可以被稱為  memory-database。它與控制器  cpu 關聯的  database 組沒有關係,因為它的名稱是  cpu-database

注意: 這只是一個極其簡化的解釋,旨在幫助讀者更好地理解。如果你想深入瞭解 Cgroup 的底層程式碼,請注意這並不準確。

總結

現在你對 Cgroup 是什麼以及它如何幫助你進行效能調優和增強安全性有了一定的瞭解。我們也討論了 Cgroup 如何與控制器進行互動。

本文並不旨在對 Cgroup 中存在的所有控制器型別進行詳細解析,這些內容可能需要一本完整的書才能解釋清楚。在下一篇文章中,我將介紹 CPU 份額。因為它們相對複雜,在系統的整體健康狀況中起著重要作用,而且其他控制器的功能與之類似。因此,學完下一篇後,你應該能夠把從 CPU 控制器中學到的知識應用於大多數其他 Cgroup 控制器中。


來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70035809/viewspace-3001782/,如需轉載,請註明出處,否則將追究法律責任。

相關文章