前言

Docker系列文章:

此篇是Docker系列的第十篇,大家一定要按照我做的Demo都手敲一遍,印象會更加深刻的,馬上就開始Kubernetes,加油!一起前行!

  1. 為什麼要學習Docker
  2. Docker基本概念
  3. Docker映象基本原理
  4. Docker容器資料卷
  5. Dockerfile
  6. Docker單機網路上
  7. Docker單機網路下
  8. Docker單機網路實戰
  9. Docker隔離技術

隔離的問題

之前我們做的Demo都沒有使用限制,這個時候我們使用stats命令來看下整體資源的使用情況;

docker stats

img

這個時候我們可以看到容器是可以使用到宿主機的所有的資源,這也是基於Linux Namespace的隔離機制相比於虛擬化技術的不足之處,就是對資源的隔離不夠徹底,當一個宿主機上執行多個容器的時候,容器是共享宿主機的CPU和記憶體,這個時候如果某XX程式寫了一個記憶體溢位的程式部署到容器中,這個時候就會影響到同一臺宿主機的其他容器,那麼對於這個問題我們該如何解決?

Cgroups

Linux Cgroups的全稱是Linux Control Group。它最主要的作用,就是限制一個程序組能夠使用的資源上限,包括CPU、記憶體、磁碟、網路頻寬等等。這種機制可以根據需求把一系列系統任務及其子任務整合(或分隔)到按資源劃分等級的不同組內,從而為系統資源管理提供一個統一的框架。簡單說,Cgroups 可以限制、記錄任務組所使用的物理資源。本質上來說,Cgroups 是核心附加在程式上的一系列鉤子(hook),通過程式執行時對資源的排程觸發相應的鉤子以達到資源追蹤和限制的目的。也就是說開發者可以通過 Cgroups 提供的精細化控制能力,限制某一個或者某一組程序的資源使用。

Cgroups的主要作用

實現 Cgroups 的主要目的是為不同使用者層面的資源管理提供一個統一化的介面。從單個任務的資源控制到作業系統層面的虛擬化,Cgroups 提供了四大功能:

  1. 資源限制:Cgroups 可以對程序的資源總額進行限制;

  2. 優先順序分配:通過分配的 CPU 時間片數量和磁碟 IO 頻寬,實際上就等同於控制了任務執行的優先順序;

  3. 資源統計:Cgroups 可以統計系統的資源使用量,比如 CPU 使用時長、記憶體用量等;

  4. 任務控制:Cgroups 可以對任務執行掛起、恢復等操作;

Cgroups檔案系統探索

在Linux中,Cgroups給使用者暴露出來的操作介面是檔案系統,即它以檔案和目錄的方式組織在作業系統的/sys/fs/cgroup路徑下,我們可以通過 mount 命令來檢視 Cgroups 預設的掛載點:

mount | grep cgroup

image.png

輸出的結果是一系列檔案系統目錄(如果你在自己的機器上沒有看到這些目錄,那你就需要自己去掛載Cgroups)。

讓我們來使用ll命令看一下 /sys/fs/cgroup目錄下包含哪些子目錄,

ll /sys/fs/cgroup

image.png

在/sys/fs/cgroup目錄包括cpuset、cpu、 memory這樣的子目錄,這些都是我這臺機器當前可以被Cgroups進行限制的資源種類,接下來我們深入到memory的子目錄下看下該目錄下都有什麼:


image.png

這些檔案就是 Cgroups 的 memory 子系統中的根級設定。比如 memory.limit_in_bytes 中的數字用來限制程序的最大可用記憶體,memory.swappiness 中儲存著使用 swap 的權重等等。

既然 Cgroups 是以這些檔案作為 API 的,那麼我就可以通過建立或者是修改這些檔案的內容來限制程序的資源,接下來我們就來在展示下如何使用Cgroups。

如何使用Cgroups

該案例是限制程序可以用的CPU

  1. 在 /sys/fs/cgroup/cpu目錄下新建一個名稱為limit_cpu的目錄;

    #進入對應的目錄
    cd /sys/fs/cgroup/cpu
    #新建資料夾
    mkdir limit_cpu
  2. 檢視新建檔案的目錄,我們可以發現系統已經幫我們自動建立的以下目錄,也就是說明了Cgroups 的檔案系統會在建立檔案目錄的時候自動建立這些配置檔案;

    cd limit_cpu/
    ls

    image.png
  3. 我們通過配置將CPU週期限制為總量的十分之一;

    #設定CPU period的週期的100ms(100000 us),該值也是預設的值
    echo 100000 > cpu.cfs_period_us
    #設定CPU的配額為10ms(10000 us),這樣就是為總量的十分之一
    echo 10000 > cpu.cfs_quota_us
  4. 切換/usr/local目錄下,新建cputime.c檔案,編寫如下相加程式;

    #切換目錄
    cd /usr/local
    #新建檔案
    touch cputime.c
    #編輯檔案
    vim cputime.c

    void main(){
        unsigned int i, end;

        end = 1024 * 1024 * 1024;
        for(i = 0; i < end; )
        {
            i ++;
        }
    }
  5. 編譯程式

    gcc cputime.c -o cputime
  6. 使用不同的CPU限制,對比執行時間執行時間,通過對比我們可以發現限制的CPU使用時間大概是我們不使用限制下的時間的10倍,說明我們限制是生效的;

    #CentOS系統需要安裝libcgroup-tools包,才有cgroup配置命令
    yum install -y libcgroup-tools.x86_64
    #無限制下的CPU執行時間
    time ./cputime
    #使用limit_cpu限制下的CPU執行時間
    time cgexec -g cpu:limit_cpu ./cputime

    image.png

總結一下,Linux Cgroups 就是一個子系統目錄加上一組資源限制檔案的組合。

Docker限制探究

使用

使用如下命令啟動,看到--cpu-period和--cpu-quota相信你會感到熟悉,這不是和我們上面使用限制CPU時候的引數配置基本上是一樣,這個時候我們懷疑Docker的限制可能使用Cgroups的技術,接下來我們就探究下是不是這樣的。

docker run -it -d --cpu-period=100000 --cpu-quota=20000 --memory 1000M --name limitcentos centos:latest

我們使用docker stats檢視docker資源使用情況,會發現limitcentos的記憶體以及被限制到1000M了。

docker stats

image.png

原理探究

通過引數我們猜測可能Docker的限制可能使用Cgroups的技術,驗證的最好的辦法就是去找下Cgroups的目錄結構,接下來我們分別看CPU的目錄是否存在docker的限制。

  1. 進入Cgroups的cpu目錄,我們會發現拖多出docker的目錄;

    cd /sys/fs/cgroup/cpu
    ls

    img
  2. 進入docker目錄,看到藍色部分我們會想到docker啟動成功以後返回一串字串,確實藍色部分就是代表Docker,最後那張圖是limitcentos啟動後返回的,我們可以看到他們是一致的;


    img

    img
  3. 進入limitcentos的對應的目錄,我們會發現其目錄和CPU限制的是基本一致的;


    image.png
  4. 接下來我們檢視下cfs_period_us和cfs_quota_us的內容是否和docker啟動的引數一致,經過驗證發現是一致的;

    #檢視週期
    cat cpu.cfs_period_us
    #檢視限制
    cat cpu.cfs_quota_us

    image.png

經過demo驗證,證實了Docker的限制就是使用Cgroups的技術。

結束

歡迎大家點點關注,點點贊!