在我的這篇文章Docker and Microservices - Hands On里爆办,根據(jù)官方提供的教程难咕,我成功地基于Docker部署了兩個Service應(yīng)用在AWS上,這篇文章嘗試從一個大的視角來介紹Docker距辆。從哪些維度出發(fā)去認(rèn)識一個新的概念余佃,在這篇文章認(rèn)識新事物的維度我表達(dá)了自己的觀點(diǎn)。
What is Docker
Docker 官方給出的定義是:
Docker is the company driving the container movement and the only container platform provider to address every application across the hybrid cloud.
Today’s businesses are under pressure to digitally transform but are constrained by existing applications and infrastructure while rationalizing an increasingly diverse portfolio of clouds, datacenters and application architectures. Docker enables true independence between applications and infrastructure and developers and IT ops to unlock their potential and creates a model for better collaboration and innovation.
即Docker是一家容器平臺提供商跨算。這個定義一目了然:Docker是一家公司爆土,它提供的產(chǎn)品是“Container Platform”。那什么是Container Platform呢诸蚕,我們把它拆分成Container和Platform來解釋步势。
Container
我們先看官方的解釋:
A container is a runtime instance of an image—what the image becomes in memory when actually executed. It runs completely isolated from the host environment by default, only accessing host files and ports if configured to do so.
這個解釋也很簡單:Container是Image的運(yùn)行時實(shí)例”撤福“Instance”這個概念在軟件世界里很常見坏瘩,比如在OO里,我們說對象(Object)是類(Class)的實(shí)例(Instance)漠魏;在Web Service里倔矾,oData是RESTful API的實(shí)例。在解釋Image之前柱锹,我們暫且先把Image理解成一個Application哪自,其架構(gòu)圖如下:
從上圖我們可以知道:在一臺服務(wù)器主機(jī)上裝了操作系統(tǒng)(OS)來控制硬件并提供硬件訪問接口,然后在這個OS里裝了Docker之后禁熏,所有的Container就可以在Docker上面執(zhí)行了壤巷。所以Docker可以理解成Container的OS。這里我們可以把Container看作是JAVA世界里的一個JAR文件匹层,當(dāng)我們寫好自己的JAVA應(yīng)用后我們會將其打包成JAR文件隙笆,里頭包含了配置文件,引用的外部庫等一系列信息升筏,然后JVM就可以執(zhí)行這個JAR文件了撑柔。所以我們說:JAR是運(yùn)行在JVM上的。同樣的您访,Container是運(yùn)行在Docker上铅忿。
Image并不僅僅是一個Application,其官方解釋:
An image is a lightweight, stand-alone, executable package that includes everything needed to run a piece of software, including the code, a runtime, libraries, environment variables, and config files.
即Image是一個可執(zhí)行的文件包(Package),它里面包括了執(zhí)行一個軟件需要的所有東西:源代碼灵汪,運(yùn)行時檀训,庫文件柑潦,環(huán)境變量,配置文件峻凫。
那么誰來執(zhí)行Image這個Package呢渗鬼?答案是Docker Engine了。就像exe文件由Windows系統(tǒng)來執(zhí)行荧琼,dmg文件由Mac OS X執(zhí)行一樣譬胎。
我們可以看下面兩張圖:
從上述兩張圖中我們可以得到一個重要信息,即:Docker的架構(gòu)是“Client-Server”型架構(gòu)命锄。
What can Docker do
第一部分很枯燥堰乔,因?yàn)橐恢痹诮忉尭鞣N概念和定義,跟現(xiàn)實(shí)世界沒有任何的聯(lián)系脐恩。這部分嘗試從現(xiàn)實(shí)角度來介紹Docker镐侯。
The World W/O Docker
在Docker出現(xiàn)之前,一個網(wǎng)絡(luò)應(yīng)用程序是如何部署在生產(chǎn)環(huán)境并維護(hù)的呢驶冒?這是一個很大的話題苟翻,我的經(jīng)驗(yàn)和水平還不夠系統(tǒng)科學(xué)地去解釋這個問題,但是我想以一個在線購物網(wǎng)站為例來解釋其可能碰到的問題(真實(shí)情況下只怎,在線購物網(wǎng)站其功能和架構(gòu)遠(yuǎn)比我下面所描述地要復(fù)雜得多)袜瞬。
非常粗糙地講,一個在線購物網(wǎng)站應(yīng)該包括數(shù)據(jù)存儲身堡,核心應(yīng)用邏輯(如用戶注冊,下訂單拍鲤,支付)贴谎,交互頁面等模塊。
在最最最理想的情況下季稳,如果第一次上線的產(chǎn)品能夠?qū)崿F(xiàn)所有的功能擅这,后期不會再加入任何新的功能,并且其吞吐量無限大景鼠,支持任意數(shù)量的用戶的同時訪問和交互仲翎,數(shù)據(jù)存儲能力和檢索能力也能夠無限大。當(dāng)然這是絕對絕對不可能的n趵臁K菹恪!產(chǎn)品的迭代升級和更新浓恶,對系統(tǒng)吞吐量和數(shù)據(jù)讀寫速度的要求玫坛,網(wǎng)絡(luò)帶寬等是軟件工程中最核心的幾個問題之一。
當(dāng)前該在線購物網(wǎng)站的支付方式只支持信用卡支付包晰,隨著業(yè)務(wù)的發(fā)展湿镀,公司認(rèn)為應(yīng)該同時支持信用卡支付和支付寶支付炕吸。
對于這一需求,第一步當(dāng)然是在開發(fā)系統(tǒng)中新增支付寶支付的相關(guān)模塊并集成到原先的支付模塊中并完成測試勉痴。我們假設(shè)這個功能開發(fā)工程師已經(jīng)高質(zhì)量地完成而且QA也簽字通過赫模,那么如何上線到生產(chǎn)環(huán)境呢。
第一個方案:將新的項(xiàng)目包部署到生產(chǎn)系統(tǒng)服務(wù)器上蒸矛,并代替舊的項(xiàng)目包嘴瓤,重新啟動服務(wù)器。
升級過程雖然簡單且易操作莉钙,但在升級期間該網(wǎng)站將會全部癱瘓廓脆,而且此時如果有用戶正在下訂單或者支付訂單,那么他的這一操作將會被中斷而且不可恢復(fù)磁玉,甚至?xí)斐蓢?yán)重的數(shù)據(jù)不一致停忿,如用戶已通過信用卡完成付款,系統(tǒng)正在更新訂單狀態(tài)為“已支付”時服務(wù)器卻無法訪問了蚊伞。當(dāng)然席赂,可以通過類似于緩存?zhèn)浞莺腿罩疚募刃畔ⅲ谙到y(tǒng)升級完成之后再來更新相應(yīng)的訂單时迫,且不說這種事后處理機(jī)制能否保持絕對的正確性和零遺漏颅停,其本身所造成的信息滯后和巨大的維護(hù)升級成本,對于購物平臺來說是非常難以接受的掠拳;而且在系統(tǒng)越來越龐大的時候癞揉,這種滯后和其所帶來的成本也會越來越大。第二個方案: 將用戶登陸模塊溺欧,下訂單模塊部署在核心入口服務(wù)器上喊熟,支付模塊等功能分開部署在不同的服務(wù)器上,“支持支付寶支付”這一功能只會影響到支付模塊所在的服務(wù)器姐刁。
相比于第一個方案芥牌,用戶可以正常登陸網(wǎng)站并下訂單,只是不能完成支付聂使,此時系統(tǒng)的可訪問性得到了極大地提高壁拉。但是因?yàn)橹Ц赌K部署在獨(dú)立的服務(wù)器上,所以需要增加新的中間件組件將請求派發(fā)到相應(yīng)的服務(wù)器上柏靶,這會增加額外的網(wǎng)絡(luò)訪問時間弃理,而且引入了新的問題,即如何確保支付模塊功能與訂單狀態(tài)更新功能之間的一致性問題(消息隊(duì)列宿礁,事務(wù)型消息隊(duì)列等可以解決這一問題案铺,我的這篇文章消息中間件使用場景有具體的介紹。此時,對于正在進(jìn)行的支付消息控汉,可以在支付隊(duì)列中根據(jù)其狀態(tài)來很好地管理決定補(bǔ)救措施笔诵。對于新進(jìn)來的消息隊(duì)列,可以有相應(yīng)的策略來管理姑子,比如直接拒絕其進(jìn)入消息隊(duì)列)乎婿。
The World W/ Docker
我們前面介紹了軟件升級和新功能交付上線時所可能面臨的問題,而且我舉的例子只是冰山一角街佑,可見其復(fù)雜性和由此帶來的巨大的成本谢翎。對于如何解決這一問題有一個特定的軟件工程實(shí)踐叫DevOps,其是在傳統(tǒng)的開發(fā),測試沐旨,運(yùn)維的基礎(chǔ)上增加的新角色:
DevOps is a set of practices intended to reduce the time between committing a change to a system and the change being placed into normal production, while ensuring high quality.[9]
-- From WikiPedia
基于DevOps這個角度森逮,Docker可以認(rèn)為是:
Docker is a tool that is designed to benefit both developers and system administrators, making it a part of many DevOps (developers + operations) toolchains.For developers, it means that they can focus on writing code without worrying about the system that it will ultimately be running on. It also allows them to get a head start by using one of thousands of programs already designed to run in a Docker container as a part of their application. For operations staff, Docker gives flexibility and potentially reduces the number of systems needed because of its small footprint and lower overhead.
-- From here
Summary
使用Docker,軟件工程師只需將自己的項(xiàng)目代碼Docker化(Dockerize)并打包成Docker Image,然后交由Docker來管理項(xiàng)目的部署和新功能的交付磁携。而且褒侧,Docker提供了一系列的工具來幫助開發(fā)人員監(jiān)控和管理項(xiàng)目的狀態(tài)。此外谊迄,Docker還支持同AWS闷供, Azure等Cloud Provider的集成,即部署在這些平臺的應(yīng)用也可以使用Docker來托管统诺。Docker(Container Platform)是通過提供一系列工具完成項(xiàng)目部署并保證高質(zhì)量的持續(xù)交付的最佳實(shí)踐之一歪脏。
當(dāng)然,Container這一概念有很多優(yōu)勢粮呢,但是它絕對不是Silver Bullet婿失, 關(guān)于其具體的優(yōu)缺點(diǎn),這篇博客講得很詳細(xì).