理解一個(gè)技術(shù)史辙,首先要明確其要點(diǎn)土童,Docker技術(shù)就是基于容器的虛擬化技術(shù)同辣,相對(duì)于其它虛擬化技術(shù)荸实,它的特點(diǎn)是:
- 輕量級(jí):?jiǎn)螜C(jī)可以輕松支持上百container匀们,讓各種個(gè)位數(shù)虛擬化的方案相形見絀
- 快速就緒:一秒以內(nèi)啟動(dòng),即使是以資源快速就緒著稱的青云IAAS也無法相比
- 弱安全:docker能夠?qū)Χ喾NOS資源進(jìn)行隔離准给,但是它本質(zhì)上依托于內(nèi)核泄朴,因此所有的內(nèi)核漏洞都是docker的致命傷
上述三個(gè)特點(diǎn)都不是實(shí)現(xiàn)上的差異,而是設(shè)計(jì)方案的先天結(jié)果圆存,因此上述結(jié)論會(huì)在很長(zhǎng)一段時(shí)間內(nèi)有效叼旋。
理解上述這些特點(diǎn)非常重要。
很多剛接觸docker的人會(huì)把它和虛擬機(jī)做類比沦辙,然而這種類比和docker的最佳實(shí)踐場(chǎng)景有所不同夫植,一個(gè)docker容器不像是一臺(tái)虛擬機(jī),而更像是一個(gè)服務(wù)單元油讯,如果要類比详民,反倒更像進(jìn)程。
當(dāng)然陌兑,docker容器從技術(shù)層面上看確實(shí)也就是一個(gè)進(jìn)程沈跨,然而這不是關(guān)鍵,“輕量級(jí)”這個(gè)特點(diǎn)帶來的其實(shí)是服務(wù)器軟件工作方式的回歸兔综。不妨來看看服務(wù)器軟件的工作單元的抽象工作方式饿凛。
服務(wù)器軟件的抽象模型是有限狀態(tài)機(jī),不難想到软驰,在這類場(chǎng)景下涧窒,服務(wù)單元最終要做的,無非就是下面這些事情:
- 從網(wǎng)絡(luò)得到請(qǐng)求
- 結(jié)合內(nèi)部狀態(tài)進(jìn)行計(jì)
2.1 訪問獨(dú)有或共享的內(nèi)存
2.2 訪問獨(dú)有或共享的文件系統(tǒng)
2.3 訪問其它服務(wù)單元 - 通過同步或者異步的方式將計(jì)算結(jié)果由網(wǎng)絡(luò)反饋出去
最為復(fù)雜的部分當(dāng)屬第2步锭亏,不過如果考慮到服務(wù)器軟件需要進(jìn)行水平擴(kuò)展纠吴,業(yè)務(wù)也會(huì)逐漸分布化,我們會(huì)想到一句話慧瘤,“不要通過共享內(nèi)存進(jìn)行通信戴已,而是要通過通信共享內(nèi)存”固该,所以,2.1. 可以改為訪問獨(dú)有的內(nèi)存
實(shí)際上糖儡,由于有2.3的存在伐坏,2.2 也可以簡(jiǎn)化為訪問獨(dú)有的文件系統(tǒng),不過文件系統(tǒng)本身的IO性能很差休玩,一旦到了這個(gè)層面著淆,往往是分布式和水平擴(kuò)展的壓力不大的場(chǎng)景,所以可以保留拴疤。
除了功能性需求永部,我們還有管理和控制需求,包括:
- 可見性——服務(wù)單元應(yīng)該通過某種方式暴露自己的運(yùn)行以及資源使用情況
- 可操作性——服務(wù)單元應(yīng)該有某種渠道接受和響應(yīng)控制信號(hào)
這樣呐矾,我們可以大致勾勒出一個(gè)“服務(wù)單元”需要具備的能力列表:
- 獨(dú)享內(nèi)存訪問
- 獨(dú)享磁盤訪問
- 對(duì)網(wǎng)絡(luò)的訪問能力
- 實(shí)時(shí)暴露自身狀態(tài)和資源占用
- 實(shí)時(shí)反饋運(yùn)行情況
- 接受和響應(yīng)外部控制信號(hào)
說這么多顯得很羅嗦苔埋,因?yàn)檫@顯然就是一個(gè)普通的操作系統(tǒng)進(jìn)程要做的——結(jié)合cgroups和 proc 文件系統(tǒng)這樣的技術(shù),現(xiàn)代linux可以將進(jìn)程對(duì)內(nèi)存蜒犯、網(wǎng)絡(luò)组橄、文件系統(tǒng)的訪問隔離開,并能實(shí)時(shí)掌握進(jìn)程的狀態(tài)罚随;通過標(biāo)準(zhǔn)輸出和syslog玉工,進(jìn)程可以持續(xù)反饋運(yùn)行情況;通過信號(hào)量淘菩,進(jìn)程有機(jī)會(huì)對(duì)外部信號(hào)作出反應(yīng)......那為什么還要Docker遵班?
因?yàn)閭鹘y(tǒng)虛擬機(jī)的傳統(tǒng)進(jìn)程做的太多了
舉幾個(gè)例子:
- 應(yīng)用如何變成daemon,很長(zhǎng)一段時(shí)間都是被應(yīng)用系統(tǒng)開發(fā)人員忽略的問題潮改,這個(gè)問題雖然有解決辦法狭郑,但是各種語言和框架的辦法并不統(tǒng)一,如果交給運(yùn)維人員汇在,千差萬別的腳本會(huì)帶來很高的維護(hù)成本翰萨,而這本來應(yīng)該是進(jìn)程管理的事,和具體的技術(shù)棧無關(guān)糕殉。
- 我們常常要從安全角度考慮問題亩鬼,一些鐵律也是這么出現(xiàn)的,比如“不要使用root”阿蝶,然而對(duì)線上服務(wù)器而言辛孵,它常常是單一進(jìn)程,其它帳號(hào)根本就用不到赡磅,所以會(huì)出現(xiàn)這樣的怪事:把要做的事分為root和admin,然后運(yùn)維腳本是 sudo 開頭的
- 由于可以隨意登錄宝与,并進(jìn)行變更焚廊,profile的load過程很復(fù)雜并且容易引入不確定性,所以大家形成共識(shí)——不用環(huán)境變量來約束和客制化軟件的行為(雖然環(huán)境變量本來就是做這個(gè)的)。這樣的后果是许溅,c/c++寄月、java、python袒餐、ruby各種社區(qū)都形成了自己的配置文件習(xí)慣用法飞蛹,更進(jìn)一步,java社區(qū)曾經(jīng)有個(gè)趨勢(shì)灸眼,把配置文件本身都做的快和代碼沒區(qū)別了(復(fù)雜度相當(dāng)卧檐,也是在編譯時(shí)而不是運(yùn)行時(shí)確定實(shí)際參數(shù)值)
而在docker時(shí)代,這些都不是問題——
- container自己就是個(gè)daemon焰宣,應(yīng)用系統(tǒng)進(jìn)程放在里面不用再考慮daemonize霉囚。
- container是獨(dú)占的,因此你完全可以僅用root帳號(hào)做事匕积,并且不會(huì)破壞授權(quán)模型盈罐。
- 對(duì)于運(yùn)行中的進(jìn)程,可以很簡(jiǎn)單的使用docker exec命令獲取其當(dāng)前的環(huán)境變量闪唆,而且Dockerfile和docker-compose.yml都可以設(shè)定環(huán)境變量盅粪,這樣,各種千奇百怪的“配置文件”的需要就可以大幅度簡(jiǎn)化悄蕾。
不太嚴(yán)謹(jǐn)?shù)恼f票顾,Docker其實(shí)是重新定義和簡(jiǎn)化了linux,它是在針對(duì)服務(wù)器的場(chǎng)景進(jìn)行裁剪笼吟,把核心問題解決的更干凈純粹库物,剝離枝節(jié),使之更加貼近服務(wù)器環(huán)境的需要贷帮。
從這個(gè)角度出發(fā)再看看之前提到的三個(gè)特點(diǎn)戚揭,會(huì)覺得這是很實(shí)用的設(shè)計(jì):
- 輕量級(jí)
表面上看,輕量級(jí)容器更容易啟動(dòng)撵枢,但更重要的是民晒,這是對(duì) linux 本身設(shè)計(jì)的某種回歸,所以雖然簡(jiǎn)單卻并不簡(jiǎn)陋锄禽。如果我們實(shí)踐中感到不便潜必,也許正應(yīng)反思是否把運(yùn)維做復(fù)雜了。
- 快速就緒
不難理解沃但,由于本身僅僅是一個(gè)普通的進(jìn)程磁滚,我們可以很快的啟動(dòng)容器,然而問題不止于此,個(gè)人理解垂攘,這也是一個(gè)“回歸”——這是“以進(jìn)程為計(jì)算單元的協(xié)作方式”的回歸维雇,all in one 其實(shí)并不是很好,每個(gè)計(jì)算單元做的少而精才是 linux 的理念晒他。
當(dāng)然吱型,傳統(tǒng) linux 腳本組裝的少而精并不能應(yīng)對(duì)web/internet,docker容器的少而精實(shí)際上是在另一個(gè)角度進(jìn)行了回歸——讓每個(gè)容器都能專注一個(gè)方面陨仅,通過容器的快速建立/釋放來協(xié)調(diào)資源津滞,通過標(biāo)準(zhǔn)規(guī)范的容器間協(xié)作來搭建復(fù)雜的系統(tǒng)。
- 弱安全
這一點(diǎn)其實(shí)是一個(gè)推論——如果要發(fā)揮系統(tǒng)的計(jì)算能力灼伤,虛擬化應(yīng)該盡可能的薄触徐,然而過于單薄將對(duì)系統(tǒng)的穩(wěn)定性和安全性造成影響,docker做了一個(gè)trade-off——它將安全性交給了IAAS系統(tǒng)饺蔑,而專注做好穩(wěn)定性锌介。
docker自身顯然還是要依托于物理系統(tǒng)或者xen/kvm這樣的虛擬機(jī),而這些系統(tǒng)的安全邊界比較清晰猾警,所以docker沒有必要再背起這么重的負(fù)擔(dān)孔祸,唯一需要考慮的是容器間的資源獨(dú)占導(dǎo)致系統(tǒng)穩(wěn)定性降低,因此重點(diǎn)不在多租戶支持发皿,而在故障隔離崔慧,后者其實(shí)就是資源隔離。
理解了docker的特點(diǎn)穴墅,我們才能進(jìn)一步分析和討論docker到底能帶來什么惶室。