Docker容器基礎入門認知 Cgroup

2022-09-09 23:09:25 字數 4585 閱讀 3050

也許你會好奇,我們不是已經通過 linux namespace 給容器建立了乙個容器了嗎,為什麼還需要對容器做限制呢?

因為在 linux 程序中,容器程序並不是物理隔離的,在執行時是和宿主機上的其他程序共享同乙個 cpu 和記憶體,如果不加以限制,必定會造成資源競爭。

在容器中,第 1 號程序在「障眼法」的干擾下只能看到容器裡的情況,但是宿主機上,它作為第 100 號程序與其他所有程序之間依然是平等的競爭關係。這就意味著,雖然第 100 號程序表面上被隔離了起來,但是它所能夠使用到的資源(比如 cpu、記憶體),卻是可以隨時被宿主機上的其他程序(或者其他容器)占用的。當然,這個 100 號程序自己也可能把所有資源吃光。這些情況,顯然都不是乙個「沙盒」應該表現出來的合理行為。

linux cgroups 就是 linux 核心中用來為程序設定資源限制的乙個重要功能

linux cgroups 的全稱是 linux control group。它最主要的作用,就是限制乙個程序組能夠使用的資源上限,包括 cpu、記憶體、磁碟、網路頻寬等等。

在 linux 中,cgroups 給使用者暴露出來的操作介面是檔案系統,即它以檔案和目錄的方式組織在作業系統的 /sys/fs/cgroup 路徑下。在 centos 機器裡,我可以用 mount 指令把它們展示出來,這條命令是:

$ mount -t cgroup

cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)

cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)

cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)

cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)

cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)

cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)

cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)

cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)

cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)

cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)

cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)

如果沒有掛載則直接使用 yum install libcgroup 安裝 cgroups 模組

可以看到,在 /sys/fs/cgroup 下面有很多諸如 cpuset、cpu、 memory 這樣的子目錄,也叫子系統。這些都是我這台機器當前可以被 cgroups 進行限制的資源種類。而在子系統對應的資源種類下,你就可以看到該類資源具體可以被限制的方法。比如,對 cpu 子系統來說,我們就可以看到如下幾個配置檔案,這個指令是:

$ ls /sys/fs/cgroup/cpu

aegis cgroup.clone_children cgroup.procs cpuacct.stat cpuacct.usage_percpu cpu.cfs_quota_us cpu.rt_runtime_us cpu.stat notify_on_release system.slice user.slice

assist cgroup.event_control cgroup.sane_beh**ior cpuacct.usage cpu.cfs_period_us cpu.rt_period_us cpu.shares docker release_agent tasks

root@centos:/sys/fs/cgroup/cpu$ mkdir container

root@centos/sys/fs/cgroup/cpu$ ls container/cgroup.clone_children cpu.cfs_period_us cpu.rt_period_us cpu.shares notify_on_release

cgroup.procs cpu.cfs_quota_us cpu.rt_runtime_us cpu.stat tasks

這個目錄就稱為乙個「控制組」。你會發現,作業系統會在你新建立的 container 目錄下,自動生成該子系統對應的資源限制檔案。現在,我們在後台執行這樣一條指令碼:

$ while : ; do : ; done &[

1] 226

這樣,我們可以用 top 指令來確認一下 cpu 有沒有被打滿:

$ top

%cpu0 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

在輸出裡可以看到,cpu 的使用率已經 100% 了(%cpu0 :100.0 us)。而此時,我們可以通過檢視 container 目錄下的檔案,看到 container 控制組裡的 cpu quota 還沒有任何限制(即:-1),cpu period 則是預設的 100 ms(100000 us):

$ cat /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us 

-1$ cat /sys/fs/cgroup/cpu/container/cpu.cfs_period_us

100000

接下來,我們可以通過修改這些檔案的內容來設定限制。比如,向 container 組裡的 cfs_quota 檔案寫入 20 ms(20000 us):

$ echo 20000 > /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us

結合前面的介紹,你應該能明白這個操作的含義,它意味著在每 100 ms 的時間裡,被該控制組限制的程序只能使用 20 ms 的 cpu 時間,也就是說這個程序只能使用到 20% 的 cpu 頻寬。接下來,我們把被限制的程序的 pid 寫入 container 組裡的 tasks 檔案,上面的設定就會對該程序生效了:

$ echo 226 > /sys/fs/cgroup/cpu/container/tasks

我們可以用 top 指令檢視一下:

$ top

%cpu0 : 20.3 us, 0.0 sy, 0.0 ni, 79.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

可以看到,計算機的 cpu 使用率立刻降到了 20%(%cpu0 : 20.3 us)。

除 cpu 子系統外,cgroups 的每乙個子系統都有其獨有的資源限制能力,比如:

linux cgroups 的設計還是比較易用的,簡單粗暴地理解呢,它就是乙個子系統目錄加上一組資源限制檔案的組合。而對於 docker 等 linux 容器專案來說,它們只需要在每個子系統下面,為每個容器建立乙個控制組(即建立乙個新目錄),然後在啟動容器程序之後,把這個程序的 pid 填寫到對應控制組的 tasks 檔案中就可以了。

而至於在這些控制組下面的資源檔案裡填上什麼值,就靠使用者執行 docker run 時的引數指定了,比如這樣一條命令:

$ docker run -it --cpu-period=100000 --cpu-quota=20000 ubuntu /bin/bash

在啟動這個容器後,我們可以通過檢視 cgroups 檔案系統下,cpu 子系統中,「docker」這個控制組裡的資源限制檔案的內容來確認:

$ cat /sys/fs/cgroup/cpu/docker/5d5c9f67d/cpu.cfs_period_us 

100000

$ cat /sys/fs/cgroup/cpu/docker/5d5c9f67d/cpu.cfs_quota_us

20000

所以你看,docker 容器時候的技術其實並沒有什麼特別大的創新,只是統一了linux相關功能,整合起來,形成容器技術。

docker容器入門

docker是乙個開源的應用容器引擎,可以將你的可執行檔案 配置檔案及一切其他你需要的檔案一併打包到這個容器中,並發布和應用到任意平台,其他使用者可以直接使。執行中的這個映象稱為容器,容器啟動是非常快速的。docker映象 images 軟體打包好的映象 放在docker倉庫中,可以理解為一堆靜態的...

Docker容器入門

docker 是乙個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到乙個可移植的容器中,然後發布到任何流行的 linux 機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何介面。安裝好後開啟docker的設定 設定docker類似與中國映象的位址 大概這樣應該就完成了do...

Docker 入門之docker容器建立

使用docker容器的大多數人都是因為想要隔離不同執行環境的差異,使得自己的應用能更好的移植和部署。那麼我們來看看掌握docker需要掌握哪些方面。1,搭建docker環境 2,編譯映象並將其執行成容器 3,將自己的應用壓縮在多個容器中 4,在乙個集群上部署自己的應用 5,通過增加後台資料庫來儲存服...