返回部落格

使用 Cgroups 管理 Docker 資源

使用 Cgroups 管理 Docker 資源

上個月我 在 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 來管理容器之間的資源是非常有意義的。例如,您可能在一個容器中執行一些背景處理任務,而另一個容器則用於提供使用者內容。在這種情況下,您可以使用新學到的知識,確保將面向使用者的容器優先於背景任務。

author

Viktor Petersson

作者 · CloudSigma

Preslav Dobrev 是 CloudSigma 的創意設計師,專注於透過傳統與創新行銷渠道建立一致的企業形象。他擅長將藝術願景與策略行銷相融合,創造具有影響力的品牌敘事。

留言

目前尚無留言。成為第一個留言的人吧。