【原文編者的話】快速創(chuàng)新的迫切要求,使得 Uber 開始在服務(wù)部署中應(yīng)用 Docker 。這篇文章講述了部署方式的轉(zhuǎn)變過程,強(qiáng)調(diào)在全面容器化之前,必須做充足的準(zhǔn)備。
無論你對(duì) Uber 的看法如何, Uber 無疑是創(chuàng)新的同義詞,因?yàn)樗陬嵏步煌ㄐ袠I(yè)的同時(shí)引領(lǐng)了共享經(jīng)濟(jì)。像Uber 這樣的最快創(chuàng)新者,就像 Microsoft, Apple 和 Amazon 公司一樣,都面臨一個(gè)問題:一旦你開始創(chuàng)新并且取得成功,你不得不一直保持這樣快的創(chuàng)新速度,這就導(dǎo)致了下面的后果:有時(shí)你看不到更遠(yuǎn)大的前景,有時(shí)會(huì)被途中的障礙絆倒。
今年初, Uber 發(fā)現(xiàn)自己就處于這樣的境地。那時(shí)候,軟件工程師 Casper S. Jensen 加入了 Uber 公司的計(jì)算機(jī)平臺(tái)團(tuán)隊(duì)。
在 Dockercon EU 的第一天, Jensen 說 Uber 應(yīng)用有非常易用的用戶界面,看起來就是一個(gè)簡(jiǎn)單的應(yīng)用;“實(shí)際上 Uber 是一個(gè)非常非常復(fù)雜的產(chǎn)品”,“應(yīng)用只是冰山之一角”,底層包含了無數(shù)的功能特性。要知道,目前 Uber 面對(duì)的是 69 個(gè)國家的不同市場(chǎng)和法律,每天安排百萬次行程,有4,000 員工使用 Uber 平臺(tái)。
以前的軟件開發(fā)模式
那時(shí)候, Jensen 和團(tuán)隊(duì)中的其他四個(gè)人剛剛加入 Uber 不久。工作簡(jiǎn)直是“一團(tuán)糟”,他們正在尋求一種解決方案。
這是去年冬天他們的開發(fā)流程:
編寫服務(wù) RFC(Request for Commments,請(qǐng)求評(píng)論)—— Uber 是一家極其依賴反饋的公司,在啟動(dòng)一項(xiàng)新服務(wù)時(shí),他們首先描述該服務(wù)的架構(gòu)和理念,發(fā)布到郵件列表中。
收集反饋——例如,“你們知道其他人也在做類似的事情嗎?”——集中精力,力爭(zhēng)在早期就找出錯(cuò)誤。
手工列出該服務(wù)的所有依賴。
開始開發(fā)服務(wù)。
等待基礎(chǔ)設(shè)施團(tuán)隊(duì)編寫服務(wù)的依賴。
等待 IT 確定服務(wù)的位置。
等待基礎(chǔ)設(shè)施團(tuán)隊(duì)提供服務(wù)。
部署到開發(fā)服務(wù)器,測(cè)試。
部署到生產(chǎn)環(huán)境的服務(wù)器。
監(jiān)控迭代。
他說,步驟 5-7 “是特別特別令人痛苦的部分,很容易耗費(fèi)數(shù)日乃至數(shù)周的時(shí)間。”原因何在?“到不是說這些步驟特別難,大部分環(huán)節(jié)我們都有相應(yīng)的腳本,”只包括大約十行的集成代碼。
“簡(jiǎn)單是簡(jiǎn)單,但是這些腳本的擴(kuò)展性差,因?yàn)楣纠镏挥猩贁?shù)人真正地知道如何擴(kuò)展且不會(huì)破壞已有的部署”, Jensen 說。再加上一些小錯(cuò)誤——例如,本來應(yīng)該是連接線,結(jié)果寫成了斜線——最后導(dǎo)致所有的服務(wù)都慢得要命。
2015 年2 月,在一封內(nèi)部郵件中,他們?cè)O(shè)置了下列目標(biāo):
Jensen 說他們想要做到:
允許服務(wù)的擁有者有專用的服務(wù)器切片,他們自行決定安裝什么,我們不干涉,但是不能影響其它的服務(wù)。
并且,他們的安裝過程也不用我們參與。
必須得有所改變了,還不能破壞現(xiàn)有的服務(wù)。
Uber 需要克服的自身問題
如果一家公司有如此快速增長(zhǎng)的基礎(chǔ)設(shè)施,自然會(huì)有一些限定,如 Jensen 所講,“無論如何,我們必須保證基礎(chǔ)設(shè)施快速增長(zhǎng),避免拖慢開發(fā)團(tuán)隊(duì)的高速開發(fā)流程”。
這不僅是因?yàn)?Uber 要求 7×24 的可用性以及支持無數(shù)的本地化特性,更重要的是,“沒有任何一個(gè)人能夠看到 Uber 的所有服務(wù),每個(gè)人只能看到自己從事的部分。”他列舉了幾個(gè)特性,像 UberPOOL、UberKITTENs、UberIceCream 和 UberEATS,每一個(gè)都在“增加新功能,好像世界末日到了一樣”。 Uber 的耀眼成功,是建立在全方位超快發(fā)展的基礎(chǔ)之上的,包括數(shù)據(jù)中心、服務(wù)器和基礎(chǔ)設(shè)施。需要找到保持增長(zhǎng)的解決方案。
“我們希望有非常方便的流程和基礎(chǔ)設(shè)施,這樣開發(fā)者就能非??斓卦黾有鹿δ?。其中最重要的一個(gè)部分是創(chuàng)建新服務(wù)的流程,” Jensen 說,“我們意識(shí)到這不就是 要用 Docker 嗎。”理由很簡(jiǎn)單,“很容易向別人解釋 Docker 的作用,人們?cè)缇土私膺^它,理解基本的概念”。每個(gè)人都有自己喜歡使用的容器,因此開發(fā)團(tuán)隊(duì)很容易接受 Docker 。
容器帶來的痛苦
他們心想,“我們都能寫代碼,這還不是小菜一疊?兩天就能干完。”實(shí)際上不是那么回事。他們 2月份作出決定,直到仲夏,才真正用上 Docker 。
Jensen 解釋說,用了 Docker ,“一切都有所改變,思路也必須隨之轉(zhuǎn)換。”
采用 Docker 的最大障礙是 Uber 內(nèi)部使用的集群管理系統(tǒng) uDeploy 。它要能在支持回滾的前提下做持續(xù)的滾動(dòng)升級(jí)。它包含很多報(bào)錯(cuò)的觸發(fā)器,像健康檢查或者發(fā)生故障時(shí)的圖形化顯示。它還支持有錯(cuò)就回滾的負(fù)載測(cè)試和集成測(cè)試。 uDeploy 包括:
每周 4,000 次升級(jí)
每周 3,000 次構(gòu)建
每周 300 次回滾
管理系統(tǒng)包含的 600 多個(gè)服務(wù)
做不到完全不使用 uDeploy ,所以 Uber 團(tuán)隊(duì)決定同時(shí)部署舊有的服務(wù)和 Docker 服務(wù)。
“我為此花了很多時(shí)間,檢查每一個(gè)功能,添加支持以便能夠把它封裝為 Docker 服務(wù),” Jensen 說,“ uDeploy 支持顯示標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤,我們必須在 Docker 中也實(shí)現(xiàn)這一點(diǎn)。”
他們?cè)陂_始使用 Docker 時(shí),沒有那么多規(guī)劃。后來 Jensen 意識(shí)到一開始給予開發(fā)者的自由度太大。“不應(yīng)該這樣,”他打了個(gè)響指,說:“你真的要考慮到基礎(chǔ)設(shè)施的方方面面”。
Jensen 說,如果你提前做好規(guī)劃,真正審視基礎(chǔ)設(shè)施以及容器在其中的一小部分作用,結(jié)果就會(huì)好很多。
Docker 正在驅(qū)動(dòng)一個(gè)全新的可擴(kuò)展的 Uber
現(xiàn)在 Uber 大約有 1/3 服務(wù)是 Docker 化的,希望不久實(shí)現(xiàn)百分之百的容器化。為什么?雖然轉(zhuǎn)換的過程很痛苦,但是最終的結(jié)果符合期望,去掉了持續(xù)部署中的三個(gè)巨大的痛點(diǎn)。有了 Docker ,他們無需再:
等待基礎(chǔ)設(shè)施團(tuán)隊(duì)編寫服務(wù)的依賴;
等待 IT 確定服務(wù)的位置;
等待基礎(chǔ)設(shè)施團(tuán)隊(duì)提供服務(wù)。
現(xiàn)在,他們不再手工編寫或者復(fù)制以前項(xiàng)目的依賴定義,而是使用包含標(biāo)準(zhǔn)服務(wù)的配置和構(gòu)建文件的工具,從而把服務(wù)提供時(shí)間從以前的幾小時(shí)、幾天縮短到現(xiàn)在的大約 10 分鐘。
不僅如此, Uber 認(rèn)識(shí)到, Docker 消除了團(tuán)隊(duì)之間的依賴,提供了更高的自由,因?yàn)椴辉俳壎ㄔ谔囟ǖ目蚣芎桶姹尽?蚣芎头?wù)的擁有者現(xiàn)在可以嘗試新技術(shù),管理自有的環(huán)境。