楊 忠
(成都理工大學(xué)工程技術(shù)學(xué)院 樂山 614000)
隨著互聯(lián)網(wǎng)的迅猛發(fā)展,傳統(tǒng)計(jì)算機(jī)架構(gòu)已不能滿足爆炸式增長的數(shù)據(jù)處理需求,云計(jì)算的出現(xiàn)為這一問題提供了新的解決思路,然而在實(shí)際使用時(shí),服務(wù)器通常會面臨多種不同種類的工作負(fù)載[1],企業(yè)需要根據(jù)這些負(fù)載的變化動(dòng)態(tài)地調(diào)整服務(wù)器的數(shù)量以保證服務(wù)的穩(wěn)定性[2]。在某些特定的互聯(lián)網(wǎng)應(yīng)用場景中,服務(wù)器時(shí)常會出現(xiàn)不可預(yù)知的負(fù)載請求,在這些額外負(fù)載出現(xiàn)時(shí),企業(yè)需要及時(shí)增加服務(wù)器的數(shù)量,從而保證服務(wù)的穩(wěn)定性,在這些額外負(fù)載消退時(shí),企業(yè)也需要即使終止部分服務(wù)器,節(jié)省運(yùn)維和管理費(fèi)用。目前已有很多基于動(dòng)態(tài)負(fù)載的集群伸縮方法研究,文獻(xiàn)[3]提出了一種基于工作流模型的虛擬機(jī)動(dòng)態(tài)分配以及回收的方法,該方法通過對作業(yè)指定截止時(shí)間的方式來進(jìn)行作業(yè)的調(diào)度分配,從而節(jié)省計(jì)算資源,但是該方法并不能對未來的工作負(fù)載進(jìn)行預(yù)測。文獻(xiàn)[4]提出了一種面向混合負(fù)載的集群資源彈性調(diào)度方法,該方法允許作業(yè)基于自身負(fù)載特征提出多維度的資源申請,從而實(shí)現(xiàn)同一集群內(nèi)各業(yè)務(wù)的統(tǒng)一部署與管理。文獻(xiàn)[5]提出了一種基于用戶負(fù)載預(yù)測的虛擬資源動(dòng)態(tài)調(diào)度管理框架,該框架可以對用戶的高負(fù)載進(jìn)行預(yù)測并快速做出響應(yīng),保證服務(wù)的可用性。在以上關(guān)于動(dòng)態(tài)負(fù)載的集群伸縮研究中,集群的底層都是基于傳統(tǒng)的虛擬機(jī)技術(shù),然而虛擬機(jī)需要額外的虛擬化控制層來實(shí)現(xiàn)硬件的虛擬化,因此給云平臺帶來了性能上的額外損失,并且虛擬機(jī)的啟動(dòng)速度也比較慢。
為了解決以上問題,本文通過引入Docker容器技術(shù),提出了一種基于混合負(fù)載的容器集群動(dòng)態(tài)伸縮方案,這一方案能夠根據(jù)不同的工作負(fù)載進(jìn)行相應(yīng)的容器集群伸縮,從而有效地應(yīng)對網(wǎng)絡(luò)峰值,提升服務(wù)質(zhì)量。
Docker是一款輕量級的容器管理引擎,其最初實(shí)現(xiàn)主要是基于Linux的容器技術(shù)(LXC),它使用Go語言進(jìn)行系統(tǒng)開發(fā),屬于操作系統(tǒng)層面的虛擬化技術(shù)[6]。Docker在容器的基礎(chǔ)上進(jìn)行了進(jìn)一步的封裝,包括文件系統(tǒng)、網(wǎng)絡(luò)通信和進(jìn)程隔離等,因此能夠給用戶提供一個(gè)更加易于使用的接口,極大地簡化了容器的創(chuàng)建和管理操作。
Docker容器從本質(zhì)上來說是宿主機(jī)中的一個(gè)進(jìn)程,它的底層核心技術(shù)主要包括Linux上的命名空間(Namespaces)、控制組(Control groups)和聯(lián)合文件系統(tǒng)(Union file systems),其中Namespaces主要用來解決容器間的資源隔離問題,cgroups主要用來實(shí)現(xiàn)容器的資源限制功能,而UFS則實(shí)現(xiàn)了容器內(nèi)高效的文件操作。
1)Docker資源隔離
Docker使用Namespaces技術(shù)來實(shí)現(xiàn)底層的資源隔離,Namespaces是Linux內(nèi)核中的一個(gè)強(qiáng)大特性,在同一個(gè)Namespace下的進(jìn)程能夠相互感知彼此的存在,但是對外界的其他進(jìn)程卻一無所知,由于這一特性,不同容器中的進(jìn)程雖然都共用同一個(gè)內(nèi)核和某些運(yùn)行時(shí)環(huán)境(如系統(tǒng)命令和系統(tǒng)庫),但是彼此都看不到,都以為系統(tǒng)中只有當(dāng)前容器存在,這樣便達(dá)到了獨(dú)立和隔離的目的,實(shí)現(xiàn)了操作系統(tǒng)層的輕量虛擬化服務(wù)。
2)Docker資源控制
Docker使用cgroups技術(shù)來實(shí)現(xiàn)對底層資源的控制功能,cgroups是Linux內(nèi)核提供的一種機(jī)制,它能夠根據(jù)用戶的需求對共享資源(CPU、內(nèi)存和I/O等)進(jìn)行隔離和限制,因此可以解決多個(gè)容器同時(shí)運(yùn)行時(shí)的資源競爭問題。cgroups能夠提供以下四種功能[7]:資源限制、優(yōu)先級分配、資源統(tǒng)計(jì)和任務(wù)控制。
資源限制:cgroups能夠限制同一個(gè)進(jìn)程組中能夠使用的資源總量。
優(yōu)先級分配:cgroups能夠通過控制對一個(gè)進(jìn)程組分配的CPU時(shí)間片的數(shù)量或磁盤I/O帶寬的大小從而控制進(jìn)程組的優(yōu)先級。
資源統(tǒng)計(jì):cgroups能夠統(tǒng)計(jì)一個(gè)進(jìn)程組中的資源使用總量。
任務(wù)控制:cgroups能夠?qū)M(jìn)程執(zhí)行掛起和恢復(fù)等操作,從而控制任務(wù)的執(zhí)行狀態(tài)。
3)Docker文件系統(tǒng)
Docker使用的聯(lián)合文件系統(tǒng)(UFS)是一種高性能的分層文件系統(tǒng),它支持將文件系統(tǒng)中的修改進(jìn)行提交和層層疊加,這一特性使得Docker鏡像能夠通過分層來實(shí)現(xiàn)繼承,在實(shí)際使用時(shí),通常會基于基礎(chǔ)鏡像來制作各種不同的應(yīng)用鏡像,這些應(yīng)用鏡像都是共享的同一個(gè)基礎(chǔ)鏡像,因此能夠提高存儲效率。
若開發(fā)者需要將Docker鏡像升級到新版本,則在改動(dòng)原始Docker鏡像時(shí),系統(tǒng)會自動(dòng)創(chuàng)建一個(gè)新的鏡像層,因此開發(fā)者無需重新構(gòu)建應(yīng)用鏡像,只需要在老版本的鏡像上添加新的層即可。在開發(fā)者分發(fā)鏡像時(shí),也只需要分發(fā)這些被改動(dòng)過的新層內(nèi)容,這使得Docker的鏡像管理變得更加方便和快捷。
Docker使用UFS作為其文件系統(tǒng)主要有以下幾點(diǎn)優(yōu)勢[8]:首先由于多個(gè)容器能夠共享同一個(gè)基礎(chǔ)鏡像存儲,因此能夠有效地節(jié)省存儲空間;其次是能夠?qū)崿F(xiàn)不同應(yīng)用的快速部署,并且節(jié)省內(nèi)存,這是因?yàn)楫?dāng)多個(gè)容器共享基礎(chǔ)鏡像時(shí),容器中的進(jìn)程命中緩存內(nèi)容的幾率也會大大增加;最后就是應(yīng)用的升級也會更加方便,開發(fā)者可以通過更新基礎(chǔ)鏡像從而一次性更新所有基于此基礎(chǔ)鏡像的容器。
在實(shí)際的使用中,Docker通常被用來與傳統(tǒng)的虛擬機(jī)技術(shù)進(jìn)行比較,圖1分別列出了Docker和傳統(tǒng)的虛擬機(jī)技術(shù)的體系結(jié)構(gòu)。傳統(tǒng)的虛擬機(jī)技術(shù)主要是通過虛擬出一套硬件系統(tǒng)后,在虛擬的硬件上運(yùn)行一個(gè)完整的操作系統(tǒng),所有的應(yīng)用程序都運(yùn)行于這個(gè)系統(tǒng)上。而容器中的應(yīng)用進(jìn)程則是直接運(yùn)行于宿主機(jī)的操作系統(tǒng)內(nèi)核上,它不需要進(jìn)行虛擬硬件的操作,也沒有自己的操作系統(tǒng),因此會比傳統(tǒng)的虛擬機(jī)技術(shù)更加輕便快捷[9]。
圖1 Docker與虛擬機(jī)的比較
集群的動(dòng)態(tài)伸縮指的是集群能夠根據(jù)工作負(fù)載的大小自動(dòng)調(diào)整集群的規(guī)模,從而調(diào)整其對外服務(wù)的能力。借助于動(dòng)態(tài)伸縮技術(shù),企業(yè)能夠在網(wǎng)絡(luò)峰值到來時(shí)自動(dòng)地?cái)U(kuò)展資源從而處理額外的工作負(fù)載,并且在峰值過后可以自動(dòng)減少資源從而降低管理和運(yùn)維成本。動(dòng)態(tài)伸縮技術(shù)按照其實(shí)現(xiàn)方式可以劃分為響應(yīng)型伸縮和預(yù)測型伸縮。
基于閾值的響應(yīng)型伸縮算法是一種比較簡單的算法[10],因此被廣泛應(yīng)用于云平臺的自動(dòng)擴(kuò)展中。具體來說,基于閾值的響應(yīng)型伸縮算法通過對系統(tǒng)資源(如CPU、內(nèi)存、網(wǎng)絡(luò)流量和磁盤I/O等)的使用情況進(jìn)行實(shí)時(shí)監(jiān)控,一旦出現(xiàn)某些指標(biāo)的實(shí)際值超過設(shè)定的閾值時(shí),就會發(fā)出擴(kuò)展或收縮命令。在基于閾值的響應(yīng)型伸縮算法中,最重要的就是響應(yīng)規(guī)則和閾值的制定,通常只有在系統(tǒng)的負(fù)載變化很明確的情況下才能很好地制定響應(yīng)規(guī)則,并設(shè)置閾值,因此它的優(yōu)點(diǎn)主要是實(shí)現(xiàn)較為簡單,通用性強(qiáng),但是在一些負(fù)載變化不明確的場景中無法很好地使用,系統(tǒng)的伸縮調(diào)整往往會晚于工作負(fù)載的變化,因此導(dǎo)致用戶的體驗(yàn)變差。
在基于閾值的響應(yīng)型伸縮算法中,算法只會對系統(tǒng)資源的實(shí)時(shí)情況進(jìn)行響應(yīng),因此具有滯后性的特點(diǎn),而在預(yù)測型伸縮算法[11]中,系統(tǒng)會對過去一段時(shí)間內(nèi)的數(shù)據(jù)進(jìn)行分析、建模并完成對未來時(shí)刻的預(yù)測,其中使用到的分析方法主要有時(shí)間序列分析、隊(duì)列理論和增強(qiáng)型學(xué)習(xí)等。通常在使用預(yù)測型伸縮算法時(shí)也會使用到基于閾值的響應(yīng)型伸縮算法,在預(yù)測型伸縮算法計(jì)算出預(yù)測結(jié)果時(shí),再通過響應(yīng)規(guī)則和閾值來決定是否需要進(jìn)行容器集群的擴(kuò)展或收縮。預(yù)測型伸縮算法能夠很好地彌補(bǔ)基于閾值的響應(yīng)型伸縮算法的缺點(diǎn),它能夠在系統(tǒng)的工作負(fù)載變化之前就發(fā)出擴(kuò)展或收縮命令,因此能夠保證系統(tǒng)的穩(wěn)定性和連續(xù)性,缺點(diǎn)就是預(yù)測算法的選擇非常重要,當(dāng)預(yù)測算法過于復(fù)雜時(shí)會使得預(yù)測建模過程過于緩慢,若預(yù)測造成較大偏差又會給容器集群帶來很大的資源浪費(fèi)。
現(xiàn)有的預(yù)測算法主要包括兩大類:機(jī)器學(xué)習(xí)[12]和時(shí)間序列分析[13],前者通常需要在學(xué)習(xí)過程上花費(fèi)大量的時(shí)間,因此不太適用于容器集群的快速伸縮中,而時(shí)間序列分析則相對簡單且無明顯的學(xué)習(xí)過程,計(jì)算速度較快。時(shí)間序列分析的常見預(yù)測算法有簡單移動(dòng)平均法、指數(shù)平滑法和自回歸模型等。
基于混合負(fù)載的容器集群動(dòng)態(tài)伸縮方案的整體架構(gòu)如圖2所示,整個(gè)方案主要由底層容器集群、負(fù)載均衡和伸縮控制系統(tǒng)這三部分組成。
圖2 方案總體架構(gòu)圖
伸縮控制系統(tǒng)是整個(gè)方案架構(gòu)的核心部分,它包括資源監(jiān)控模塊、伸縮決策模塊和資源調(diào)度模塊。其中資源監(jiān)控模塊負(fù)責(zé)統(tǒng)計(jì)物理主機(jī)和Dock?er容器的資源使用情況并報(bào)告給伸縮決策模塊,伸縮決策模塊會分析統(tǒng)計(jì)數(shù)據(jù)從而決定是否需要進(jìn)行擴(kuò)展或收縮,資源調(diào)度模塊負(fù)責(zé)對底層的容器資源進(jìn)行調(diào)度,負(fù)責(zé)容器的創(chuàng)建和銷毀工作。
4.2.1 資源監(jiān)控類型
對容器集群的資源監(jiān)控可以劃分為對物理主機(jī)的資源監(jiān)控和對Docker容器的資源監(jiān)控。
1)基于物理主機(jī)的資源監(jiān)控
相對于Docker容器來說,物理主機(jī)的生命周期更長,因此更應(yīng)該進(jìn)行資源優(yōu)化,當(dāng)多個(gè)Docker容器運(yùn)行于同一臺物理主機(jī)時(shí),需要很好地考慮資源分配問題,因此需要對物理主機(jī)的相關(guān)指標(biāo)進(jìn)行監(jiān)控。物理主機(jī)的相關(guān)監(jiān)控指標(biāo)包括主機(jī)CPU使用情況、主機(jī)內(nèi)存使用情況、主機(jī)網(wǎng)絡(luò)帶寬和主機(jī)上運(yùn)行的容器數(shù)量等。
2)基于容器的資源監(jiān)控
主機(jī)資源的共享需要對容器進(jìn)行合理的調(diào)配,在容器集群的彈性伸縮中,需要根據(jù)容器資源的使用情況來確定是否需要進(jìn)行擴(kuò)容或縮容。Docker主要通過cgroups來實(shí)現(xiàn)容器的資源限制,限制的對象包括容器的CPU占用率、內(nèi)存使用量、磁盤I/O,網(wǎng)絡(luò)流量也是需要監(jiān)控的因素之一。
4.2.2 資源監(jiān)控架構(gòu)設(shè)計(jì)
資源監(jiān)控模塊主要對主機(jī)和Docker容器運(yùn)行時(shí)的各項(xiàng)指標(biāo)數(shù)據(jù)進(jìn)行收集并進(jìn)行存儲,其架構(gòu)如圖3所示,主要分為數(shù)據(jù)采集(Collector)、數(shù)據(jù)處理(Processor)、數(shù)據(jù)存儲(Storage)和數(shù)據(jù)展示(Dash?boards)這四個(gè)模塊。其中Collector運(yùn)行在主機(jī)上,它會將所有指標(biāo)數(shù)據(jù)上傳到Processor,Processor在獲取到監(jiān)控?cái)?shù)據(jù)后會通過Storage定時(shí)進(jìn)行數(shù)據(jù)的存儲,用戶能夠通過Dashboards獲取到監(jiān)控?cái)?shù)據(jù)并進(jìn)行展示。
圖3 資源監(jiān)控架構(gòu)圖
伸縮決策模塊主要負(fù)責(zé)根據(jù)資源監(jiān)控模塊的數(shù)據(jù)判斷是否需要進(jìn)行容器集群的擴(kuò)展或收縮,然后向資源調(diào)度模塊發(fā)出對應(yīng)的指令,其架構(gòu)圖如圖4所示。伸縮決策模塊主要由兩個(gè)部分組成:Mod?eler模塊和Controller模塊,其中Modeler模塊負(fù)責(zé)對監(jiān)控歷史數(shù)據(jù)進(jìn)行建模,從而預(yù)測未來時(shí)刻的數(shù)據(jù),而Controller模塊則負(fù)責(zé)對所有的輸入數(shù)據(jù)進(jìn)行判斷,并在滿足伸縮條件時(shí)對資源調(diào)度模塊發(fā)出伸縮調(diào)整命令。
圖4 伸縮決策模塊系統(tǒng)架構(gòu)圖
在實(shí)際的互聯(lián)網(wǎng)應(yīng)用場景中,通??梢詫⒎?wù)劃分為計(jì)算密集型服務(wù)和網(wǎng)絡(luò)密集型服務(wù),計(jì)算密集型服務(wù)主要依賴于CPU,在這種服務(wù)場景下,CPU的使用率會在很短的時(shí)間內(nèi)提升到一個(gè)較高的值,并且變化很快,因此很難對其進(jìn)行預(yù)測,而網(wǎng)絡(luò)密集型服務(wù)則主要依賴于網(wǎng)絡(luò)帶寬,在這種服務(wù)場景下,網(wǎng)絡(luò)流量的變化更為平緩,連續(xù)性也較強(qiáng),因此對于網(wǎng)絡(luò)流量使用預(yù)測算法通常能夠得到一個(gè)比較合理的預(yù)測值。綜合考慮CPU和網(wǎng)絡(luò)流量的變化特征,本文中對計(jì)算密集型服務(wù)采用基于閾值的響應(yīng)型伸縮算法,而對網(wǎng)絡(luò)密集型服務(wù)則采用預(yù)測型伸縮算法。
4.3.1 Modeler模塊
Modeler模塊主要負(fù)責(zé)預(yù)測型伸縮算法的實(shí)現(xiàn),它會讀取數(shù)據(jù)庫中的網(wǎng)絡(luò)流量歷史數(shù)據(jù),并對其進(jìn)行建模,然后預(yù)測下一時(shí)刻的網(wǎng)絡(luò)流量值,最后將這一預(yù)測值發(fā)送給Controller模塊。綜合考慮時(shí)序序列分析的各種預(yù)測算法,本文選用了二次指數(shù)平滑法來對網(wǎng)絡(luò)流量值進(jìn)行預(yù)測,二次指數(shù)平滑法的計(jì)算公式為
二次指數(shù)平滑法的預(yù)測模型為
其中,F(xiàn)t+T為第t+T次的預(yù)測值,T為未來預(yù)測的期數(shù),at和bt分別為模型參數(shù),其計(jì)算公式為
Modeler模塊的工作流程圖如圖5所示。
圖5 Modeler模塊流程圖
4.3.2 Controller模塊
Controller模塊主要負(fù)責(zé)基于閾值的響應(yīng)型伸縮算法的實(shí)現(xiàn),它會對Modeler模塊提供的網(wǎng)絡(luò)流量預(yù)測值和CPU的實(shí)時(shí)使用數(shù)據(jù)進(jìn)行判斷,若有任意一種資源的使用情況超過給定的閾值,則會立即計(jì)算需要擴(kuò)充的容器數(shù)量,并向資源調(diào)度模塊發(fā)送對應(yīng)的伸縮命令,完成容器集群的伸縮。這一模塊主要包含兩個(gè)過程:伸縮條件判斷和容器數(shù)量計(jì)算。
1)判斷伸縮條件
Controller模塊會根據(jù)容器的實(shí)際資源使用情況對各種硬件資源(主要是CPU使用率和網(wǎng)絡(luò)流量大?。┰O(shè)定一個(gè)閾值T0,當(dāng)容器資源的實(shí)際使用值Ut第一次超過這個(gè)閾值的時(shí)候,會進(jìn)入伸縮評估階段,算法會維護(hù)一個(gè)長度為L的數(shù)組A,當(dāng)后續(xù)的資源使用值Ut大于閾值T0時(shí),會將Ut加入數(shù)組A,若在后續(xù)的L個(gè)資源使用值中有一個(gè)小于閾值T0,則會將數(shù)組清零,重新等待下一次的評估。若在L長度的時(shí)間內(nèi),資源的實(shí)際使用值一直都大于閾值T0,則認(rèn)為需要進(jìn)行對應(yīng)服務(wù)的擴(kuò)容,并且在這之后Controller模塊會進(jìn)入一段時(shí)間的冷卻階段,這期間不會進(jìn)行伸縮評估,避免容器集群的頻繁伸縮給系統(tǒng)服務(wù)帶來劇烈抖動(dòng)[14]。
2)計(jì)算容器數(shù)量
當(dāng)伸縮條件判斷過程給出了服務(wù)擴(kuò)容的信號,則系統(tǒng)會進(jìn)行擴(kuò)充容器數(shù)量的計(jì)算。擴(kuò)充容器數(shù)量的計(jì)算主要通過網(wǎng)絡(luò)流量進(jìn)行估算,若設(shè)定單個(gè)容器的服務(wù)能力為C0,額外網(wǎng)絡(luò)流量對應(yīng)的服務(wù)需求為C,則系統(tǒng)所需要擴(kuò)充的容器數(shù)量為
整個(gè)Controller模塊的流程圖如圖6所示。
圖6 Controller模塊流程圖
在容器集群擴(kuò)展時(shí),綜合考慮CPU和網(wǎng)絡(luò)流量的實(shí)際情況,在CPU突破閾值的場景下,系統(tǒng)只會進(jìn)行第一步,也就是只會判定是否滿足擴(kuò)展條件,在滿足擴(kuò)展條件時(shí),Controller模塊會向資源調(diào)度模塊發(fā)出擴(kuò)展命令,并且指定擴(kuò)展數(shù)量為1,而在網(wǎng)絡(luò)流量突破閾值的場景下,系統(tǒng)會首先進(jìn)行擴(kuò)展條件的判斷,然后再計(jì)算需要擴(kuò)充的容器數(shù)量n,此時(shí)Controller模塊也會向資源調(diào)度模塊發(fā)出擴(kuò)展命令,指定擴(kuò)展數(shù)量為n。
在容器集群收縮時(shí),考慮到業(yè)務(wù)容器數(shù)量的突然變小會給負(fù)載均衡模塊帶來較大的影響,因此在這種情況下,系統(tǒng)也只會進(jìn)行第一步,即判斷是否滿足收縮條件,若滿足指定的收縮條件,則Control?ler模塊會向資源調(diào)度模塊發(fā)出收縮指令,并指定收縮數(shù)量為1。
資源調(diào)度模塊主要負(fù)責(zé)對容器集群的底層資源進(jìn)行分配和調(diào)度,當(dāng)集群需要進(jìn)行擴(kuò)展或收縮時(shí),資源調(diào)度模塊會確定在哪臺宿主機(jī)上進(jìn)行容器的創(chuàng)建或銷毀[15]。資源調(diào)度模塊主要分為兩個(gè)部分:Manager模塊和Scheduler模塊,其架構(gòu)圖如圖7所示。
圖7 資源調(diào)度模塊系統(tǒng)架構(gòu)圖
4.4.1 Manager模塊
Manager主要負(fù)責(zé)根據(jù)給定的調(diào)度策略確定待創(chuàng)建或銷毀的容器對應(yīng)的宿主機(jī)節(jié)點(diǎn),其調(diào)度策略主要包含兩個(gè)步驟:節(jié)點(diǎn)篩選和節(jié)點(diǎn)打分。
在節(jié)點(diǎn)篩選過程中,主要考慮的篩選條件包括端口占用和資源占用,端口占用主要是查看待調(diào)度容器指定的端口是否已經(jīng)在宿主機(jī)上被占用,若端口已被占用則舍棄此節(jié)點(diǎn),資源占用主要是查看宿主機(jī)上的可用資源是否能夠滿足待調(diào)度容器的資源使用需求,若不滿足則同樣舍棄此節(jié)點(diǎn)。
在經(jīng)過了篩選過程后,會得到一個(gè)備選主機(jī)節(jié)點(diǎn)列表,然后便進(jìn)入打分過程,打分過程中的分值主要用于體現(xiàn)宿主機(jī)上的資源消耗情況,資源消耗越小,則其對應(yīng)的分值越高,這一策略使得集群中的宿主機(jī)資源使用情況能夠盡量平衡。其具體計(jì)算過程為:首先計(jì)算出待調(diào)度容器和宿主機(jī)上所有容器的CPU占用總量totalCpu、內(nèi)存占用總量to?talMem和網(wǎng)絡(luò)帶寬占用總量totalNet,然后對其打分,打分規(guī)則為
其中,CpuCap為宿主機(jī)的CPU計(jì)算能力,Memory?Cap為宿主機(jī)的內(nèi)存總?cè)萘?,NetCap為宿主機(jī)的網(wǎng)絡(luò)帶寬大小,int()為取整函數(shù)。
在經(jīng)過篩選和打分兩個(gè)階段后,對于待調(diào)度的容器會確定其對應(yīng)的宿主機(jī),系統(tǒng)會將這一配對信息寫入到etcd中,供各個(gè)主機(jī)上的Scheduler模塊使用。
4.4.2 Scheduler模塊
Scheduler主要負(fù)責(zé)對Manager生成的調(diào)度信息進(jìn)行監(jiān)聽,在獲取到本節(jié)點(diǎn)的調(diào)度信息后,自動(dòng)從本地倉庫下載容器鏡像,并啟動(dòng)容器。其調(diào)度過程如下:
1)Scheduler根據(jù)etcd中的容器信息確定其對應(yīng)的Docker鏡像和資源限制情況;
2)若當(dāng)前節(jié)點(diǎn)上不存在對應(yīng)的Docker鏡像,則向本地倉庫進(jìn)行鏡像的拉??;
3)創(chuàng)建容器對應(yīng)的工作目錄并生成容器必要的環(huán)境變量和參數(shù);
4)構(gòu)造Docker run container命令行所需的參數(shù)并調(diào)用Docker REST API來進(jìn)行容器的創(chuàng)建。
為了測試基于CPU負(fù)載的容器集群動(dòng)態(tài)伸縮功能,在本地部署了一套基于Docker容器的Web服務(wù),Web服務(wù)的后端通過Python實(shí)現(xiàn),其主要功能是在收到Web請求的時(shí)候進(jìn)行一系列的數(shù)值運(yùn)算,提高CPU的運(yùn)行頻率,從而模擬某些場景下的計(jì)算密集型服務(wù)。用戶的請求模擬主要通過一個(gè)Python腳本實(shí)現(xiàn),并通過Apache JMeter工具來實(shí)現(xiàn)并發(fā)從而提升容器集群的CPU負(fù)載。最終得到的CPU負(fù)載變化和對應(yīng)容器數(shù)量變化如圖8所示。
圖8 CPU負(fù)載及容器數(shù)量變化圖
從圖8可以看出,容器集群的確能夠隨著CPU負(fù)載的變化而動(dòng)態(tài)伸縮,但是具有一定的滯后性,容器集群在CPU負(fù)載升高后的第20s左右才會開始進(jìn)行擴(kuò)展,由于每次只擴(kuò)充1個(gè)容器,因此容器集群的擴(kuò)展速度也比較慢,與此同時(shí),容器集群的收縮也是在CPU負(fù)載降低后的第20s左右才會開始進(jìn)行。
為了測試基于網(wǎng)絡(luò)流量的容器集群動(dòng)態(tài)伸縮功能,在Web服務(wù)的基礎(chǔ)上編寫了一個(gè)Python腳本來實(shí)現(xiàn)文件的傳輸,然后在使用Apache JMeter工具進(jìn)行并發(fā)測試時(shí),同時(shí)往對應(yīng)的容器發(fā)送一個(gè)文件,從而模擬某些場景下的網(wǎng)絡(luò)密集型服務(wù),最后得到的網(wǎng)絡(luò)流量變化和對應(yīng)的容器數(shù)量變化如圖9所示。
圖9 網(wǎng)絡(luò)流量及容器數(shù)量變化圖
從圖9可以看出,容器集群的確能夠根據(jù)網(wǎng)絡(luò)流量的變化而進(jìn)行相應(yīng)的動(dòng)態(tài)伸縮,并且基于網(wǎng)絡(luò)流量的伸縮策略是預(yù)測型伸縮算法,因此會比基于閾值的響應(yīng)型伸縮算法的滯后時(shí)長短一些,容器集群在擴(kuò)展時(shí)的滯后時(shí)長大約為10s,同時(shí)預(yù)測型伸縮算法能夠確定即將到來的額外網(wǎng)絡(luò)流量,因此可以及時(shí)確定容器集群的擴(kuò)展數(shù)量,從而擴(kuò)展速度也比較快。
Docker作為一種新興的虛擬化技術(shù)正在打破傳統(tǒng)的以虛擬機(jī)為基礎(chǔ)的云平臺部署方式,本文正是通過使用Docker容器技術(shù)作為集群的底層虛擬化技術(shù),針對互聯(lián)網(wǎng)應(yīng)用場景中的不可預(yù)知負(fù)載,提出了一種基于混合負(fù)載的容器集群動(dòng)態(tài)伸縮方案,這一方案通過對不同的工作負(fù)載采用不同的容器集群伸縮策略從而實(shí)現(xiàn)業(yè)務(wù)的動(dòng)態(tài)伸縮,保證服務(wù)的穩(wěn)定性,文末通過設(shè)計(jì)兩種不同的工作負(fù)載場景對容器集群的伸縮功能進(jìn)行了測試,驗(yàn)證了這一方案的可行性。但是本方案也存在一定的不足之處,文中使用的二次指數(shù)平滑法在遇到網(wǎng)絡(luò)流量的突然大規(guī)模變化時(shí)預(yù)測結(jié)果會不太準(zhǔn)確,對于這種情況,后續(xù)可以使用如線性自回歸模型、機(jī)器學(xué)習(xí)等方法來進(jìn)行預(yù)測,提升預(yù)測的準(zhǔn)確率。