近年來,云原生 (cloud native)可謂是 it 界最火的概念之一,眾多互聯(lián)網(wǎng)巨頭都已經(jīng)開始積極擁抱云原生。而說到云原生,我們就不得不了解本文的主角 —— 容器(container)。容器技術(shù)可謂是撐起了云原生生態(tài)的半壁江山。容器作為一種先進的虛擬化技術(shù),已然成為了云原生時代軟件開發(fā)和運維的標(biāo)準(zhǔn)基礎(chǔ)設(shè)施,在了解它之前,我們不妨從虛擬化技術(shù)說起。
何謂虛擬化技術(shù)
1961 年—— ibm709 機實現(xiàn)了分時系統(tǒng)
計算機歷史上首個虛擬化技術(shù)實現(xiàn)于 1961 年,ibm709 計算機首次將 cpu 占用切分為多個極短 (1/100sec) 時間片,每一個時間片都用來執(zhí)行著不同的任務(wù)。通過對這些時間片的輪詢,這樣就可以將一個 cpu 虛擬化或者偽裝成為多個 cpu,并且讓每一顆虛擬 cpu 看起來都是在同時運行的。這就是虛擬機的雛形。
容器的功能其實和虛擬機類似,無論容器還是虛擬機,其實都是在計算機不同的層面進行虛擬化,即使用邏輯來表示資源,從而擺脫物理限制的約束,提高物理資源的利用率。虛擬化技術(shù)是一個抽象又內(nèi)涵豐富的概念,在不同的領(lǐng)域或?qū)用嬗兄煌暮x。
這里我們首先來粗略地講講計算機的層級結(jié)構(gòu)。計算機系統(tǒng)對于大部分軟件開發(fā)者來說可以分為以下層級結(jié)構(gòu):
應(yīng)用程序?qū)雍瘮?shù)庫層操作系統(tǒng)層硬件層
各層級自底向上,每一層都向上提供了接口,同時每一層也只需要知道下一層的接口即可調(diào)用底層功能來實現(xiàn)上層操作(不需要知道底層的具體運作機制)。
但由于早期計算機廠商生產(chǎn)出來的硬件遵循各自的標(biāo)準(zhǔn)和規(guī)范,使得操作系統(tǒng)在不同計算機硬件之間的兼容性很差;同理,不同的軟件在不同的操作系統(tǒng)下的兼容性也很差。于是,就有開發(fā)者人為地在層與層之間創(chuàng)造了抽象層:
應(yīng)用層函數(shù)庫層 api抽象層操作系統(tǒng)層 硬件抽象層硬件層
就我們探討的層面來說,所謂虛擬化就是在上下兩層之間,人為地創(chuàng)造出一個新的抽象層,使得上層軟件可以直接運行在新的虛擬環(huán)境上。簡單來說,虛擬化就是通過模訪下層原有的功能模塊創(chuàng)造接口,來“欺騙”上層,從而達到跨平臺開發(fā)的目的。
綜合上述理念,我們就可以重新認(rèn)識如今幾大廣為人知的虛擬化技術(shù):
虛擬機:存在于硬件層和操作系統(tǒng)層間的虛擬化技術(shù)。
虛擬機通過“偽造”一個硬件抽象接口,將一個操作系統(tǒng)以及操作系統(tǒng)層以上的層嫁接到硬件上,實現(xiàn)和真實物理機幾乎一樣的功能。比如我們在一臺 windows 系統(tǒng)的電腦上使用 android 虛擬機,就能夠用這臺電腦打開 android 系統(tǒng)上的應(yīng)用。
容器:存在于操作系統(tǒng)層和函數(shù)庫層之間的虛擬化技術(shù)。
容器通過“偽造”操作系統(tǒng)的接口,將函數(shù)庫層以上的功能置于操作系統(tǒng)上。以 docker 為例,其就是一個基于 linux 操作系統(tǒng)的 namespace 和 cgroup 功能實現(xiàn)的隔離容器,可以模擬操作系統(tǒng)的功能。簡單來說,如果虛擬機是把整個操作系統(tǒng)封裝隔離,從而實現(xiàn)跨平臺應(yīng)用的話,那么容器則是把一個個應(yīng)用單獨封裝隔離,從而實現(xiàn)跨平臺應(yīng)用。所以容器體積比虛擬機小很多,理論上占用資源更少。
jvm:存在于函數(shù)庫層和應(yīng)用程序之間的虛擬化技術(shù)。
java 虛擬機同樣具有跨平臺特性,所謂跨平臺特性實際上也就是虛擬化的功勞。我們知道 java 語言是調(diào)用操作系統(tǒng)函數(shù)庫的,jvm 就是在應(yīng)用層與函數(shù)庫層之間建立一個抽象層,對下通過不同的版本適應(yīng)不同的操作系統(tǒng)函數(shù)庫,對上提供統(tǒng)一的運行環(huán)境交給程序和開發(fā)者,使開發(fā)者能夠調(diào)用不同操作系統(tǒng)的函數(shù)庫。
在大致理解了虛擬化技術(shù)之后,接下來我們就可以來了解容器的誕生歷史。雖然容器概念是在 docker 出現(xiàn)以后才開始在全球范圍內(nèi)火起來的,但在 docker 之前,就已經(jīng)有無數(shù)先驅(qū)在探索這一極具前瞻性的虛擬化技術(shù)。
容器的前身 “jail”
1979 年—— 貝爾實驗室發(fā)明 chroot
容器主要的特性之一就是進程隔離。早在 1979 年,貝爾實驗室在 unix v7 的開發(fā)過程中,發(fā)現(xiàn)當(dāng)一個系統(tǒng)軟件編譯和安裝完成后,整個測試環(huán)境的變量就會發(fā)生改變,如果要進行下一次構(gòu)建、安裝和測試,就必須重新搭建和配置測試環(huán)境。要知道在那個年代,一塊 64k 的內(nèi)存條就要賣 419 美元,“快速銷毀和重建基礎(chǔ)設(shè)施”的成本實在是太高了。
開發(fā)者們開始思考,能否在現(xiàn)有的操作系統(tǒng)環(huán)境下,隔離出一個用來重構(gòu)和測試軟件的獨立環(huán)境?于是,一個叫做 chroot(change root)的系統(tǒng)調(diào)用功能就此誕生。
chroot 可以重定向進程及其子進程的 root 目錄到文件系統(tǒng)上的新位置,也就是說使用它可以分離每個進程的文件訪問權(quán)限,使得該進程無法接觸到外面的文件,因此這個被隔離出來的新環(huán)境也得到了一個非常形象的命名,叫做 chroot jail (監(jiān)獄)。之后只要把需要的系統(tǒng)文件一并拷貝到 chroot jail 中,就能夠?qū)崿F(xiàn)軟件重構(gòu)和測試。這項進步開啟了進程隔離的大門,為 unix 提供了一種簡單的系統(tǒng)隔離功能,尤其是 jail 的思路為容器技術(shù)的發(fā)展奠定了基礎(chǔ)。但是此時 chroot 的隔離功能僅限于文件系統(tǒng),進程和網(wǎng)絡(luò)空間并沒有得到相應(yīng)的處理。
進入21世紀(jì),此時的虛擬機(vm)技術(shù)已經(jīng)相對成熟,人們可以通過虛擬機技術(shù)實現(xiàn)跨操作系統(tǒng)的開發(fā)。但由于 vm 需要對整個操作系統(tǒng)進行封裝隔離,占用資源很大,在生產(chǎn)環(huán)境中顯得太過于笨重。于是人們開始追求一種更加輕便的虛擬化技術(shù),眾多基于 chroot 擴展實現(xiàn)的進程隔離技術(shù)陸續(xù)誕生。
2000 年——freebsd推出 freebsd jail
在 chroot 誕生 21 年后,freebsd 4.0 版本推出了一套微型主機環(huán)境共享系統(tǒng) freebsd jail,將 chroot 已有的機制進行了擴展。在 freebsd jail 中,程序除了有自己的文件系統(tǒng)以外,還有獨立的進程和網(wǎng)絡(luò)空間,jail 中的進程既不能訪問也不能看到 jail 之外的文件、進程和網(wǎng)絡(luò)資源。
2001 年——linux vserver誕生
2001年,linux 內(nèi)核新增 linux vserver(虛擬服務(wù)器),為 linux 系統(tǒng)提供虛擬化功能。linux vserver 采取的也是一種 jail 機制,它能夠劃分計算機系統(tǒng)上的文件系統(tǒng)、網(wǎng)絡(luò)地址和內(nèi)存,并允許一次運行多個虛擬單元。
2004 年—— sun 發(fā)布 solaris containers
該技術(shù)同樣由 chroot 進一步發(fā)展而來。2004 年 2 月,sun 發(fā)布類 unix 系統(tǒng) solaris 的 10 beta 版,新增操作系統(tǒng)虛擬化功能 container,并在之后的 solaris 10 正式版中完善。solaris containers 支持 x86 和 sparc 系統(tǒng),sun 創(chuàng)造了一個 zone 功能與 container 配合使用,前者是一個單一操作系統(tǒng)中完全隔離的虛擬服務(wù)器,由系統(tǒng)資源控制和 zones 提供的邊界分離實現(xiàn)進程隔離。
2005 年——openvz誕生
類似于 solaris containers,它通過對 linux 內(nèi)核進行補丁來提供虛擬化、隔離、資源管理和狀態(tài)檢查 checkpointing。每個 openvz 容器都有一套隔離的文件系統(tǒng)、用戶及用戶組、進程樹、網(wǎng)絡(luò)、設(shè)備和 ipc 對象。
這個時期的進程隔離技術(shù)大多以 jail 模式為核心,基本實現(xiàn)了進程相關(guān)資源的隔離操作,但由于此時的生產(chǎn)開發(fā)仍未有相應(yīng)的使用場景,這一技術(shù)始終被局限在了小眾而有限的世界里。
就在此時,一種名為“云”的新技術(shù)正悄然萌發(fā)……
“云”的誕生
2003 年至 2006 年間,google 公司陸續(xù)發(fā)布了 3 篇產(chǎn)品設(shè)計論文,從計算方式到存儲方式,開創(chuàng)性地提出了分布式計算架構(gòu),奠定了大數(shù)據(jù)計算技術(shù)的基礎(chǔ)。在此基礎(chǔ)上,google 顛覆性地提出“google 101”計劃,并正式創(chuàng)造“云”的概念。一時間,“云計算”、“云存儲”等全新詞匯轟動全球。隨后,亞馬遜、ibm 等行業(yè)巨頭也陸續(xù)宣布各自的“云”計劃,宣告“云”技術(shù)時代的來臨。
也是從這時期開始,進程隔離技術(shù)進入了一個更高級的階段。在 google 提出的云計算框架下,被隔離的進程不僅僅是一個與外界隔絕但本身卻巍然不動的 jail,它們更需要像一個個輕便的容器,除了能夠與外界隔離之外,還要能夠被控制與調(diào)配,從而實現(xiàn)分布式應(yīng)用場景下的跨平臺、高可用、可擴展等特性。
2006 年—— google 推出 process containers,后更名為cgroups
process container 是 google 工程師眼中“容器”技術(shù)的雛形,用來對一組進程進行限制、記賬、隔離資源(cpu、內(nèi)存、磁盤 i/o、網(wǎng)絡(luò)