什麼是 cgroup (Control Group) 和 Namespaces (Name spaces) ? 要先說什麼是 container ?
Container 與虛擬機類似,都是在原作業系統提供一個環境給另外一個作業系統來使用,虛擬機器 Virtual Machine 透過 VMM (Virtual Machine Monitor,也可以稱作 Hybervisor) 的方式來建立一個虛擬化的環境給虛擬機的作業系統來使用,而 Container 是在原作業系統中透過資源共享的方式,建立出一個獨立空間,這環境有自己的 file system, process 與 block I/O ,network.
傳統的 VMM 優點是所有的作業系統我們都可以模擬,但需要透過 VMM 效能會比較差一點,Container 只能使用在 Linux 同值性的作業系統下,透過資源共享,效能佳,也不會消耗過多的系統資源.
但 Container 要如何隔離主系統與 Containers 之間的存取? 與限制 Containers 使用的資源?
這就需要透過 cgroup & namespace 這兩項功能 (Linux 核心從 2.6.24 之後的版本內建了 Control Group 和 Namespaces ),
測試環境為 Ubuntu 16.04 x86_64 虛擬機.
Cgroup (Control Group)
Linux kernel 的 cgroups 可以針對 Container 下的資源(CPU , Memory , Block I/O , network , etc.)進行限制和優先順序.
下面兩個指令,可以清楚看到我們可以透過 Cgroup 去限制哪些資源.
root@ubuntu:~# mount -t cgroup cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct) cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio) cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb) cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
root@ubuntu:~# lssubsys -m cpuset /sys/fs/cgroup/cpuset cpu,cpuacct /sys/fs/cgroup/cpu,cpuacct blkio /sys/fs/cgroup/blkio memory /sys/fs/cgroup/memory devices /sys/fs/cgroup/devices freezer /sys/fs/cgroup/freezer net_cls,net_prio /sys/fs/cgroup/net_cls,net_prio perf_event /sys/fs/cgroup/perf_event hugetlb /sys/fs/cgroup/hugetlb pids /sys/fs/cgroup/pids
範例:限制 CPU 資源
- 建立 group
root@ubuntu:~# mkdir /sys/fs/cgroup/cpu/limitg1 root@ubuntu:~# ll /sys/fs/cgroup/cpu/limitg1 total 0 drwxr-xr-x 2 root root 0 Dec 28 19:09 ./ dr-xr-xr-x 4 root root 0 Dec 28 19:09 ../ -rw-r--r-- 1 root root 0 Dec 28 19:09 cgroup.clone_children -rw-r--r-- 1 root root 0 Dec 28 19:09 cgroup.procs -r--r--r-- 1 root root 0 Dec 28 19:09 cpuacct.stat -rw-r--r-- 1 root root 0 Dec 28 19:09 cpuacct.usage -r--r--r-- 1 root root 0 Dec 28 19:09 cpuacct.usage_percpu -rw-r--r-- 1 root root 0 Dec 28 19:09 cpu.cfs_period_us -rw-r--r-- 1 root root 0 Dec 28 19:09 cpu.cfs_quota_us -rw-r--r-- 1 root root 0 Dec 28 19:09 cpu.shares -r--r--r-- 1 root root 0 Dec 28 19:09 cpu.stat -rw-r--r-- 1 root root 0 Dec 28 19:09 notify_on_release -rw-r--r-- 1 root root 0 Dec 28 19:09 tasks
- 限制特定 group 使用 20% CPU 的資源
root@ubuntu:~# echo 20000 > /sys/fs/cgroup/cpu/limitg1/cpu.cfs_quota_us
cpu.cfs_quota_us 值設定要參考 cpu.cfs_period_us 20000/100000 =20%
root@ubuntu:~# cat /sys/fs/cgroup/cpu/limitg1/cpu.cfs_period_us 100000 root@ubuntu:~# cat /sys/fs/cgroup/cpu/limitg1/cpu.cfs_quota_us 20000
- 指派 process 到 group (limitg1)
透過 #top 去觀察,這個 random.sh script (PID: 2262) 已經用掉大部分的 CPU 所有資源.root@ubuntu:~# cat random.sh #!/bin/bash while true do echo $RANDOM done root@ubuntu:~# ./random.sh
top - 19:11:20 up 50 min, 3 users, load average: 0.42, 0.16, 0.14 Tasks: 215 total, 3 running, 212 sleeping, 0 stopped, 0 zombie %Cpu(s): 42.7 us, 54.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 3.3 si, 0.0 st KiB Mem : 998228 total, 79544 free, 281580 used, 637104 buff/cache KiB Swap: 1046524 total, 1041148 free, 5376 used. 485620 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2262 root 20 0 12520 908 800 R 43.7 0.1 0:04.22 random.sh
root@ubuntu:~# echo 2262 >> /sys/fs/cgroup/cpu/limitg1/tasks
透過 #top 去觀察,可以看到 random.sh script 被限制最高只能使用 20% 的 CPU 資源.
top - 19:15:00 up 53 min, 3 users, load average: 0.76, 0.68, 0.37 Tasks: 214 total, 3 running, 211 sleeping, 0 stopped, 0 zombie %Cpu(s): 15.5 us, 28.0 sy, 0.0 ni, 54.7 id, 0.0 wa, 0.0 hi, 1.7 si, 0.0 st KiB Mem : 998228 total, 79364 free, 281688 used, 637176 buff/cache KiB Swap: 1046524 total, 1041148 free, 5376 used. 485448 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2262 root 20 0 12520 908 800 R 20.2 0.1 1:07.79 random.sh
Namespace (Name spaces)
namespace 提供了 Container 彼此之間與作業系統是完全隔離且不受影響的, 提供 pid (Process ID) , network , IPC (interprocess communication) , mount , UTS (UNIX Time-sharing System) , User 等 namespace.
Ubuntu – LXC
Ubuntu 採用 LXC (Linux Containers) 作業系統層的虛擬化技術 (Operating system–level virtualization) 實現 Container 技術.
- LXC (Linux Containers) 基礎介紹 – https://benjr.tw/95955
- LXC (Linux Containers) 的使用 – https://benjr.tw/93708
- LXC 的網路架構 – https://benjr.tw/96074