什么是 Docker?
關(guān)于 docker 是什么,有個(gè)著名的隱喻: 集裝箱 。但是它卻起了個(gè)“ 碼頭工人”(docker 的英文翻譯)的名字。這無(wú)疑給使用者很多暗示:“快來(lái)用吧!用了 docker,就像世界出現(xiàn)了集裝箱,這樣你的業(yè)務(wù)就可以隨意的、無(wú)拘無(wú)束的運(yùn)行在任何地方(Docker 公司的口號(hào): Build,Ship,and Run Any App,Anywhere ),于是碼頭工人就基本都可以下崗了。”但是人們往往忽略了一個(gè)問(wèn)題,隱喻的好處是方便人理解一個(gè)不容易理解的概念,但并不能解釋其概念本身。
互聯(lián)網(wǎng)技術(shù)行業(yè)的一大特點(diǎn)是,這里的絕大多數(shù)事物并不像現(xiàn)實(shí)生活那么具體,在這個(gè)行業(yè)中我們所接觸的絕大多數(shù)概念都是抽象的、不具體的。所以現(xiàn)實(shí)生活中很多可笑的事情在互聯(lián)網(wǎng)技術(shù)行業(yè)就不僅變的不可笑,反而可能很嚴(yán)肅。就比如,現(xiàn)實(shí)生活中你是幾乎不可能看見(jiàn)兩個(gè)神經(jīng)正常的成年人爭(zhēng)論到底是錘子更好還是螺絲刀更好這個(gè)問(wèn)題的。而在我們這個(gè)行業(yè),你可以很容易的被卷入到底是 java 好?還是 php 好?還是 js 好?或者類似的 語(yǔ)言之爭(zhēng) 中。當(dāng)然除了語(yǔ)言,其它的軟件工具之爭(zhēng)也比比皆是,比如經(jīng)典的還有 vim vs emacs。
由于不具體和抽象,就需要隱喻來(lái)給投資人解釋其價(jià)值,畢竟投資人大多數(shù)是外行嘛。至于 docker 到底是“集裝箱”還是“碼頭工人”并不重要,即使這兩個(gè)概念本質(zhì)上沖突了都不重要,很少有人會(huì)去真的思考 集裝箱的出現(xiàn)導(dǎo)致碼頭工人幾乎絕跡 。只要能讓大家明白 docker 是個(gè)重要的、有價(jià)值的、劃時(shí)代的工具,騙到投資人的錢就足夠了。也很少有投資人去考究集裝箱的發(fā)明人到底有沒(méi)有因此賺到錢?以及為什么沒(méi)賺到錢?只要概念能忽悠人就行了。當(dāng)然這個(gè)概念順便也忽悠了所有懶得思考的技術(shù)工程師。
吐了一大段槽之后,回到我們的正題,docker 到底是什么?既然大家喜歡集裝箱這個(gè)隱喻,那么我們也不妨先來(lái)看看集裝箱的本質(zhì)。大家應(yīng)該基本都理解集裝箱是怎么改變世界的吧?在集裝箱之前,貨物運(yùn)輸沒(méi)有統(tǒng)一的標(biāo)準(zhǔn)方式進(jìn)行搬運(yùn),于是鐵路、公路、海洋等各種運(yùn)輸之間,需要大量的人力作為貨物中轉(zhuǎn),效率極低,而且成本很高。集裝箱出現(xiàn)之后,世界上絕大多數(shù)的貨物運(yùn)輸都可以放到這個(gè)神奇的箱子里,然后在公路、鐵路、海洋等所有運(yùn)輸場(chǎng)景下,這個(gè)箱子都可以不用變化形態(tài)直接可以承運(yùn),而且中間的中轉(zhuǎn)工作,都可以通過(guò)大型機(jī)械搞定,效率大大提升。從此全球化開(kāi)始,商業(yè)的潛力被進(jìn)一步挖掘……牛逼之處我就不多說(shuō)了,可是這個(gè)箱子為什么這么神奇呢?答案其實(shí)也就在上面的描述中,無(wú)非就是兩個(gè)字: 標(biāo)準(zhǔn) 。
是的! 標(biāo)準(zhǔn)!標(biāo)準(zhǔn)!標(biāo)準(zhǔn)! 重要的事情說(shuō)三遍。
因?yàn)橐?guī)范了集裝箱的大小和尺寸的規(guī)格標(biāo)準(zhǔn),于是相應(yīng)的船舶、卡車、列車才能按照規(guī)格制造出來(lái)使聯(lián)運(yùn)成為可能,所有的運(yùn)輸中轉(zhuǎn)的自動(dòng)化工具才能被設(shè)計(jì)建造出來(lái)并且高效的使用,才可以極大的提高效率,提升自動(dòng)化水平,以至于碼頭工人才會(huì)失業(yè)。集裝箱本身是一個(gè)產(chǎn)品,而這個(gè)產(chǎn)品無(wú)非就是“標(biāo)準(zhǔn)化”的這個(gè)概念穿上了馬甲,馬甲可以有紅的、綠的、藍(lán)的、花的,但是大小規(guī)格必須都一樣。現(xiàn)實(shí)世界中的事實(shí)顯而易見(jiàn),就是這么簡(jiǎn)單。那么 docker 呢?
按照這個(gè)思路,docker 其實(shí)跟集裝箱一樣,或者說(shuō)它想跟集裝箱一樣,成為穿著馬甲的“標(biāo)準(zhǔn)化”。這樣開(kāi)發(fā)工程師就可以把它們開(kāi)發(fā)出來(lái)的 bug 們放到“集裝箱”里,然后運(yùn)維人員就可以使用標(biāo)準(zhǔn)化的操作工具去運(yùn)維這些可愛(ài)的 bug 們。于是實(shí)現(xiàn)了“海陸聯(lián)運(yùn)”,就好像運(yùn)維工程師根本不需要了解其運(yùn)維的軟件架構(gòu),而開(kāi)發(fā)工程師也并不需要了解其軟件運(yùn)行的操作系統(tǒng)一樣……
這就是 docker 的實(shí)質(zhì): 穿著馬甲的標(biāo)準(zhǔn)化 。docker 的發(fā)明人根據(jù)自己運(yùn)維 PaaS 平臺(tái)的經(jīng)驗(yàn),重新思考了自己的工作, 將PaaS 平臺(tái)的 devops 工作從各個(gè)角度標(biāo)準(zhǔn)化了一下,將系統(tǒng)底層實(shí)現(xiàn)的 cgroup、namespace、aufs|device mapper 等技術(shù)集成在一個(gè)使用鏡像方式發(fā)布的工具中,于是形成了 docker 。觀察 docker 形成的思考過(guò)程,其實(shí)就是作者針對(duì)他所運(yùn)維的場(chǎng)景如何做自動(dòng)化運(yùn)維的思考,大家可以參見(jiàn)其演講的 PPT 。這個(gè)演講的名字就跟自動(dòng)化運(yùn)維相關(guān): Docker: automation for the rest of us 。那么 docker 的實(shí)質(zhì)是什么?在我看來(lái)就是個(gè)針對(duì) PaaS 平臺(tái)的自動(dòng)化運(yùn)維工具而已。眾所周知(當(dāng)然如果你不知道,那么我來(lái)告訴你): 自動(dòng)化運(yùn)維的大前提就是標(biāo)準(zhǔn)化 。
如果你正好是一個(gè)運(yùn)維工程師,而且你正感覺(jué)你的運(yùn)維環(huán)境一團(tuán)糟,麻煩請(qǐng)你思考一下這是為什么?你是不是正在運(yùn)維著一個(gè)使用 php、java、C# 甚至 C/C++ 等用各種語(yǔ)言編寫的應(yīng)用都在運(yùn)行的環(huán)境里?這個(gè)環(huán)境是不是因?yàn)槟撤N歷史原因,使你的操作系統(tǒng)運(yùn)行著各個(gè)版本的內(nèi)核,甚至還有 windows?即使是同樣語(yǔ)言編寫的業(yè)務(wù)也運(yùn)行著不同版本的庫(kù)?你的整個(gè)系統(tǒng)環(huán)境是不是甚至找不出來(lái)兩臺(tái)硬件、操作系統(tǒng)、庫(kù)版本以及語(yǔ)言版本完全一樣的環(huán)境?于是你每次遇到問(wèn)題都要去排查到底那個(gè)坑到底在那里?從網(wǎng)絡(luò)、內(nèi)核到應(yīng)用邏輯。你每次遇到產(chǎn)品升級(jí)都要在各種環(huán)境上做穩(wěn)定性測(cè)試,發(fā)現(xiàn)不同的環(huán)境代碼 crash 的原因都不盡相同。你就像一個(gè)老中醫(yī)一樣去經(jīng)歷各種疑難雜癥,如果遇到問(wèn)題能找到原因甚至都是幸運(yùn)的,絕大多數(shù)情況是解決了但不知道原因,和沒(méi)解決自動(dòng)好了也不知道原因。于是你們?cè)谝粋€(gè)特定的公司的環(huán)境中積累著“經(jīng)驗(yàn)”,成為你們組新手眼中的大神,憑借歷經(jīng)故障養(yǎng)成的條件反射在快速解決不斷發(fā)生的重復(fù)問(wèn)題,并故弄玄虛的說(shuō):這就是工作經(jīng)驗(yàn)。 因?yàn)榻?jīng)驗(yàn)經(jīng)常是搞不清楚原因時(shí)的***一個(gè)遮羞布 。當(dāng)別人抱怨你們部門效率低的時(shí)候,你一般的反應(yīng)是:”you can you up,no can no BB!“
我花了這么多口舌吐槽運(yùn)維,無(wú)非就是想提醒大家” 運(yùn)維標(biāo)準(zhǔn)化的重要性 “這一顯而不易見(jiàn)的事實(shí)。標(biāo)準(zhǔn)化了,才能提高效率。標(biāo)準(zhǔn)化了,才能基于標(biāo)準(zhǔn)建設(shè)屬于你們系統(tǒng)的自動(dòng)化運(yùn)維。那么我們?cè)賮?lái)看看 docker 是怎么做的?
首先, 標(biāo)準(zhǔn)化就要有標(biāo)準(zhǔn)化的文檔規(guī)范 ,要定義系統(tǒng)軟件版本等一系列內(nèi)容。規(guī)范好了之后,大家開(kāi)始實(shí)施。但是在長(zhǎng)期運(yùn)維的過(guò)程中,很可能出現(xiàn)隨著系統(tǒng)的發(fā)展,文檔內(nèi)容已經(jīng)過(guò)時(shí)了,工程師又來(lái)不及更新文檔的問(wèn)題。怎么解決?docker 給出的答案是: 用 dockerfile 。dockerfile 就是你的文檔,并且用來(lái)產(chǎn)生鏡像。要改變 docker 鏡像中的環(huán)境,先改 dockerfile,用它產(chǎn)生鏡像就行了,保證文檔和環(huán)境一致。那么現(xiàn)實(shí)是,有多少在使用 docker 的人是這樣用的?你們是不是嫌這樣麻煩,于是干脆直接在線 docker commit 產(chǎn)生鏡像,讓文檔跟現(xiàn)場(chǎng)環(huán)境又不符了?或者我還是太理想,因?yàn)槟銈儔焊B文檔都沒(méi)有?
其次, 標(biāo)準(zhǔn)化要有對(duì)應(yīng)用統(tǒng)一操作的方法 。在現(xiàn)實(shí)中,即使你用的是 php 開(kāi)發(fā)的應(yīng)用,啟動(dòng)的方式都可能不盡相同。有用apache 的,有用 nginx 的,還有用某種不知名 web 容器的,甚至是自己開(kāi)發(fā) web 容器的。如果操作范圍擴(kuò)大到包含 java 等其它語(yǔ)言,或數(shù)據(jù)庫(kù)等其它服務(wù),那么操作方式更是千奇百怪。雖然 UNIX 操作系統(tǒng)早就對(duì)此作了統(tǒng)一的規(guī)范,就是大家常見(jiàn)的把啟動(dòng)腳本放到 /etc/rc.d 中,SYSV 標(biāo)準(zhǔn)中甚至規(guī)定了啟動(dòng)腳本該怎么寫,應(yīng)該有哪些方法。但是絕大多數(shù)人不知道,或者知道了也不這么做,他們習(xí)慣用 ./start 作為自己業(yè)務(wù)啟動(dòng)的唯一標(biāo)準(zhǔn)。甚至 ./ 是哪個(gè)目錄可能都記不住。于是 docker 又給出了解決方案:我壓根不管你怎么啟動(dòng),你自己愛(ài)咋來(lái)咋來(lái),我們用 docker start 或 run 作為統(tǒng)一標(biāo)準(zhǔn)。于是 docker start 可以啟動(dòng)一個(gè) apache、nginx、jvm、mysql 等等。有人病垢 docker 的設(shè)計(jì),質(zhì)疑它為什么設(shè)計(jì)上一個(gè)容器內(nèi)只給啟動(dòng)一個(gè)進(jìn)程?這就是原因:人家壓根不是為了給你當(dāng)虛擬機(jī)用的,人家是為了給啟動(dòng)生產(chǎn)環(huán)境的進(jìn)程做標(biāo)準(zhǔn)化的!
第三, 為了維護(hù)生產(chǎn)環(huán)境的一致性和配置變更的冪等,docker 創(chuàng)造性的使用了類似 git 管理代碼的方式對(duì)環(huán)境鏡像進(jìn)行管理 。于是:
你想做庫(kù)版本升級(jí)嗎?更新個(gè)鏡像吧!
你想做 php、java 的版本升級(jí)嗎?更新個(gè)鏡像吧。
好方便!太爽了!
等等……神馬?你想改變 apache 配置文件中的一個(gè)字段?做個(gè)新鏡像升級(jí)吧!你的 php 代碼寫錯(cuò)了一行要改個(gè) bug?做個(gè)新鏡像升級(jí)吧……
在一群人吐血三升之后,于是有人出了個(gè)主意。唉,其實(shí)后兩種需求沒(méi)必要這么麻煩,有一種軟件叫做 puppet、chef、salt、ansible、rsync ……
于是我們要在 docker 中啟動(dòng)一個(gè) puppet。什么?你要用 ansible?好吧,我們來(lái)看看怎么在 docker 中啟動(dòng)一個(gè) sshd?我有個(gè)計(jì)劃任務(wù)要跑,起個(gè) crontab 可以么?
你的 docker 是不是就這么變成了“虛擬機(jī)”的?
不過(guò)請(qǐng)注意:我并不是說(shuō) docker 不好,只是你是否真的評(píng)估了它標(biāo)準(zhǔn)化的方式是不是適合你的業(yè)務(wù)場(chǎng)景?錘子是用來(lái)砸釘子的,但是你非要用它來(lái)砸手指,我也沒(méi)什么辦法。
作為一個(gè)工程師,而且是受過(guò)專業(yè)訓(xùn)練的工程師,總是想設(shè)計(jì)出一套工具滿足所有場(chǎng)景需求。因?yàn)楣こ處熕艿乃季S訓(xùn)練是:你越是解決了更普遍的問(wèn)題,你所創(chuàng)造的價(jià)值就越大。但是請(qǐng)搞清楚,這個(gè)任務(wù)一般是由標(biāo)準(zhǔn)委員會(huì)來(lái)完成的,每個(gè)工程行業(yè)都會(huì)有這么個(gè)組織來(lái)做這件事情。當(dāng)然,不排除商業(yè)公司的產(chǎn)品可以深刻影響標(biāo)準(zhǔn)制定的情況。那么我們這些工程師***的價(jià)值是什么?擺正自己的位置,看清自己的問(wèn)題,幫小組所在的企業(yè)進(jìn)一步提高效率,提高競(jìng)爭(zhēng)力。每個(gè)企業(yè)都有其歷史和當(dāng)前特點(diǎn),就運(yùn)維工作來(lái)講,根據(jù)企業(yè)的實(shí)際情況找到其標(biāo)準(zhǔn)化的最經(jīng)濟(jì)有利方式才是我們這些受聘用的職業(yè)工程師的核心價(jià)值。軟件選型要要因地制宜,而不是跟風(fēng)炒作。當(dāng)然,如果你的核心價(jià)值是想要站在“技術(shù)前沿”,打算一直***技術(shù)潮流,做一個(gè)出沒(méi)于各大技術(shù)交流會(huì)的新技術(shù)吹牛逼者,并以此抬高自己身價(jià)的話,那我的話自然是對(duì)你不適用的。(說(shuō)這話可能會(huì)得罪很多人,我要解釋一下:對(duì)于那些真誠(chéng)的想要分享自己技術(shù),希望為社區(qū)發(fā)展做貢獻(xiàn)的人,我是懷著深深的敬意的!謝謝你們!)對(duì)待新技術(shù),大多數(shù)工程師的狀態(tài)是:測(cè)試是為了上線的,測(cè)試出的問(wèn)題都是要解決的而不是用來(lái)評(píng)估的,不上線就沒(méi)有工作成果。我認(rèn)為工程師對(duì)待新技術(shù)應(yīng)有得態(tài)度是:激進(jìn)的用新技術(shù)新方法來(lái)做線下測(cè)試,認(rèn)真的總結(jié)評(píng)估測(cè)試流程和結(jié)果和現(xiàn)有環(huán)境的異同,保守謹(jǐn)慎的評(píng)估決策新技術(shù)是否在業(yè)務(wù)上大規(guī)模使用。
docker 是銀彈么?真的能像集裝箱那樣改變世界么?我的看法當(dāng)然不是。即使集裝箱,也不能解決一些特殊的運(yùn)輸問(wèn)題,比如大型飛機(jī)零部件的運(yùn)輸,或者小件零散商品的運(yùn)輸。如果說(shuō)云計(jì)算行業(yè)真的要出現(xiàn)集裝箱的話,那么首先這個(gè)行業(yè)要被幾大云計(jì)算廠商瓜分完畢,市場(chǎng)成熟之后才有可能。為什么?因?yàn)樽屢粋€(gè)應(yīng)用可以在任何地方跑的需求,主要應(yīng)該來(lái)自云的用戶,他們可能為了穩(wěn)定性考慮既租用了阿某云,又租用了騰訊云(純廣告,自己所在的公司,所以請(qǐng)勿吐槽),還可能為了海外市場(chǎng)還用了某馬遜云。這時(shí)用戶會(huì)有需求說(shuō),我想要這些云的環(huán)境標(biāo)準(zhǔn)一致,以便我的應(yīng)用可以在哪朵云上都能跑(Build,Ship,and Run Any App)。而現(xiàn)在,云計(jì)算市場(chǎng)剛剛起步,群雄逐鹿,正是差異化發(fā)展?fàn)帄Z用戶的時(shí)候。出了云計(jì)算廠商外,其它公司的 IT 環(huán)境都不一樣,標(biāo)準(zhǔn)化要求也就不可能一樣。那么你覺(jué)得 docker 這個(gè)標(biāo)準(zhǔn)可能適合所有人么?
如果你用過(guò)了 docker,并且還覺(jué)得它非常合適你的環(huán)境,那么我希望你能回答這幾個(gè)問(wèn)題:
你的 docker 是用 dockerfile 產(chǎn)生的鏡像還是直接 docker commit?
你的 docker 里面跑了多少個(gè)進(jìn)程?
你的 docker 是當(dāng)虛擬機(jī)用的么?
那么你用的是 docker 么?
***,送大家一個(gè)段子,希望能博你一笑。
工程師:“嘿!有人發(fā)明了一個(gè)叫做集裝箱的東西,這東西一定可以使運(yùn)輸成本大大下降!甚至改變世界!”
用戶:“好興奮!這東西可以運(yùn)輸我的波音787客機(jī)么?“
工程師:“額。。不能整個(gè)運(yùn),需要拆開(kāi)再運(yùn),因?yàn)槲覀円霞b箱的標(biāo)準(zhǔn)……”
用戶:“那這東西可以運(yùn)輸我的空客380嘛?”
工程師:“額。。我們討論的是同一件事情。”
用戶:“不行是嘛?那不能改造一下集裝箱讓它可以運(yùn)嘛?”
工程師:“額。。。這不僅僅是我們的問(wèn)題,要到達(dá)運(yùn)輸目的地還要經(jīng)過(guò)鐵路,公路,他們可能也無(wú)法……”
用戶:“真的不能改造集裝箱么?可這東西是以后的發(fā)展方向啊!未來(lái)的世界都是應(yīng)該是集裝箱運(yùn)輸?shù)?”
工程師:“額……”
老板:“嗯!這東西說(shuō)不定真的是未來(lái)的發(fā)展方向!我們一定要實(shí)現(xiàn)用集裝箱運(yùn)輸這些飛機(jī)!工程師們,你們趕緊去攻克這些技術(shù)難題,早日可以實(shí)現(xiàn)我們用戶的特殊需求!讓集裝箱可以達(dá)到我們的業(yè)務(wù)要求!快去吧!加油啊!”
工程師:“額……”


























