十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
歡迎來到Tungsten Fabric用戶案例系列文章,一起發(fā)現(xiàn)TF的更多應(yīng)用場景?!敖颐豅OL”系列的主人公是Tungsten Fabric用戶Riot Games游戲公司,作為LOL《英雄聯(lián)盟》的開發(fā)和運營商,Riot Games面臨全球范圍復(fù)雜部署的挑戰(zhàn),讓我們一起揭秘LOL背后的“英雄們”,看他們是如何運行在線服務(wù)的吧。
作者:Kyle Allan和Carl Quinn(文章來源:Riot Games)站在用戶的角度思考問題,與客戶深入溝通,找到新洲網(wǎng)站設(shè)計與新洲網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網(wǎng)站制作、成都網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、域名注冊、虛擬主機、企業(yè)郵箱。業(yè)務(wù)覆蓋新洲地區(qū)。
我們是Kyle Allan和Carl Quinn,在Riot的基礎(chǔ)架構(gòu)團隊工作。歡迎閱讀這個系列的第二篇文章,詳細介紹我們?nèi)绾卧谌蚍秶鷥?nèi)部署和操作后端功能。在本文中,我們將深入探討部署生態(tài)系統(tǒng)的第一個核心組件:容器調(diào)度。
在Jonathan的第一篇系列文章中,討論了Riot的部署歷史和我們面臨的挑戰(zhàn)。特別是,他概述了當(dāng)我們?yōu)椤队⑿勐?lián)盟》不斷添加基礎(chǔ)架構(gòu)設(shè)施時,尤其是面對“為每個應(yīng)用程序手動配置服務(wù)器”這樣的場景下,我們軟件部署難度不斷加劇。后來,出現(xiàn)了一個名為Docker的工具,改變了我們的服務(wù)器部署方法——進一步在我們內(nèi)部就迭代出來Admiral,它是我們用于集群調(diào)度和管理的內(nèi)部工具。
重要的是,應(yīng)用程序部署的旅程還遠遠沒有結(jié)束,它還在不斷發(fā)展,我們正在為下一個階段做準備(可能采用DC/OS,稍后討論)。本文介紹了如何到達這一步,以及為什么做出這樣的決定,希望其他人也可以從這個故事中有所收益。
當(dāng)Docker橫空出世,并且Linux容器化成為一種更廣為人知的技術(shù)時,我們意識到,可以通過容器化基礎(chǔ)架構(gòu)的實施而受益。Docker容器映像提供了一個不變的、可部署的“神器”,它可以一次構(gòu)建并部署在開發(fā)、測試和生產(chǎn)中。此外,它還保證生產(chǎn)環(huán)境中運行的映像的依賴性,與測試期間的依賴性完全相同。
另一個好處尤其重要:Docker允許將部署單元(容器)與計算單元(主機)解耦,它通過利用調(diào)度程序?qū)⑷萜鞣峙浣o主機(希望以一種智能的方式),從而消除了服務(wù)器與應(yīng)用程序之間的耦合——給定的容器可以在任意數(shù)量的可能的服務(wù)器上運行。
通過將后端服務(wù)打包成Docker映像,并且可以隨時將其部署并擴展到服務(wù)器集群,我們應(yīng)該能夠迅速適應(yīng)變化。我們可以添加新的玩家功能,當(dāng)流量增加時進行擴容,并快速推出更新和修復(fù)程序。在考慮將容器內(nèi)的服務(wù)部署到生產(chǎn)環(huán)境時,需要解決三個主要問題:
這三個問題的答案是,我們需要一個調(diào)度程序——一種在服務(wù)集群層面運行并執(zhí)行我們的容器策略的服務(wù)。調(diào)度程序是維護集群、確保容器在正確的位置運行,以及在容器退出時重新啟動它們的關(guān)鍵組件。
例如,我們可能要啟動諸如Hextech Crafting之類的服務(wù),該服務(wù)需要六個容器實例來處理其負載。調(diào)度程序負責(zé)查找具有足夠內(nèi)存和CPU資源以支持這些容器的主機,并執(zhí)行使這些容器運行所需的任何操作。如果這些服務(wù)器之一發(fā)生故障,調(diào)度程序還負責(zé)為受影響的容器查找替換主機。
當(dāng)我們決定使用調(diào)度程序時,就快速進行原型設(shè)計,以便了解容器化服務(wù)在生產(chǎn)中是否適合我們。此外,我們需要確?,F(xiàn)有的開放源代碼選項可以在目前的環(huán)境中運行,或者確保維護人員愿意接受我們的調(diào)整。
在開始編寫Admiral調(diào)度程序之前,我們調(diào)查了現(xiàn)有集群管理器和調(diào)度程序的狀況。都有誰在Docker主機集群之間調(diào)度容器,它們是如何做到的?它們的技術(shù)還能解決我們的問題嗎?
在最初的研究中,我們調(diào)研了一些項目:
Mesos + Marathon
LMCTFY => Kubernetes
Fleet
我們還原型化了一個小型命令行工具,該工具可通過REST與Docker API進行通信,并且成功演示了如何使用此工具來協(xié)調(diào)部署。然后,我們決定繼續(xù)編寫自己的調(diào)度程序。
我們借鑒了研究過的系統(tǒng)的一些最佳功能,包括Kubernetes的Pods和Marathon的約束系統(tǒng)背后的核心思想。我們的愿景是跟蹤這些系統(tǒng)的體系結(jié)構(gòu)和功能,在可能的情況下影響它們,并最終嘗試在將來與其中之一融合。
在創(chuàng)建了一個基于JSON的基礎(chǔ)部署元數(shù)據(jù)語言(我們稱為CUDL,ClUster描述語言)之后,我們開始編寫Admiral。CUDL成為Admiral在其REST API中使用的語言,兩個主要組成部分如下:
集群和打包具有兩個不同的方面:spec和live。每個方面都代表對容器生命周期不同階段的描述。
Spec,表示元素所需的狀態(tài)
Live,表示元素已實現(xiàn)的狀態(tài)
Admiral用Go編寫,并且在生產(chǎn)數(shù)據(jù)中心中運行時,被編譯并打包到Docker容器中。Admiral有幾個內(nèi)部子系統(tǒng),其中大部分如下圖所示。
從用戶的角度來看,與Admiral的交互是通過其提供的admiralctl命令行工具進行的,該工具通過REST API與Admiral進行通信。借助admiralctl,用戶可以通過標(biāo)準指令訪問Admiral的所有功能:POST新的Spec打包以進行調(diào)度,DELETE舊包(Packs),以及GET當(dāng)前狀態(tài)。
在生產(chǎn)過程中,Admiral將使用Hashicorp的Consul存儲Spec狀態(tài),定期對其進行備份,以防發(fā)生災(zāi)難性故障。萬一完全丟失數(shù)據(jù),Admiral還能使用從各個Docker守護程序檢索到的Live狀態(tài)中的信息,來部分重建其Spec狀態(tài)。
協(xié)調(diào)器(reconciler)屬于Admiral的核心,是驅(qū)動調(diào)度工作流程的關(guān)鍵子系統(tǒng)。協(xié)調(diào)器會周期性地將實際的Live狀態(tài)與所需的Spec狀態(tài)進行比較,并且在出現(xiàn)差異時,調(diào)度所需的操作,以便將Live狀態(tài)恢復(fù)正常。
Live狀態(tài)及其驅(qū)動程序包通過緩存Live主機和容器狀態(tài),并通過其REST API提供與集群主機上所有Docker守護程序的通信,來支持協(xié)調(diào)器。
Admiral的協(xié)調(diào)器可對Spec打包進行操作,有效地將其轉(zhuǎn)換為Live打包。在將Spec打包提交給Admiral時,協(xié)調(diào)器將創(chuàng)建容器并使用Docker守護程序啟動它們。正是通過這種機制,協(xié)調(diào)器實現(xiàn)了我們前面所述的最重要的兩個高級調(diào)度目標(biāo)。當(dāng)協(xié)調(diào)器收到Spec打包時,它將:
讓我們看一下在Docker主機上啟動容器的示例。在此示例中,我們將使用本地Docker守護程序作為Docker主機,并與Admiral服務(wù)器的本地實例進行交互。
首先,我們使用“admiral pack create
你能注意到,幾乎在剛剛運行命令后,容器就已經(jīng)在我的機器上啟動。這個容器是使用我的打包文件中的參數(shù)啟動的,如下所示:
接下來,在調(diào)用“admiral pack create”之后,我們可以使用“show”命令來查看Admiral創(chuàng)建的Live打包。這里的命令是“admiral pack show
最后,通過點擊容器中的服務(wù),我們可以驗證打包是否正常工作。使用來自“admiral pack show”命令的信息,我們可以通過一個簡單的curl來拼出我們的服務(wù):
在Admiral內(nèi)部,協(xié)調(diào)器始終處于運行狀態(tài),以確保集群的Live狀態(tài)始終與所需的Spec狀態(tài)相匹配。這樣,當(dāng)容器由于崩潰而失敗并退出,或者由于硬件故障而導(dǎo)致整個服務(wù)器不可用時,我們還可以進行恢復(fù)業(yè)務(wù)。協(xié)調(diào)器努力確保狀態(tài)匹配,以便玩家永遠不會遇到中斷問題。此功能解決了我們前面提到的第三個,也是最后一個問題:當(dāng)容器意外退出時,我們可以快速恢復(fù),并且將影響控制到最小。
下面將展示通過“admiral pack create”命令啟動的現(xiàn)有容器。然后,我將終止該容器,并停止其執(zhí)行。在幾秒鐘內(nèi),協(xié)調(diào)器啟動了一個新的容器(具有不同的ID),因為它意識到Live狀態(tài)與Spec狀態(tài)不匹配。
為了最好地分配容器,調(diào)度程序必須洞悉主機集群。解決此問題有兩個關(guān)鍵組件:
資源——服務(wù)器可用資源的一種表示形式,包括內(nèi)存、CPU、I/O,以及網(wǎng)絡(luò)等其他資源。
約束——打包隨附的一組條件,可為調(diào)度程序提供有關(guān)可放置打包的限制的詳細信息。例如,我們可能要放置一個打包實例:
通過在主機上定義資源,我們使調(diào)度程序可以靈活地決定將容器放置在何處。
通過在打包集(packs)上定義約束,我們可以限制調(diào)度程序的選擇,以便將特定的模式強制應(yīng)用到集群中。
對于Riot而言,Admiral是我們部署技術(shù)不斷發(fā)展的重要組成部分。通過利用Docker和調(diào)度系統(tǒng)的功能,我們能夠比以前更快地向玩家交付后端功能。
在本文中,我們深入研究了Admiral的一些功能,并展示了如何在一組機器集群之間調(diào)度容器。就像Jonathan在他的第一篇文章中提到的那樣,開源世界已經(jīng)迅速轉(zhuǎn)向非常相似的模型。展望未來,我們將轉(zhuǎn)移Admiral的工作,并專注于部署DC/OS,它已成為調(diào)度容器工作負載的領(lǐng)先的開源應(yīng)用程序之一。
如果你經(jīng)歷了類似的旅程,或者覺得自己有話要補充,非常歡迎與我們?nèi)〉寐?lián)系。
更多“揭秘LOL”系列文章
● 揭秘LOL背后的IT基礎(chǔ)架構(gòu)丨踏上部署多樣性的征程