1. 程式人生 > >容器核心技術詳解

容器核心技術詳解

最近看了docker用到的技術,於是在公司分享了一下,對於Linux核心比較關心的同學肯定早就知道這些知識了,但是我一直對核心不怎麼了解,這些對我來說算是新知識,尋思著後面看看核心相關的書。

Linux Namespace

a feature of the Linux kernel that isolate and virtualize system resources of a collection of processes.

注:linux kernel的一個特性,可以隔離並且虛擬化一組程序的系統資源。

名稱 巨集定義 隔離內容 釋出版本
IPC CLONE_NEWIPC System V IPC, POSIX message queues since Linux 2.6.19
Network CLONE_NEWNET network device interfaces, IPv4 and IPv6 protocol stacks, IP routing tables, firewall rules, the /proc/net and /sys/class/net directory trees, sockets, etc since Linux 2.6.24
Mount CLONE_NEWNS Mount points since Linux 2.4.19
PID CLONE_NEWPID Process IDs since Linux 2.6.24
User CLONE_NEWUSER User and group IDs started in Linux 2.6.23 and completed in Linux 3.8
UTS CLONE_NEWUTS Hostname and NIS domain name since Linux 2.6.19

實驗

我將程式放在github上 fake_docker ,這裡不再貼出程式碼,可以把程式碼下載下來自己玩一玩。

UTS(Unix Time-sharing System)

UTS namespaces allow a single system to appear to have different host and domain names to different processes.

注:允許在一個系統中的不同程序中可以出現不同的主機名和域名

到原始碼的fake_docker目錄,編譯該程式 gcc uts.cpp -o uts ,執行程式 sudo ./uts ,可以看到主機名發生了改變。

IPC (Inter-Process Communication)

IPC namespaces isolate processes from SysV style inter-process communication.

注:隔離SysV風格的程序間通訊

首先建立一個IPC的佇列,可以看到這個msqid為0的佇列

[email protected]:~/fake$ ipcmk -Q
Message queue id: 0
[email protected]:~/fake$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0xa201b648 0          June       644        0            0

同樣編譯ipc.cpp並執行,可以看到IPC中沒有隊列了

[email protected]:~/fake$ ./ipc 
Parent - start a container!
Parent - container stopped!
[email protected]:~/fake$ sudo ./ipc 
[sudo] password for June: 
Parent - start a container!
Container - inside the container!
[email protected]:~/fake# ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages

PID (Process ID)

The PID namespace provides processes with an independent set of process IDs (PIDs) from other namespaces.

注:提供給程序獨立於其它名稱空間的PIDs集合

編譯執行pid.cpp

[email protected]:~/fake$ sudo ./pid 
Parent [19487] - start a container!
Container [    1] - inside the container!

Mount

Mount namespaces control mount points. Upon creation the mounts from the current mount namespace are copied to the new namespace, but mount points created afterwards do not propagate between namespaces (using shared subtrees, it is possible to propagate mount points between namespaces).

注:控制掛載點,將當前的掛載資訊拷貝到新的namespace中,但在次之後的掛載點不在不同的namespace中傳播,除非是用到了shared sybtrees

通過 ls /proc 可以看到有很多檔案和資料夾,以及數字名稱的資料夾,那是對應程序號的程序的一些資訊。

編譯執行mount.cpp,再次列出/proc,可以看到少了好多內容,數字資料夾也只有兩個。

User (User ID)

User namespaces are a feature to provide both privilege isolation and user identification segregation across multiple sets of processes.

注: 跨程序集合的許可權和使用者身份隔離

Network

Network namespaces virtualize the network stack. Each namespace will have a private set of IP addresses, its own routing table, socket listing, connection tracking table, firewall, and other network-related resources.

注:虛擬化網路棧,每個namespace會有自己私有的ip地址、路由表、socket清單、連線追蹤表、防火牆以及別的網路相關的資源

cgroup(Control Group)

  • Resource limitation: 限制資源使用,比如記憶體使用上限以及檔案系統的快取限制。
  • Prioritization: 優先順序控制,比如:CPU利用和磁碟IO吞吐。
  • Accounting: 一些審計或一些統計,主要目的是為了計費。
  • Control: 掛起程序,恢復執行程序。

Linux把CGroup實現成了一個file system,通過mount來啟用一個控制組, 如下通過mount命令顯示型別為cgroup的mount point。

June@Payne:~/fake$ 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/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)

...

或者使用lssubsys命令,如果沒有的需要安裝相應的軟體包 sudo apt install cgroup-tools

June@Payne:~$ lssubsys -m
cpuset /sys/fs/cgroup/cpuset
cpu,cpuacct /sys/fs/cgroup/cpu,cpuacct
blkio /sys/fs/cgroup/blkio

...

列出 /sys/fs/cgroup 目錄我們可以看到很多目錄,每個目錄表示一種資源。

[email protected]:~$ ls /sys/fs/cgroup/
blkio  cgmanager  cpu  cpuacct  cpu,cpuacct  cpuset  devices  freezer  hugetlb  memory  net_cls  net_cls,net_prio  net_prio  perf_event  pids  systemd

實驗

以下程式碼deadloop.cpp是一個死迴圈,我們用gcc編譯並執行。

#include <sys/types.h>
#include <unistd.h>

int main(void)
{
    printf("PID [%5d] \n", getpid());
    int i = 0;
    for(;;) i++;
    return 0;
}

毫無疑問,cpu一定會飆到100%,接下來我們就用cgroup來控制這個程式的cpu佔用率。

PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND  
13420 June      20   0    4360    656    580 R 98.7  0.1   0:34.26 deadloop

轉到 /sys/fs/cgroup/cpu ,可以看到像 cpu.stat 、 cpu.stat 這樣的檔案,然後建立一個目錄 sudo mkdir xp ,進入xp目錄,發現已經有了和上層目錄同樣的檔案,這個xp目錄就相當於是一個控制組的配置目錄,我們把該組的cpu佔用限制一下。

[email protected]:/sys/fs/cgroup/cpu/xp$ cat cpu.cfs_quota_us 
-1
[email protected]:/sys/fs/cgroup/cpu/xp$ sudo sh -c "echo 20000 >  cpu.cfs_quota_us"

然後將deadloop的pid加到tasks檔案中

[email protected]:/sys/fs/cgroup/cpu/xp$ sudo sh -c "echo 13420 >  tasks"

[email protected]:/sys/fs/cgroup/cpu/xp$ top -p 13420

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND  
13420 June      20   0    4360    656    580 R 20.3  0.1   3:03.35 deadloop

cgroup能夠實現資源的層級管理,例如直接在xp目錄下建一個test,test目錄會繼承xp目錄中已有的屬性。

要把程序移出控制組,把 pid 寫入到根 cgroup 的 tasks 檔案即可。因為每個程序都屬於且只屬於一個 cgroup,加入到新的 cgroup 後,原有關係也就解除了。要刪除一個 cgroup,可以用 rmdir 刪除相應目錄。不過在刪除前,必須先讓其中的程序全部退出,對應子系統的資源都已經釋放,否則是無法刪除的。當然如果有子控制組,需要先將其刪除之後才能刪除父控制組。

關於cgroup的內容比較多,這裡不是主要講這個的,大概理解cgroup是幹什麼的就可以,docker用run命令啟動一個容器的時候,通過後面帶的引數來限制資源,當然內部就是用的cgroup的功能。

概念解析

  • 任務(Tasks):就是系統的一個程序。
  • 控制組(Control Group):一組按照某種標準劃分的程序,比如官方文件中的Professor和Student,或是WWW和System之類的,其表示了某程序組。Cgroups中的資源控制都是以控制組為單位實現。一個程序可以加入到某個控制組。而資源的限制是定義在這個組上,就像上面示例中我用的xp目錄一樣。簡單點說,cgroup的呈現就是一個目錄帶一系列的可配置檔案。
  • 層級(Hierarchy):控制組可以組織成hierarchical的形式,既一顆控制組的樹(目錄結構)。控制組樹上的子節點繼承父結點的屬性。簡單點說,hierarchy就是在一個或多個子系統上的cgroups目錄樹。
  • 子系統(Subsystem):一個子系統就是一個資源控制器,比如CPU子系統就是控制CPU時間分配的一個控制器。子系統必須附加到一個層級上才能起作用,一個子系統附加到某個層級以後,這個層級上的所有控制族群都受到這個子系統的控制。Cgroup的子系統可以有很多,也在不斷增加中。

UnionFS

目的:把不同物理位置的目錄合併mount到同一個目錄中

原理說明

寫時複製(CoW)

所有驅動都用到的技術——寫時複製(CoW)。CoW就是copy-on-write,表示只在需要寫時才去複製,這個是針對已有檔案的修改場景。比如基於一個image啟動多個Container,如果為每個Container都去分配一個image一樣的檔案系統,那麼將會佔用大量的磁碟空間。而CoW技術可以讓所有的容器共享image的檔案系統,所有資料都從image中讀取,只有當要對檔案進行寫操作時,才從image裡把要寫的檔案複製到自己的檔案系統進行修改。所以無論有多少個容器共享同一個image,所做的寫操作都是對從image中複製到自己的檔案系統中的複本上進行,並不會修改image的原始檔,且多個容器操作同一個檔案,會在每個容器的檔案系統裡生成一個複本,每個容器修改的都是自己的複本,相互隔離,相互不影響。使用CoW可以有效的提高磁碟的利用率。

用時分配(allocate-on-demand)

而寫時分配是用在原本沒有這個檔案的場景,只有在要新寫入一個檔案時才分配空間,這樣可以提高儲存資源的利用率。比如啟動一個容器,並不會為這個容器預分配一些磁碟空間,而是當有新檔案寫入時,才按需分配新空間。

Docker用到的實現

AUFS (Advance UnionFS)

Linus不同意併入kernel,但ubuntu、debian、gentoo支援

AUFS(AnotherUnionFS)是一種Union FS,是檔案級的儲存驅動。AUFS能透明覆蓋一或多個現有檔案系統的層狀檔案系統,把多層合併成檔案系統的單層表示。簡單來說就是支援將不同目錄掛載到同一個虛擬檔案系統下的檔案系統。這種檔案系統可以一層一層地疊加修改檔案。無論底下有多少層都是隻讀的,只有最上層的檔案系統是可寫的。當需要修改一個檔案時,AUFS建立該檔案的一個副本,使用CoW將檔案從只讀層複製到可寫層進行修改,結果也儲存在可寫層。在Docker中,底下的只讀層就是image,可寫層就是Container。結構如下圖所示:

btrfs

Btrfs被稱為下一代寫時複製檔案系統,併入Linux核心,也是檔案級級儲存,但可以像Device mapper一直接操作底層裝置。Btrfs把檔案系統的一部分配置為一個完整的子檔案系統,稱之為subvolume 。那麼採用 subvolume,一個大的檔案系統可以被劃分為多個子檔案系統,這些子檔案系統共享底層的裝置空間,在需要磁碟空間時便從底層裝置中分配,類似應用程式呼叫 malloc()分配記憶體一樣。為了靈活利用裝置空間,Btrfs 將磁碟空間劃分為多個chunk 。每個chunk可以使用不同的磁碟空間分配策略。比如某些chunk只存放metadata,某些chunk只存放資料。這種模型有很多優點,比如Btrfs支援動態新增裝置。使用者在系統中增加新的磁碟之後,可以使用Btrfs的命令將該裝置新增到檔案系統中。Btrfs把一個大的檔案系統當成一個資源池,配置成多個完整的子檔案系統,還可以往資源池裡加新的子檔案系統,而基礎映象則是子檔案系統的快照,每個子映象和容器都有自己的快照,這些快照則都是subvolume的快照。

device mapper

Device mapper是Linux核心2.6.9後支援的,提供的一種從邏輯裝置到物理裝置的對映框架機制,在該機制下,使用者可以很方便的根據自己的需要制定實現儲存資源的管理策略。前面講的AUFS和OverlayFS都是檔案級儲存,而Device mapper是塊級儲存,所有的操作都是直接對塊進行操作,而不是檔案。Device mapper驅動會先在塊裝置上建立一個資源池,然後在資源池上建立一個帶有檔案系統的基本裝置,所有映象都是這個基本裝置的快照,而容器則是映象的快照。所以在容器裡看到檔案系統是資源池上基本裝置的檔案系統的快照,並不有為容器分配空間。當要寫入一個新檔案時,在容器的映象內為其分配新的塊並寫入資料,這個叫用時分配。當要修改已有檔案時,再使用CoW為容器快照分配塊空間,將要修改的資料複製到在容器快照中新的塊裡再進行修改。Device mapper 驅動預設會建立一個100G的檔案包含映象和容器。每一個容器被限制在10G大小的卷內,可以自己配置調整。結構如下圖所示:

overlay

Overlay是Linux核心3.18後支援的,也是一種Union FS,和AUFS的多層不同的是Overlay只有兩層:一個upper檔案系統和一個lower檔案系統,分別代表Docker的映象層和容器層。當需要修改一個檔案時,使用CoW將檔案從只讀的lower複製到可寫的upper進行修改,結果也儲存在upper層。在Docker中,底下的只讀層就是image,可寫層就是Container。結構如下圖所示:

當寫入一個新檔案時,為在容器的快照裡為其分配一個新的資料塊,檔案寫在這個空間裡,這個叫用時分配。而當要修改已有檔案時,使用CoW複製分配一個新的原始資料和快照,在這個新分配的空間變更資料,變結束再更新相關的資料結構指向新子檔案系統和快照,原來的原始資料和快照沒有指標指向,被覆蓋。

ZFS

ZFS 檔案系統是一個革命性的全新的檔案系統,它從根本上改變了檔案系統的管理方式,ZFS 完全拋棄了“卷管理”,不再建立虛擬的卷,而是把所有裝置集中到一個儲存池中來進行管理,用“儲存池”的概念來管理物理儲存空間。過去,檔案系統都是構建在物理裝置之上的。為了管理這些物理裝置,併為資料提供冗餘,“卷管理”的概念提供了一個單裝置的映像。而ZFS建立在虛擬的,被稱為“zpools”的儲存池之上。每個儲存池由若干虛擬裝置(virtual devices,vdevs)組成。這些虛擬裝置可以是原始磁碟,也可能是一個RAID1映象裝置,或是非標準RAID等級的多磁碟組。於是zpool上的檔案系統可以使用這些虛擬裝置的總儲存容量。

下面看一下在Docker裡ZFS的使用。首先從zpool裡分配一個ZFS檔案系統給映象的基礎層,而其他映象層則是這個ZFS檔案系統快照的克隆,快照是隻讀的,而克隆是可寫的,當容器啟動時則在映象的最頂層生成一個可寫層。如下圖所示:

當要寫一個新檔案時,使用按需分配,一個新的資料快從zpool裡生成,新的資料寫入這個塊,而這個新空間存於容器(ZFS的克隆)裡。

當要修改一個已存在的檔案時,使用寫時複製,分配一個新空間並把原始資料複製到新空間完成修改。

參考內容

相關推薦

容器核心技術

最近看了docker用到的技術,於是在公司分享了一下,對於Linux核心比較關心的同學肯定早就知道這些知識了,但是我一直對核心不怎麼了解,這些對我來說算是新知識,尋思著後面看看核心相關的書。 Linux Namespace a feature of the Linux

掃地機器人的構造及核心技術

智能掃地機器人  掃地機器人,又稱自動打掃機、智能吸塵、機器人吸塵器等,是智能家居電器的一種,能憑借一定的人工智能,自動在房間內完成地板清理工作。一般采用刷掃和真空方式,將地面雜物先吸納進入自身的垃圾收納盒,從而完成地面清理的功能。一般來說,將完成清掃、吸塵、擦地工作的機器人,也統一歸為掃地機器人。  掃地機

《Unity3D 實戰核心技術》書中關於矩陣的錯誤

不同的 linear 應該 印刷 幫助 tar 線性代數 計算 計算機圖形學 最近一直在學習實時渲染,不免要接觸線性代數。而渲染中,一定會用到矩陣,當我再次去復習我之前看的書時,發現《Unity3D 實戰核心技術詳解》關於矩陣就有幾處錯誤 ,特標註出來。 書的第一章《3

[轉帖]記憶體核心頻率、工作頻率,等效頻率、預讀取技術

https://blog.csdn.net/hit_shaoqi/article/details/78121556 ■何為記憶體頻率  對於記憶體條,相信大家並不陌生。因為記憶體已經成為每臺電腦的必備配件,從EDO、SDRAM、DDR、DDR2再到現如今的DDR3記憶體,變化可謂是翻天覆地。記憶體無論是在

容器技術

一、什麼是容器? IT裡的容器技術是英文單詞Linux Container的直譯。container這個單詞有集裝箱、容器的含義(主要偏集裝箱意思)。不過,在中文環境下,咱們要交流要傳授,如果翻譯成“集裝箱技術” 就有點拗口,所以結合中國人的吐字習慣和文化背景,更喜歡用容器這個詞。不過,如果要形

Java 進階——多執行緒優化之執行緒池 ThreadPoolExecutor的核心容器阻塞佇列(一)

#引言 多執行緒我想無論是後端開發,還是對於App開發者來說都不會陌生,何況Android強制要求不能在主執行緒中做網路請求,於是乎,在很多初學者或者App的原始碼中會出現會多的new Thread…的方式,這樣的程式碼是不優雅而且存在很多的隱患,假如說在使用者

記憶體核心頻率、工作頻率,等效頻率、預讀取技術

DRAM (Synchronous Dynamic Random-Access Memory)SDRAM的工作原理,實際上,它內部包括了許多儲存單元陣列,以及輸入/輸出快取和電源/重新整理電路,最後一個單元(電源/重新整理電路)和我們下面的描述沒有關係。它的三個子系統(儲存單元陣列,輸入/輸出快取)都以相

實現高性能糾刪碼引擎 | 糾刪碼技術(下)

糾刪碼引擎 基礎知識 深入優化 技術 工程師 作者介紹: 徐祥曦,七牛雲工程師,獨立開發了多套高性能糾刪碼/再生碼編碼引擎。柳青,華中科技大學博士,研究方向為基於糾刪碼的分布式存儲系統。前言:在上篇《如何選擇糾刪碼編碼引擎》中,我們簡單了解了 Reed-Solomon Codes(RS 碼

Nginx技術(2)

web服務器 nginx部署一個Web站點:服務器準備:node0IP:192.168.10.3進入/application/nginx/html/下把index.html文件刪除:rm -rf /application/nginx/html/index.html創建index.html文件,並追加文本:ec

Nginx技術(1)

web服務器 nginxNginx Web服務應用:Nginx(engine x)是一個開源的,支持高並發的www服務和代理服務軟件。Nginx是俄羅斯人Igor Sysoev開發的,最初被應用到俄羅斯的大型網站(www.rambler.ru)上。後來作者將源代碼以類BSD許可證的形式開源出來供全球使用。在功

JSP/Servlet及相關技術

script return 指令 o-c rip title info turn expires JSP聲明 <%!聲明部分%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitio

C#漢字轉換拼音技術(高性能)

rim none pie 存在 asp pub net 如果 pinyin public static class ChineseToPinYin { private static readonly Dictionary<<span class=

14.javaweb AJAX技術

填充 cut pub cti div htm .get conn lec 一、簡介 1, ajax:在不重新加載網頁的前提下,與服務器交換數據並更新部分網頁的技巧,但其本身並不是一種新技術 2, 核心:XMLHttpRequest對象。AJAX技術主要是通過此

CDN技術(七)

事務 失敗 需求 重復數 ebsp 一個 解析 設置 不用 動態內容加速服務的實現 隨著Web2.0的興起,產生了動態網頁、個性化內容、電子交易數據等內容的加速,這些就涉及了動態內容加速技術。 靜態內容的加速,都是對於表現層的加速,對於動態頁面等內容的加速,則要涉及邏輯層

HTTP協議報文、工作原理及Java中的HTTP通信技術

tor 報文 buffered mod protoc 禁止 ans 請求報文 客戶端 博客園 首頁 新隨筆 聯系 管理 訂閱

ajax技術,封裝一個原生的ajax請求

status 語法 match 基礎上 abort param sync 可選參數 導致 一、Ajax 概述 Ajax 是 Asynchronous Javascript And XML 的簡寫 Ajax是一門技術,並不是一門語言 使用XHTML+CSS來標準化呈現 使

mysql主從復制技術

mysql主從復制技術詳解M-S主服務器:master1第一步:打開bin-log日誌,設置如下:vim /etc/my.cnflog_binserver-id=1gtid_mode=ONenforce_gtid_consistency=1第二步:進入數據庫授權用戶mysql -uroot -p‘密碼‘gra

WEB網站滲透技術

大拇指 一段 上傳 二次開發 們的 好好學習 提交 tar AR 有兩天沒發文章了,今天給大家來個大頭,那就是WEB網站滲透測試入侵教程 這個WEB網站滲透測試教程~是我見過的幾個少數的讓我看完就豎大拇指的教程 這部教程那可是我只能用棒棒的來形容說不出其他話來的 WEB網站

進階-中小型網絡構建-二層VLAN技術配實驗步驟

中小型網絡構建進階-中小型網絡構建-二層VLAN技術詳解配實驗步驟為什麽講 VLAN ? 在傳統的交換網絡中,為了隔離沖突域,我們引入了交換機。 交換機的每一個端口都是一個不同的隔離域。 但是交換機無法隔離廣播域, 所以,如果網絡中有一個惡意的主機發送廣播的惡意流量, 那麽處於同一個交換網路中的所有設備

ThinkPHP 緩存技術 使用大S方法

sqlite 前臺 thum port class 比較 pac 周期性 百萬 如果沒有緩存的網站是百萬級或者千萬級的訪問量,會給數據庫或者服務器造成很大的壓力,通過緩存,大幅減少服務器和數據庫的負荷,假如我們把讀取數據的過程分為三個層,第一個是訪問層,第一個是緩存層