欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你徹底搞懂Docker中的cgroup的具體使用

 更新時間:2021年11月28日 10:35:55   作者:神技圈子  
本文主要介紹了Docker中的cgroup的具體使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

前言

進程在系統(tǒng)中使用CPU、內存、磁盤等計算資源或者存儲資源還是比較隨心所欲的,我們希望對進程資源利用進行限制,對進程資源的使用進行追蹤。這就讓cgroup的出現(xiàn)成為了可能,它用來統(tǒng)一將進程進行分組,并在分組的基礎上對進程進行監(jiān)控和資源控制管理。

什么是cgroup

Linux CGroup(Linux Contral Group),它其實是Linux內核的一個功能,它是Linux下的一種將進程按組進行管理的機制。最開始是由Google工程師Paul Menage和Rohit Seth于2006年發(fā)起的,最早起名叫進程容器。在2007之后隨著容器得提出,為了避免混亂重命名為cgroup,并且被合并到了內核2.6.24版本中去了。
在用戶層看來,cgroup技術就是把系統(tǒng)中的所有進程組織成一顆一顆獨立的樹,每棵樹都包含系統(tǒng)的所有進程,樹的每個節(jié)點是一個進程組,而每顆樹又和一個或者多個subsystem關聯(lián)。樹主要用來將進程進行分組,而subsystem用來對這些組進行操作。

cgroup的組成

cgroup主要包含以下兩個部分

  • subsystem: 一個subsystem就是一個內核模塊,它被關聯(lián)到一顆cgroup樹之后,就會在樹節(jié)點進行具體的操作。subsystem經常被稱作"resource controller",因為它主要被用來調度或者限制每個進程組的資源,但是這個說法不完全準確,因為有時我們將進程分組只是為了做一些監(jiān)控,觀察一下他們的狀態(tài),比如perf_event subsystem。
  • hierarchy:一個hierarchy可以理解為一棵cgroup樹,樹的每個節(jié)點就是一個進程組,每棵樹都會與多個subsystem關聯(lián)。在一顆樹里面,會包含Linux系統(tǒng)中的所有進程,但每個進程只能屬于一個節(jié)點(進程組)。系統(tǒng)中可以有很多顆cgroup樹,每棵樹都和不同的subsystem關聯(lián),一個進程可以屬于多顆樹,即一個進程可以屬于多個進程組,這些進程組和不同的subsystem關聯(lián)。

可以通過查看/proc/cgroup目錄查看當前系統(tǒng)支持哪些subsystem關聯(lián)

在這里插入圖片描述

第一列:表示subsystem名

第二列:表示關聯(lián)到的cgroup樹的ID,如果多個subsystem關聯(lián)到同一顆cgroup樹,那么它們的這個字段將一樣。比如圖中的cpuset、cpu和cpuacct。

第三列:表示subsystem所關聯(lián)的cgroup樹中進程組的個數(shù),即樹上節(jié)點的個數(shù)。

cgroup提供的功能

它提供了如下功能

  • Resource limitation:資源使用限制
  • Prioritization:優(yōu)先級控制
  • Accounting:一些審計或者統(tǒng)計
  • Control:掛起進程,恢復執(zhí)行進程

一般我們可以用cgroup做以下事情

  • 隔離一個進程集合(比如MySQL的所有進程),限定他們所占用的資源,比如綁定的核限制
  • 為這組進程分配內存
  • 為這組進程的分配足夠的帶寬及進行存儲限制
  • 限制訪問某些設備

cgroup在Linux中表現(xiàn)為一個文件系統(tǒng),運行如下命令

在這里插入圖片描述

mount成功后,可以看到,在/sys/fs下有個cgroup目錄,這個目錄下有很多子系統(tǒng)。比如cpu、cpuset、blkio等。
然后在/sys/fs/cgroup/cpu目錄下建個子目錄test,這個時候會發(fā)現(xiàn)在該目錄下多了很多文件

在這里插入圖片描述

限制cgroup中的CPU

在cgroup里面,跟CPU相關的子系統(tǒng)有cpusets、cpuacct和cpu。
其中cpuset主要用于設置CPU的親和性,可以限制cgroup中的進程只能在指定的CPU上運行,或者不能在指定的CPU上運行,同時cpuset還能設置內存的親和性。cpuacct包含當前cgroup所使用的CPU的統(tǒng)計信息。這里我們只說以下cpu。

然后我們在/sys/fs/cgroup/cpu下創(chuàng)建一個子group, 該目錄下文件列表

在這里插入圖片描述

cpu.cfs_period_us用來配置時間周期長度,cpu.cfs_quota_us用來配置當前cgroup在設置的周期長度內所能使用的CPU時間數(shù),兩個文件配合起來設置CPU的使用上限。兩個文件的單位都是微秒(us),cpu.cfs_period_us的取值范圍為1毫秒(ms)到1秒(s),cpu.cfs_quota_us的取值大于1ms即可。
下面來舉個例子講解如何使用cpu限制
假如我們寫了一個死循環(huán)

在這里插入圖片描述

運行起來用top查看下占用率達到了100%

在這里插入圖片描述

我們執(zhí)行如下命令對cfs_quota_us進行設置

echo 20000 > /sys/fs/cgroup/cpu/test/cpu.cfs_quota_us

這條命令表示把進程的CPU利用率下降20%,然后把進程PID加入到cgroup中

在這里插入圖片描述

再執(zhí)行top可以看到cpu利用率下降了

在這里插入圖片描述

限制cgroup中的內存

代碼如果有bug,比如內存泄露等會榨干系統(tǒng)內存,讓其它程序由于分配不了足夠的內存而出現(xiàn)異常,如果系統(tǒng)配置了交換分區(qū),會導致系統(tǒng)大量使用交換分區(qū),從而系統(tǒng)運行很慢。
而cgroup對進程內存控制主要控制如下:

  • 限制cgroup中所有進程使用的內存總量
  • 限制cgroup中所有進程使用的物理內容+swap交換總量
  • 限制cgroup中所有進程所能使用的內核內存總量及其它一些內核資源(CONFIG_MEMCG_KMEM)。

這里限制內核內存就是限制cgroup當前所使用的內核資源,包括當前進程的內核占空間,socket所占用的內存空間等。當內存吃緊時,可以阻止當前cgroup繼續(xù)創(chuàng)建進程以及向內核申請分配更多的內核資源。

下面通過一個例子帶大家理解cgroup做內存控制的

#include <iostream>
#include <sys/types.h>
#include <cstdlib>
#include <cstdio>
#include <string.h>
#include <unistd.h>

#define CHUNK_SIZE 512


int main()
{
   int size = 0;
   char *p = nullptr; 
   while(1)
   {
          if((p = (char*)malloc(CHUNK_SIZE))==nullptr)
          {
              break;
         }

      memset(p, 0, CHUNK_SIZE);
       printf("[%u]-- [%d]MB is allocated ", getpid(), ++size);
       sleep(1);
   }
    
   return 0;
}

首先,在/sys/fs/cgroup/memory下創(chuàng)建一個子目錄即創(chuàng)建了一個子cgroup,比如這里我們創(chuàng)建了一個test目錄

$mkdir /sys/fs/cgroup/memory/test

test目錄包含以下文件

在這里插入圖片描述

每個文件的作用大概介紹下:

文件 說明
cgroup.event_control 用于eventfd的接口
memory.usage_in_bytes 顯示當前已用的內存
memory.limit_in_bytes 設置/顯示當前限制的內存額度
memory.failcnt 顯示內存使用量達到限制值的次數(shù)
memory.max_usage_in_bytes 歷史內存最大使用量
memory.soft_limit_in_bytes 設置/顯示當前限制的內存軟額度
memory.stat 顯示當前cgroup的內存使用情況
memory.use_hierarchy 設置/顯示是否將子cgroup的內存使用情況統(tǒng)計到當前cgroup里面
memory.force_empty 觸發(fā)系統(tǒng)立即盡可能的回收當前cgroup中可以回收的內存
memory.pressure_level 設置內存壓力的通知事件,配合cgroup.event_control一起使用
memory.swappiness 設置和顯示當前的swappiness
memory.move_charge_at_immigrate 設置當進程移動到其他cgroup中時,它所占用的內存是否也隨著移動過去
memory.oom_control 設置/顯示oom controls相關的配置
memory.numa_stat 顯示numa相關的內存

然后通過寫文件memory.limit_in_bytes來設置限額。這里設置5M的限制,如下圖所示

在這里插入圖片描述

把上面示例進程加入這個cgroup,如下圖所示

在這里插入圖片描述

為了避免受swap空間的影響,設置swappiness為0來禁止當前cgroup使用swap,如下圖所示

在這里插入圖片描述

當物理內存達到上限后,系統(tǒng)的默認行為是kill掉cgroup中繼續(xù)申請內存的進程。那么怎么控制這個行為呢?那就是配置memory.oom_control。這個文件里面包含了一個控制是否為當前cgroup啟動OOM-killer的標識。如果寫0到這個文件,將啟動OOM-killer,當內核無法給進程分配足夠的內存時,將會直接kill掉該進程;如果寫1到這個文件,表示不啟動OOM-killer,當內核無法給進程分配足夠的內存時,將會暫停該進程直到有空余的內存之后再繼續(xù)運行;同時,memory.oom_control還包含一個只讀的under_oom字段,用來表示當前是否已經進入oom狀態(tài),也即是否有進程被暫停了。還有一個只讀的killed_oom字段,用來表示當前是否有進程被kill掉了。

限制cgoup的進程數(shù)

cgroup中有一個subsystem叫pids,功能是限制cgroup及其所有子孫cgroup里面能創(chuàng)建的總的task數(shù)量。這里的task指通過fork和clone函數(shù)創(chuàng)建的進程,由于clone函數(shù)也能創(chuàng)建線程,所以這里的task也包含線程。
之前cgroup樹是已經掛載好的,這里就直接創(chuàng)建子cgroup,取名為test。命令如下圖所示

在這里插入圖片描述

再來看看test目錄下的文件

在這里插入圖片描述

其中pids.current表示當前cgroup和其所有孫子cgroup現(xiàn)有的總的進程數(shù)量。

在這里插入圖片描述

pids.max 當前cgroup和其所有孫子cgroup所允許創(chuàng)建的最大進程數(shù)量。

在這里插入圖片描述

下面我們做個實驗,將pids.max設置為1

在這里插入圖片描述

然后將當前bash進程加入到該cgroup中

在這里插入圖片描述

隨便運行一個命令,由于在當前窗口pids.current已經等于pids.max了,所以創(chuàng)建進程失敗

在這里插入圖片描述

當前cgroup中的pids.current和pids.max代表了當前cgroup及所有子孫cgroup的所有進程,所以子孫cgroup中的pids.max大小不能超過父cgroup中的大小,如果超過了會怎么樣?我們把pids.max設置為3

在這里插入圖片描述

當前進程數(shù)為2

在這里插入圖片描述

重新打開一個shell窗口,創(chuàng)建個孫子cgroup,將其中的pids.max設置為5

在這里插入圖片描述

講當前shell的bash進程寫入croup.procs

在這里插入圖片描述

回到原來的shell窗口隨便執(zhí)行一條命令可以看到執(zhí)行失敗

在這里插入圖片描述

可以看到,子cgroup中的進程數(shù)不僅受制與自己的pids.max,還受制于祖先cgroup的pids.max

到此這篇關于一文帶你徹底搞懂Docker中的cgroup的具體使用的文章就介紹到這了,更多相關Docker cgroup內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • docker搭建dnsmasq服務的實現(xiàn)

    docker搭建dnsmasq服務的實現(xiàn)

    本文將指導讀者如何使用Docker搭建DNSmasq服務,通過簡單的步驟和詳細的說明,幫助讀者快速在Docker環(huán)境中部署DNSmasq,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • Docker中Nginx反向代理的實現(xiàn)步驟

    Docker中Nginx反向代理的實現(xiàn)步驟

    為了安全考慮,我們一般會設置反向代理,用來屏蔽應用程序真實的IP和端口號,本文主要介紹了Docker中Nginx反向代理的實現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • docker掛載本地目錄和數(shù)據卷容器操作

    docker掛載本地目錄和數(shù)據卷容器操作

    這篇文章主要介紹了docker掛載本地目錄和數(shù)據卷容器操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • 解決Docker錯誤“docker?build“?requires?exactly?1?argument(s)問題

    解決Docker錯誤“docker?build“?requires?exactly?1?argument(s)

    這篇文章主要介紹了解決Docker錯誤“docker?build“?requires?exactly?1?argument(s)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • docker默認路徑存儲不足解決過程

    docker默認路徑存儲不足解決過程

    這篇文章主要給大家介紹了關于docker默認路徑存儲不足的解決過程,Docker存儲空間不足的錯誤通常表明Docker Daemon分配的本地磁盤空間用盡,文中通過代碼將解決的辦法介紹的非常詳細,需要的朋友可以參考下
    2024-04-04
  • 使用OpenSSL生成Kubernetes證書的介紹

    使用OpenSSL生成Kubernetes證書的介紹

    今天小編就為大家分享一篇關于使用OpenSSL生成Kubernetes證書的介紹,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • docker安裝tomcat并部署Springboot項目war包的方法

    docker安裝tomcat并部署Springboot項目war包的方法

    這篇文章主要介紹了docker安裝tomcat并部署Springboot項目war包的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • 詳解基于Harbor搭建Docker私有鏡像倉庫

    詳解基于Harbor搭建Docker私有鏡像倉庫

    這篇文章主要介紹了詳解基于Harbor搭建Docker私有鏡像倉庫,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • docker實現(xiàn)MySQL的主從復制

    docker實現(xiàn)MySQL的主從復制

    在學習項目的時候實現(xiàn)讀寫分離用到了主從復制,但是一般要實現(xiàn)的話需要虛擬機或服務器非常麻煩,但是docker可以完美解決這一問題,本文主要介紹了docker實現(xiàn)MySQL的主從復制,感興趣的可以了解一下
    2024-01-01
  • Docker學習之Container容器的具體使用

    Docker學習之Container容器的具體使用

    這篇文章主要介紹了Docker學習之Container容器的具體使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-06-06

最新評論