系列檔案目錄
第一章:容器技術發展程序
第二章:容器底層技術
目錄
- 系列檔案目錄
- 前言
- 一、Namespace
- 先從Linux提供的“命名空間API說起”
- clone()
- unshare()
- setns()
- mount命名空間
- UTS命名空間
- Network命名空間
- User命名空間
- IPC命名空間
- PID命名空間
- 二、Cgroups
- 1. Cgroups功能介紹:
- 2. Cgroups子系統介紹
- 三、容器種類
- 總結
前言
容器底層技術依賴核心的Cgroups和Namespace
一、Namespace
先從Linux提供的“命名空間API說起”
-
clone()
通過flags參數來控制建立新程序的特性,使得"新建立的程序"擁有獨立的Namespace
本質上clone()是一個通用的fork()版本,fork()的功能由flags參數控制。/proc/PID/ns目錄下為每個命名空間對應一個檔案,這些描述符連結可以用來判斷兩個命名空間是否在同一個命名空間。如果兩個程序在同一個命名空間,核心會保證/proc/PIC/ns導出的inode号是一樣的。
#define _GNU_SOURCE
#include <sched.h>
int clone(int (*fn)(void *), void *stack, int flags, void *arg);
/*
**int (*fn)(void *) --子程序要執行的函數
**void *stack --子程序棧
**int flags --CLONE_NEW* flags的組合
**void *arg --傳給子程序參數
*/
-
unshare()
将"目前程序"和所在的Namespace分離,并加入到一個新的Namespace中
#define _GNU_SOURCE
#include <sched.h>
int unshare(int flags);
/*
**int flags --需要脫離的命名空間并建立新的命名空間CLONE_NEW*
*/
-
setns()
将“目前程序”關聯一個存在的命名空間
setns()将調用的程序和一個特定的命名空間解除關系并将該程序和一個同類型的命名空間關聯。使用setns()和execve()能建構一個簡單但有用的工具,一個和特定命名空間關聯的程式并且在命名空間中可以執行一個指令。
#define _GNU_SOURCE
#include <sched.h>
int setns(int fd, int nstype);
/*
**int fd --fd引用/proc/[pid]/ns/ link連接配接,或者是一個PID file descriptor
**int nstype --用來檢查fd關聯的Namespace是否與nstype表明的Namespace一緻,如果填0将不檢查
*/
mount命名空間
- 用于隔離一組程序看到的檔案系統挂載點集合(處于不同mount命名空間的程序看到的檔案系統不一樣,賦予容器不同的檔案系統)
- CLONE_NEWNS
- mount() / unmount()系統調用
UTS命名空間
- 隔離了兩個系統變量,節點名+域名(UTS賦予了每個容器各自的主機名+域名)
- CLONE_NEWUTS
- uname()系統調用傳回UTS
- setnodename()系統調用,設定節點名
- setdomainname()系統調用,設定域名
Network命名空間
- 隔離和網絡有關的資源,使得每個網絡命名空間有其自己的網絡裝置、IP位址、IP路由表、/proc/net目錄、端口号等。讓每個container擁有自己的網絡裝置(虛拟的)和網絡端口号。
- CLONE_NEWNET
User命名空間
- 隔離使用者ID群組ID,一個使用者ID在命名空間之外非特權,而在命名空間之内具有特權,讓不同User命名空間的container擁有不同的特權。
- CLONE_NEWUSER
IPC命名空間
- 隔離程序間通信資源
- CLONE_NEWIPC
- System V IPC表示符和POSIX消息隊列
PID命名空間
- 隔離程序ID号,不同命名空間的程序ID可以相同,保證了每個container能有自己的1号init程序。
- CLONE_NEWPID
- 一個程序有2個PID,一個ID屬于PID命名空間,一個ID屬于主機系統
二、Cgroups
Cgroups是控制組群的簡寫(Control groups),是Linux核心的一個功能,用來限制、控制與分離一個程序組的資源(如cpu、記憶體、磁盤、IO輸入輸出等)。Cgroups是LXC(Linux Container)實作容器虛拟化的基礎。
這個項目最早由Google的工程師在2006年發起,最早的名稱為“程序容器(process containers)”。但在Linux核心中,容器(container)這個詞有許多不同的意義,為了避免混亂,被重命名為cgroups,并合入到Linux kernel 2.6.24版本中。
1. Cgroups功能介紹:
Cgroups功能 | 描述 |
資源限制 | 對資源可以設定一個不超過的上線值。例如:控制組可以被設定不超過設定值的記憶體限制,也包括虛拟記憶體。 |
優先級 | 設定資源的占有比例,讓占有比例多的獲得更多的資源,間接達到優先級的效果。例如:一些組可能會得到大量的CPU或者磁盤IO吞吐量。 |
結算 | 用來度量系統實際用了多少資源 |
控制 | 當機組或檢查點和重新開機動 |
2. Cgroups子系統介紹
Cgroups子系統 | 描述 |
cpu | 使用排程程式提供對CPU的cgroup任務通路 |
cpuset | 為cgroup中的任務配置設定獨立CPU(在多核系統)和記憶體節點 |
cpuacct | 自動生成cgroup中任務所使用的CPU報告 |
memory | 設定cgroup中任務使用記憶體的限制,并自動生成由那些任務使用的記憶體資源報告 |
blkio | 為塊裝置設定輸入/輸出限制,比如實體裝置(磁盤、固态硬碟、USB等) |
devices | 可允許或者拒絕cgroup中的任務通路裝置 |
freezer | 挂起或者恢複cgroup中的任務 |
三、容器種類
容器類型 | 技術路線 | 注釋 |
lxc(linux container) | LXC容器常常被考慮為介于chroot和virtual machine之間的一個事物。LXC的目标是建立一個和标準安裝的linux系統盡可能一樣的環境,但不需要單獨的kernel。 LXC可以為容器綁定特定的cpu和memory,配置設定特定比例的cpu時間,IO時間,限制可以使用的記憶體大小,提供device通路控制,提供獨立的namespace(network、pid、ipc、mnt、uts) LXC用了一下kernel feature:
| lxc-checkconfig 用于判斷linux核心是否支援LXC lxc-create 用于建立一個容器 lxc-execute 用于在一個容器執行應用程式 lxc-cgroup 用于擷取或調整與cgroup相關的參數 |
systemd-nspawn |
| 以systemd服務啟動systemd-nspawn容器: [Service] ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth --machine =%I |
cells | linux kernel的namespace和cgroups機制 | 哥倫比亞大學論文:http://systems.cs.columbia.edu/projects/cells/ 浙大github項目:http://condroid.github.io/ 以色列公司網址:https://www.cellrox.com/ |
containerd | Containerd是一個行業标準的容器運作時container runtime,強調簡單性、健壯性和可移植性。它可以作為Linux和Windows的守護程序,也可以管理其主機系統的容器完整的生命周期:image鏡像的傳輸和存儲、容器執行和監督、低級存儲和網絡附件等。 Containerd被設計為嵌入到更大的系統中,而不是被開發人員或最終使用者直接使用。 | containerd是CNCF成員,是已經畢業狀态,很穩定 github項目:https://github.com/containerd/containerd |
CRI-O | 基于oci的Kubernetes容器運作時接口的實作。 crio的目的是在符合OCI的運作時和kubelet之間提供內建路徑。具體來說,它使用符合OCI的運作時實作了Kubelet容器運作時接口(CRI)。CRI- o的範圍與CRI的範圍綁定在一起。
| github項目:https://github.com/cri-o/cri-o |
總結
- mount命名空間、UTS命名空間、Network命名空間、User命名空間,這4個命名空間可以了解為建構container環境Env的。
- IPC命名空間、PID命名空間,這2個命名空間可以了解為container運作時相關的。