Linux namespace 和 cgroups,一次性搞清楚~

先放結論,namespace 是用來做資源隔離, cgroup 是用來做資源限制。

Namespace

先說 Namespace,虛擬技術基本要求就是資源隔離,簡單的說就是我獨佔當前所有的資源。比如我在 8080 端口起 web 服務器,不用擔心其他進程端口占用。Linux 自帶 namespace 就能達到這個目的。namespace 從 2002 開始開發到現在已經快 20 年的歷史了,到現在一共有 6 種 namespace:

可以通過三個系統調用的方式

shell 也提供了一個和系統調用同名的 unshare 命令可以非常簡單的創建 namespace。

sudo unshare --fork --pid --mount-proc bash

這樣創建了一個新的 PID namespace 並在裏面運行了 bash。我們看看當前 namespace 的進程

在這個 namespace 裏,就只有兩個進程了。

Cgroups

cgroups 是 control groups 控制組的意思, 可以通過文件系統來訪問這些信息。一般 cgroups 掛載在 /sys/fs/cgroup

內核會讀取這些信息來調度資源分配給每個進程。比如我要限制進程佔用 CPU 的時間。我用 Go 寫了一個模擬高 CPU 的代碼。

func IsPrime(value int) bool {
    for i := 2; i <= int(math.Floor(float64(value)/2)); i++ {
        if value%2 == 0 {
            return false
        }
    }
    return true
}
func main() {
    for i := 0; i < 999999999; i++ {
        fmt.Printf("%v is prime: %v\n", i, IsPrime(i))
    }
}

我創建兩個 CPU 的 cgroups

sudo cgcreate -g cpu:/cpulimited
sudo cgcreate -g cpu:/lesscpulimited

cpu.shares 是給內核爲每個進程決定 CPU 計算資源,默認值是 1024。給 cpulimited 設置爲 512,lesscpulimited 保留默認值,那麼在這兩個組的進程會以 1 :2 的比例佔用 CPU。

sudo cgset -r cpu.shares=512 cpulimited

我們來驗證一下。

在 cpulimited 起一個進程

sudo cgexec -g cpu:cpulimited ./main > /dev/null &

可以看到獨佔了 100% 的 CPU,在 cpulimited 再起一個進程

兩個進程都在 cpulimited,各佔 50% 的 CPU。在 lesscpulimited 起一個進程

sudo cgexec -g cpu:lesscpulimited ./main > /dev/null &

兩個 cpulimited 進程的 CPU 之和 與 一個 lesscpulimited 進程的 CPU 差不多就是 1:2 的關係。

來源:https://zhuanlan.zhihu.com/p/55099839

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/K5UxgdRmn6uZMjcyAICy9w