容器技術(shù)在Netflix基于AWS EC2虛擬機(jī)打造的全球云平臺(tái)中大放異彩,并產(chǎn)生了深遠(yuǎn)影響。之前我們?cè)窒磉^(guò)不少有關(guān)Netflix使用容器的故事(視頻、幻燈片),本文將深入討論Netflix對(duì)容器的使用情況,以及Netflix為基于容器的應(yīng)用程序打造的底層基礎(chǔ)架構(gòu)Titus。Titus為Netflix提供了可伸縮的集群和資源管理能力,增強(qiáng)了容器執(zhí)行與Amazon EC2之間的集成度,提供了Netflix所需的通用基礎(chǔ)架構(gòu)功能。
本月,Netflix的容器技術(shù)迎來(lái)兩個(gè)重大里程碑。首先,我們的平臺(tái)規(guī)模更上一層樓,在一周內(nèi)順利擴(kuò)展至上百萬(wàn)個(gè)容器。其次,Titus現(xiàn)已可為提供流播服務(wù)客戶體驗(yàn)的功能提供支持。我們將深入介紹Docker容器的具體使用方法,以及使得該容器運(yùn)行時(shí)顯得如此獨(dú)一無(wú)二的原因。
容器的發(fā)展歷史
基于Amazon虛擬機(jī)(EC2)的基礎(chǔ)架構(gòu)早已成為Netflix實(shí)現(xiàn)各項(xiàng)創(chuàng)新的重要推動(dòng)力。除了虛擬機(jī),我們還大量使用基于容器的工作負(fù)載,這類工作負(fù)載為我們提供了獨(dú)特的價(jià)值。容器技術(shù)帶給我們不菲的收益,對(duì)此我們倍感激動(dòng),同時(shí)容器的用量也經(jīng)歷了爆發(fā)式增長(zhǎng),甚至我們自己的開(kāi)發(fā)人員都對(duì)這些因素感到吃驚。
雖然EC2支持對(duì)服務(wù)進(jìn)行高級(jí)調(diào)度,但我們的批處理用戶無(wú)法從中獲益。Netflix有很多用戶需要同時(shí)運(yùn)行多個(gè)作業(yè),甚至要通過(guò)基于事件的觸發(fā)器分析數(shù)據(jù),執(zhí)行運(yùn)算,并將結(jié)果發(fā)送給其他Netflix服務(wù)、用戶,以及報(bào)告。我們需要每天多次運(yùn)行諸如機(jī)器學(xué)習(xí)模型訓(xùn)練、媒體編碼、持續(xù)集成測(cè)試、大數(shù)據(jù)Notebook,以及CDN部署分析作業(yè)等工作負(fù)載。因此我們希望為基于容器的應(yīng)用程序提供不依賴具體工作負(fù)載類型的通用資源調(diào)度器,通過(guò)更高級(jí)的工作流調(diào)度器對(duì)所有內(nèi)容進(jìn)行集中控制。Titus可同時(shí)承擔(dān)通用部署單位(Docker鏡像)和通用批處理作業(yè)調(diào)度系統(tǒng)的任務(wù),它的順利上線幫助Netflix通過(guò)擴(kuò)展為批處理用例提供了更好的支持。
借助Titus,我們的批處理用戶只需要指定自己對(duì)資源的需求,即可快速獲得成熟的基礎(chǔ)架構(gòu)環(huán)境。用戶無(wú)須選擇并維護(hù)在規(guī)模方面無(wú)法與自己的工作負(fù)載完美匹配的AWS EC2實(shí)例,而是可以安心地通過(guò)Titus將更大規(guī)模的實(shí)例“打包”在一起,高效運(yùn)用于不同類型的工作負(fù)載。批處理用戶可在本地編寫代碼,隨后立即通過(guò)調(diào)度通過(guò)Titus進(jìn)行大規(guī)模執(zhí)行。在容器的幫助下,Titus可以運(yùn)行任何批處理應(yīng)用程序,并且可以明確指定自己需要的應(yīng)用程序代碼和依賴項(xiàng)。例如,在機(jī)器學(xué)習(xí)訓(xùn)練過(guò)程中,用戶將能配合運(yùn)行Python、R、Java和Bash腳本應(yīng)用程序。
除了批處理,我們發(fā)現(xiàn)其他工作負(fù)載也能從更簡(jiǎn)單的資源管理和本地開(kāi)發(fā)體驗(yàn)等方面獲益。通過(guò)與Edge、UI和設(shè)備工程團(tuán)隊(duì)合作,我們還將這些收益擴(kuò)展到了服務(wù)的使用者群體。目前,我們正在通過(guò)重建將面向具體設(shè)備的服務(wù)器端邏輯部署到API層,這樣即可更充分地利用面向單內(nèi)核優(yōu)化的NodeJS服務(wù)器。我們的UI和設(shè)備工程團(tuán)隊(duì)還希望獲得更好的開(kāi)發(fā)體驗(yàn),例如與生產(chǎn)環(huán)境完全一致,更簡(jiǎn)單的本地測(cè)試環(huán)境。
除了一致的環(huán)境,開(kāi)發(fā)者還可以在容器技術(shù)的幫助下,通過(guò)Docker層鏡像和面對(duì)容器部署進(jìn)行優(yōu)化的預(yù)供應(yīng)虛擬機(jī),更快速地推送新版應(yīng)用程序。現(xiàn)在,使用Titus進(jìn)行的部署可在1-2分鐘內(nèi)完成,而以往單純使用虛擬機(jī)時(shí)往往需要數(shù)十分鐘。
所有這些改進(jìn)都源自開(kāi)發(fā)者更快速的創(chuàng)新。現(xiàn)在,批處理用戶和服務(wù)用戶都可以更快速地在本地進(jìn)行實(shí)驗(yàn)和測(cè)試,他們還可以更自信地將代碼部署到生產(chǎn)環(huán)境。這樣的速度也可以讓Netflix客戶更快獲得各類新功能。可以說(shuō),容器技術(shù)對(duì)我們的業(yè)務(wù)非常重要。
深入了解Titus上文介紹了我們構(gòu)建Titus的原因。下文將深入介紹Titus到底是如何提供這些價(jià)值的。我們將簡(jiǎn)要介紹Titus的調(diào)度功能和容器的執(zhí)行如何為服務(wù)和批處理作業(yè)需求提供支持,具體情況如下圖所示。
在處理應(yīng)用程序的調(diào)度工作時(shí),Titus可對(duì)所需資源和可用計(jì)算資源進(jìn)行匹配。Titus可支持“永久”運(yùn)行的服務(wù)作業(yè),以及“持續(xù)運(yùn)行直到完成”的批處理作業(yè)。服務(wù)作業(yè)可重啟動(dòng)失敗的實(shí)例,并通過(guò)自動(dòng)伸縮與負(fù)載的變化相匹配。批處理作業(yè)可根據(jù)策略進(jìn)行重試并一直運(yùn)行直到完成。
Titus為資源調(diào)度提供了多種SLA。通過(guò)EC2的自動(dòng)伸縮功能,Titus可根據(jù)當(dāng)前需求為即席(Ad hoc)批處理和非關(guān)鍵內(nèi)部服務(wù)提供按需獲取的計(jì)算容量。它還能為用戶需要執(zhí)行的工作負(fù)載和更關(guān)鍵的批處理任務(wù)提供預(yù)配置、有保障的容量。調(diào)度器可通過(guò)集裝優(yōu)化(Bin packing)提高大規(guī)模虛擬機(jī)的效能,并能通過(guò)反關(guān)聯(lián)性(Anti-affinity)實(shí)現(xiàn)跨越虛擬機(jī)和可用性集的可靠性。這種調(diào)度功能源自Netflix開(kāi)發(fā)的一個(gè)名為Fenzo的開(kāi)源庫(kù)。
Titus容器運(yùn)行在EC2虛擬機(jī)基礎(chǔ)上,并能與AWS和Netflix基礎(chǔ)架構(gòu)進(jìn)行集成。我們預(yù)測(cè)到用戶會(huì)在很長(zhǎng)一段時(shí)間內(nèi)同時(shí)使用虛擬機(jī)和容器,因此決定盡可能讓云平臺(tái)和運(yùn)維體驗(yàn)保持簡(jiǎn)單。使用AWS的過(guò)程中,我們選擇盡可能利用現(xiàn)有的EC2服務(wù)。例如,我們會(huì)使用Virtual Private Cloud(VPC)獲得可路由的IP,而沒(méi)有使用單獨(dú)的網(wǎng)絡(luò)覆蓋(Network overlay)。我們使用Elastic Network Interface(ENI)以確保所有容器都包含特定應(yīng)用程序所需的安全組。Titus提供的元數(shù)據(jù)代理使得容器可以了解自己運(yùn)行環(huán)境特定的容器視圖以及IAM憑據(jù)。容器無(wú)法看到宿主機(jī)的元數(shù)據(jù)(例如IP、主機(jī)名、實(shí)例ID)。我們還配合使用Linux、Docker,以及自有的隔離技術(shù)實(shí)施了多租戶隔離(CPU、內(nèi)存、磁盤、網(wǎng)絡(luò)、安全)。
為了成功地在Netflix的環(huán)境中應(yīng)用容器技術(shù),我們還要將其與現(xiàn)有開(kāi)發(fā)工具和運(yùn)維基礎(chǔ)架構(gòu)無(wú)縫集成。例如,Netflix已經(jīng)具備持續(xù)交付解決方案Spinnaker。雖然也可以通過(guò)調(diào)度器進(jìn)行滾動(dòng)更新并實(shí)現(xiàn)其他CI/CD概念,但通過(guò)Spinnaker提供這樣的功能使得我們的用戶可以跨越虛擬機(jī)和容器使用一套一致的部署工具。另外還有個(gè)例子:服務(wù)之間的通信。我們會(huì)盡可能避免重新實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)和服務(wù)負(fù)載均衡工作,取而代之的是提供一個(gè)完整的IP棧,借此容器將能與現(xiàn)有的Netflix服務(wù)發(fā)現(xiàn)和基于DNS(Route 53)的負(fù)載均衡機(jī)制配合使用。在這些例子中,Titus成功與否的一個(gè)關(guān)鍵原因在于:需要確定那些事情不該通過(guò)Titus來(lái)做,而是應(yīng)該利用其他基礎(chǔ)架構(gòu)團(tuán)隊(duì)所提供的相關(guān)功能來(lái)實(shí)現(xiàn)。
繼續(xù)使用現(xiàn)有系統(tǒng)的代價(jià)是:我們需要對(duì)這些系統(tǒng)進(jìn)行擴(kuò)充,以便能與虛擬機(jī)和容器技術(shù)配合使用。除了上文列舉的例子,我們還需要對(duì)遙測(cè)、性能自動(dòng)調(diào)優(yōu)、健康度檢查系統(tǒng)、混沌自動(dòng)化(Chaos automation)、流量控制、區(qū)域性故障轉(zhuǎn)移支持、密文管理,以及交互式系統(tǒng)訪問(wèn)等機(jī)制進(jìn)行擴(kuò)充。另一個(gè)代價(jià)是:由于需要與Netflix的這些系統(tǒng)進(jìn)行深入綁定,這使得我們很難利用其他開(kāi)源容器解決方案提供容器運(yùn)行時(shí)平臺(tái)之外的其他功能。
以我們的規(guī)模(以及工作負(fù)載密度)來(lái)說(shuō),容器平臺(tái)的運(yùn)行還需要密切關(guān)注可靠性,并且我們還會(huì)在系統(tǒng)的所有層面上遭遇不小的挑戰(zhàn)。我們已經(jīng)順利解決了Titus軟件,以及所依賴的其他開(kāi)源軟件(Docker Engine、Docker Distribution、Apache Mesos、Snap和Linux)相關(guān)的伸縮性和可靠性問(wèn)題。我們針對(duì)整個(gè)系統(tǒng)的所有層面設(shè)計(jì)了失敗處理機(jī)制,包括通過(guò)協(xié)調(diào)促進(jìn)資源管理層和容器運(yùn)行時(shí)之間分布式狀態(tài)的一致性。通過(guò)清晰衡量的服務(wù)級(jí)別目標(biāo)(容器發(fā)布啟動(dòng)延遲、由于Titus中問(wèn)題導(dǎo)致容器崩潰的百分率,以及系統(tǒng)API整體可用性),我們可以更好地對(duì)可靠性和功能進(jìn)行權(quán)衡。
容器技術(shù)幫助工程師提高效率的一個(gè)關(guān)鍵原因在于開(kāi)發(fā)工具。開(kāi)發(fā)者生產(chǎn)力工具團(tuán)隊(duì)構(gòu)建了一個(gè)名為Newt(Netflix Workflow Toolkit)的本地開(kāi)發(fā)工具。通過(guò)本地迭代并借助Titus進(jìn)行部署,Newt可簡(jiǎn)化容器開(kāi)發(fā)工作。通過(guò)在Newt和Titus之間實(shí)現(xiàn)一致的容器環(huán)境,也可以幫助開(kāi)發(fā)者更自信地編寫代碼。
目前Titus的使用情況
為了驅(qū)動(dòng)Netflix的服務(wù),我們通過(guò)三個(gè)Amazon區(qū)域,用多個(gè)測(cè)試和生產(chǎn)賬戶運(yùn)行了多個(gè)Titus棧。
2015年12月發(fā)布Titus后,當(dāng)時(shí)我們每周需要啟動(dòng)數(shù)千個(gè)容器,用來(lái)處理少量工作負(fù)載。上周,我們啟動(dòng)了上百萬(wàn)個(gè)容器,這些容器中運(yùn)行了數(shù)百個(gè)工作負(fù)載。一年多時(shí)間里,容器的用量增加了1000倍,而增長(zhǎng)勢(shì)頭依然沒(méi)有任何放緩的跡象。
為了向批處理用戶提供支持,我們?cè)诜逯禃r(shí)段運(yùn)行了500個(gè)r3.8xl實(shí)例,這意味著16,000個(gè)處理器內(nèi)核,以及120TB內(nèi)存的規(guī)模。我們還通過(guò)p2.8xl實(shí)例獲得了所需的GPU資源,借此支撐基于神經(jīng)網(wǎng)絡(luò)和微批(Mini-batch)的深度學(xué)習(xí)功能。
2017年上半年,流處理即服務(wù)團(tuán)隊(duì)決定通過(guò)Titus為自己基于Flink的系統(tǒng)提供更簡(jiǎn)單快速的集群管理能力。這一決定導(dǎo)致新增了超過(guò)10,000個(gè)長(zhǎng)期運(yùn)行的服務(wù)作業(yè)容器,并且隨著流處理作業(yè)的變化,這些容器都需要重新部署。各種服務(wù)共使用了數(shù)千個(gè)m4.4xl實(shí)例。
雖然上述用例對(duì)我們的業(yè)務(wù)很重要,但這些用例都不會(huì)對(duì)Netflix的客戶產(chǎn)生直接影響。不過(guò)這種情況最近有了些變化,最近我們開(kāi)始通過(guò)Titus容器運(yùn)行某些直接面向Netflix客戶的服務(wù)。
用于支撐直接面向客戶的服務(wù),這個(gè)決定必須慎重。過(guò)去六個(gè)月來(lái),我們一直在對(duì)虛擬機(jī)和容器之間的實(shí)時(shí)通信進(jìn)行復(fù)制,并使用復(fù)制的流量了解如何更好地運(yùn)維容器,以驗(yàn)證該平臺(tái)是否已經(jīng)面向生產(chǎn)環(huán)境做好了準(zhǔn)備。通過(guò)大量的前期工作,我們已經(jīng)可以自信地在基礎(chǔ)架構(gòu)中推行如此重大的變動(dòng)。
Titus團(tuán)隊(duì)
Netflix得以成功運(yùn)用Titus的原因之一在于,Titus開(kāi)發(fā)團(tuán)隊(duì)所積累的寶貴經(jīng)驗(yàn)和不斷的成長(zhǎng)。我們的容器用戶堅(jiān)信不疑地認(rèn)為,Titus團(tuán)隊(duì)可以通過(guò)Titus的運(yùn)維和創(chuàng)新滿足自己的需求。
這個(gè)團(tuán)隊(duì)的后續(xù)成長(zhǎng)還有很長(zhǎng)的路要走,我們也希望能將這個(gè)容器運(yùn)行時(shí)和開(kāi)發(fā)者體驗(yàn)擴(kuò)展到更多領(lǐng)域。