從操作系統(tǒng)看Docker
Linux 操作系統(tǒng)的內(nèi)核裁剪不僅是為了提升系統(tǒng)的安全性,而且是為了進(jìn)一步提升應(yīng)用系統(tǒng)的性能。Linux 的內(nèi)核裁剪技術(shù)并沒有得到廣泛的應(yīng)用,對(duì)于安全性、應(yīng)用的性能以及開發(fā)效率而言,業(yè)界普遍采用的是虛擬化技術(shù)——虛擬機(jī)和容器。無論哪一種虛擬化技術(shù),本質(zhì)上都可以看作是操作系統(tǒng)能力的抽象、分拆和組合。
虛擬化技術(shù)一瞥
無論是哪一種虛擬化技術(shù),都是在操作系統(tǒng)之上的不同抽象,從而形成了分層的架構(gòu)。層次越多,調(diào)用鏈也相應(yīng)地變長,運(yùn)行時(shí)的開銷也就越大。
如上圖所示,虛擬機(jī)中的Hypervisor 這一層是一個(gè)常用的硬件虛擬化軟件,把操作系統(tǒng)抽象為多個(gè)底層的硬件接口,利用這些硬件接口,虛擬機(jī)可以實(shí)現(xiàn)自己操作系統(tǒng)。Docker則不同, 它構(gòu)建在原有的操作系統(tǒng)之上,是某種程度的復(fù)用。
從部署時(shí)間來看,物理機(jī)由于涉及到采購和軟硬件安裝等因素,部署的時(shí)間最長,虛擬機(jī)則要短很多,Dcoker則是秒級(jí)的。
2013年,Docker 對(duì)外開源,2014年6月9日正式發(fā)布,很快便風(fēng)靡全球,容器虛擬化技術(shù)的發(fā)展脈絡(luò)大致是這樣的——
Docker 的 OS 依賴
Docker 構(gòu)建于操作系統(tǒng)之上,是強(qiáng)依賴于操作系統(tǒng)的虛擬化技術(shù),依賴于Cgroup來管理進(jìn)程組,依賴于命名空間來實(shí)現(xiàn)資源隔離,通過特定的文件系統(tǒng)來使用操作系統(tǒng)自身的文件系統(tǒng)。
Cgroup
Cgroup全稱為Linux Control Group,是 Linux 內(nèi)核的一個(gè)功能,用來限制、控制與分離一個(gè)進(jìn)程組的資源(如CPU、內(nèi)存、磁盤輸入輸出等)。
Cgroup是由Google的工程師在2006年發(fā)起的,最早的名稱為進(jìn)程容器(process containers)。在2007年,由于在Linux內(nèi)核中,容器這個(gè)名詞有許多不同的意義,進(jìn)而被重命名為cgroup,并且被合并到2.6.24的內(nèi)核版本中,后來又添加了很多功能。
Cgroup的主要功能:
限制進(jìn)程組可以使用的資源數(shù)量,例如,可以為進(jìn)程組設(shè)定一個(gè)內(nèi)存使用的上限,一旦進(jìn)程組使用的內(nèi)存達(dá)到限額再申請(qǐng)內(nèi)存,就會(huì)觸發(fā)OOM。
進(jìn)程組的優(yōu)先級(jí)控制,例如,可以使用為某個(gè)進(jìn)程組分配特定的cpu share。
記錄進(jìn)程組使用的資源數(shù)量,例如,可以記錄某個(gè)進(jìn)程組使用的cpu時(shí)間
進(jìn)程組隔離,例如,可以使不同的進(jìn)程組使用不同的命名空間,以達(dá)到隔離的目的,不同的進(jìn)程組有各自的進(jìn)程、網(wǎng)絡(luò)、文件系統(tǒng)掛載空間。
進(jìn)程組控制,例如,將進(jìn)程組掛起和恢復(fù)。
命名空間
Namespace(命名空間) 是 Linux 提供的一種內(nèi)核級(jí)別資源隔離的方法。又稱為命名空間,它主要做訪問隔離,即同一個(gè)命名空間的多個(gè)資源(memory, CPU, network, pid)可以相互看到,但是之外的看不到。
目前Linux Namespace 大致有7種,如下表所示:
類型 | 系統(tǒng)調(diào)用參數(shù) | 隔離資源 |
Mount | CLONE_NEWNS | 系統(tǒng)掛載點(diǎn) |
IPC | CLONE_NEWIPC | system V IPC(信號(hào)量,消息隊(duì)列,共享內(nèi)存等) |
UTS | CLONE_NEWUTS | 主機(jī)名,NIS域名 |
PID | CLONE_NEWPID | 進(jìn)程PID |
Network | CLONE_NEWNET | 網(wǎng)絡(luò)設(shè)備,協(xié)議棧,端口 |
User | CLONE_NEWUSER | 用戶和用戶組 |
Cgroup | CLONE_NEWCGROUP | Cgroup 根目錄 |
這樣, 通過對(duì)內(nèi)核的系統(tǒng)調(diào)用,即可實(shí)現(xiàn)相應(yīng)的資源隔離。
多層單一化文件系統(tǒng)
早期的Docker使用AUFS文件系統(tǒng),是Docker image的基石,可以將分布在不同地方的目錄掛載到同一個(gè)虛擬文件系統(tǒng)中,只有第一層(第一個(gè)文件夾層級(jí))是可寫的,其余層是只讀的,增加/刪除文件時(shí)都會(huì)轉(zhuǎn)換為寫操作寫入可寫層。AUFS 的 Cow 特性能夠允許在多個(gè)容器之間共享分層,從而減少物理空間占用。
AUFS本質(zhì)上仍是堆棧式的聯(lián)合文件系統(tǒng)。在 Linux啟動(dòng)時(shí),首先加載 bootfs目錄,這個(gè)目錄里面包括 Bootloader和kernel,Bootloader用來加載啟動(dòng) kernel。當(dāng)kernel成功加載到內(nèi)存中后, bootfs就會(huì)釋放掉, kernel隨之開始加載rootfs。rootfs包含的是 Linux系統(tǒng)中標(biāo)準(zhǔn)的 /dev、/proc、/bin、/etc等文件, 是后續(xù)kernel啟動(dòng)的基礎(chǔ),因此此時(shí) kernel將 Rootfs加鎖,設(shè)為 readonly。在只讀權(quán)限下, kernel進(jìn)行一系列的檢查操作。當(dāng)kernel確認(rèn) rootfs包含的文件正確無誤后,將 readonly改為readwrite(可讀可寫),以后用戶就可以按照正確的權(quán)限對(duì)這些目錄進(jìn)行操作了。
當(dāng) Docker虛擬化出來一個(gè)容器之后,就相當(dāng)于有了內(nèi)存、CPU、硬盤,但沒有操作系統(tǒng)。參考 Linux的啟動(dòng)過程,通過 AUFS,將readonly權(quán)限的 rootfs添加到 bootfs之上,當(dāng)rootfs檢查完畢之后,再將用戶所要使用的文件內(nèi)容掛載到 rootfs之上,同樣是readonly權(quán)限。每次掛載一個(gè) FS文件層,每層之間只會(huì)掛載增量。這些文件層就是堆棧式文件系統(tǒng)中所保存的數(shù)據(jù),AUFS就是用來管理、使用這些文件層的文件系統(tǒng)。
目前,一些Docker開始嘗試使用OverlayFS,對(duì)比于AUFS,OverlayFS速度更快,實(shí)現(xiàn)更簡(jiǎn)單。OverlayFS也是一種多層單一化的文件系統(tǒng),它依賴并建立在其它的文件系統(tǒng)之上(例如ext4fs和xfs等等),并不直接參與磁盤空間結(jié)構(gòu)的劃分,僅僅將原來底層文件系統(tǒng)中不同的目錄進(jìn)行“合并”,然后向用戶呈現(xiàn),這也就是聯(lián)合掛載技術(shù)。Linux 內(nèi)核為Docker提供的OverlayFS驅(qū)動(dòng)有兩種:overlay和overlay2。而overlay2是相對(duì)于overlay的一種改進(jìn),在inode利用率方面比overlay更有效。
Docker 的架構(gòu)模型
目前來說,除了 Linux 系統(tǒng)可以直接運(yùn)行 Docker之外,其他系統(tǒng)都是基于虛擬機(jī)運(yùn)行的。
其中,Client是與 Docker 通信的一個(gè)組件,也就是客戶端。Docker daemon相當(dāng)于守護(hù)進(jìn)程,也就是 docker 的 Server。Image是鏡像,運(yùn)行起來的鏡像就是一個(gè)容器。Registry是具體存放鏡像的倉庫,鏡像倉庫分為公有倉庫(如DockerHub、DockerPool)和私有倉庫。有了鏡像倉庫,用戶可以用它來提供上傳/下載 鏡像的能力,大多數(shù)倉庫都提供了檢索和版本整理能力。
Docker 能夠保持容器內(nèi)部所有的配置和依賴關(guān)系始終不變,可以在任何擁有 Docker runtime 的環(huán)境快速部署而沒有遷移成本,實(shí)現(xiàn)了環(huán)境的標(biāo)準(zhǔn)化和版本化管理,具有較高的隔離性和安全性。
一句話小結(jié)
從操作系統(tǒng)看Docker,Docker 是操作系統(tǒng)能力的抽象重組,或者, 可以看成進(jìn)程組粒度的可復(fù)用內(nèi)核裁剪,其中以linux 內(nèi)核中的Cgroup來管理進(jìn)程組,以命名空間來實(shí)現(xiàn)資源隔離,以AUFS或者OverlayFS實(shí)現(xiàn)文件系統(tǒng)的掛載,從而,形成了一個(gè)通過網(wǎng)絡(luò)分發(fā)的容器環(huán)境。