上個月我 在 ApacheCon 發表了演講,主題是 Cgroups。似乎很少有 Linux 使用者(包括不久前的我自己)熟悉 Cgroups 及其強大之處。這很可惜,因為 Cgroups 是 非常 強大的,且與 Linux 工具箱中的任何其他工具相比,它允許您以更細粒度的方式在伺服器上分配資源。此外,它’是直接內置於核心中,並且在大多數 Linux 發行版中都是開箱即用的。
在這篇文章中,我將介紹如何將 Cgroups 與 Docker 結合使用,這算是對我在 Docker Meetup(德州奧斯汀)所做之另一場演講的後續。
這篇文章確實需要對 Cgroups 有一些基本的了解。如果您’對 Cgroups 完全陌生,我建議您瀏覽我的 簡報(來自 ApacheCon)以及結尾處的資源。不過別擔心,我們不會深入探討。如果您只是粗略瀏覽一下簡報,應該就能掌握基本概念。
Docker 與 Cgroups
Docker 附帶兩種不同的驅動程式:LXC 和 libcontainer。LXC 驅動程式是舊版驅動程式,而 libcontainer 是新的預設驅動程式。在大多數情況下,libcontainer 是首選驅動程式,因為那是創新發生的地方(例如 docker exec 無法與 LXC 驅動程式搭配工作)。
然而,需要特別注意的是,這裡有兩種不同的驅動程式,原因在於並非所有的 Cgroup 功能都已移植到 libcontainer(或至少尚未開放給 Docker)。使用 LXC 驅動程式時,您只需直接傳遞 LXC 參數,而使用 libcontainer 時,則有顯式的 Cgroup 策略參數開放給 Docker。您在啟動 Docker 守護行程時需要明確設定驅動程式,因此您無法同時執行這兩種驅動程式。
這裡’有一個您可以如何檢查的範例:
[bash light=”true”] # 使用 LXC 驅動程式$ docker run -d –name=’lxc_test’ \
–lxc-conf="lxc.cgroup.cpu.shares=50" \
busybox
# 使用 libcontainer 驅動程式
$ docker run -d –name=’libcontainer_test’ \
–cpu-shares=50 \
busybox
[/bash]
以下是’一些 Cgroup 功能以及它們在兩種驅動程式之間如何對應的概覽:
| 功能 | Libcontainer | LXC |
|---|---|---|
| 相對 CPU 份額 | -c, –cpu-shares | –lxc-conf=”lxc.cgroup.cpu.shares” |
| 鎖定至 CPU 核心 | –cpuset-cpus | –lxc-conf=”lxc.cgroup.cpuset.cpus” |
| 限制記憶體 | -m, –memory | –lxc-conf=”lxc.cgroup.cpuset.mems” |
LXC
如果您想在 Docker 中使用 LXC 驅動程式,您首先需要啟用它。具體的操作方法會因您的 Linux 發行版而異,但以下是關於如何在 Ubuntu 14.04 上啟用 LXC 驅動程式.
如上所述,這樣做時您將放棄許多功能。因此,除非您確實需要某個尚未’在 Docker 中使用 libcontainer 開放的功能,否則您真的應該堅持使用預設驅動程式。
一些尚未在 libcontainer 中開放的實用 Cgroup 策略包括 I/O 節流(在簡報中有介紹),這對某些應用程式來說非常方便。
如果您已決定使用 LXC 驅動程式,新增參數非常簡單。您只需要新增參數 --lxc-conf 並傳入您想’設定的 Cgroup 策略。
Libcontainer
如上表所示,基本的 Cgroup 策略在目前的 Docker 版本(撰寫本文時為 1.6)中已經開放。
使用這些策略非常簡單。例如,如果您想將 Docker 容器鎖定在第一個 CPU 核心,您只需將 --cpuset-cpus=0 附加到您的 docker run 指令中。
您也可以在 libcontainer 中使用 --cgroup-parent 參數,並手動設定更細粒度的資源限制。然後,您可以使用該參數將其對應到該群組。
示範:Docker 搭配 Cgroups
在下方的螢幕錄影中,我們將使用兩個 Docker 容器(‘low_prio’ 和 ‘high_prio’)。我們使用 ‘busybox’ 基礎容器並執行 md5sum /dev/urandom 來模擬一個消耗大量 CPU 的程序。預設情況下,這會消耗所有可用的 CPU 資源。然而,我們將套用兩個 Cgroup 策略來管理資源。首先,我們使用 ‘cpuset.cpus’ 將容器鎖定在同一個 CPU 核心(核心 0)。
接下來,我們使用 ‘cpu.shares’ 來分配相對的 CPU 份額。我們給予 ‘low_prio’ 容器一個值為 20,而 ‘high_prio’ 的值為 80。這意味著 20% 的 CPU 將分配給 ‘low_prio’ 容器,而 80% 的 CPU 將分配給 ‘high_prio’ 容器。但請注意,相對份額是一個任意的比例(我們也可以使用 2 和 8 作為數值)。
在我們證實資源管理確實有效之後,我們將在不套用任何 Cgroup 策略的情況下啟動同一組容器,以觀察它們的行為。
作為參考,以下是用於啟動容器的指令。
[bash light=”true”] $ docker run -d \–name=’low_prio’ \
–cpuset-cpus=0 \
–cpu-shares=20 \
busybox md5sum /dev/urandom
$ docker run -d \
–name=’high_prio’ \
–cpuset-cpus=0 \
–cpu-shares=80 \
busybox md5sum /dev/urandom
[/bash]
總結
如果您在同一台主機上管理多個 Docker 容器,使用 Cgroups 來管理容器之間的資源是非常有意義的。例如,您可能在一個容器中執行一些背景處理任務,而另一個容器則用於提供使用者內容。在這種情況下,您可以使用新學到的知識,確保將面向使用者的容器優先於背景任務。
留言
目前尚無留言。成為第一個留言的人吧。