王小雪,王曉鋒,劉 淵
(江南大學人工智能與計算機學院,江蘇無錫 214122)
隨著互聯網技術的不斷發展和硬件設施的迭代更新,為滿足人們對數據處理能力、資源利用率、資源集中化的迫切需求,云計算[1]技術應運而生。OpenStack 是云計算基礎設施即服務(Infrastructure as a Service,IaaS)中重要的云計算管理平臺[2],具備開源性、兼容性、靈活性和可擴展性。OpenStack 默認以虛擬機為載體發布和交付服務應用,虛擬機由全虛擬化技術等傳統虛擬化技術生成,需要安裝完整的操作系統,會消耗大量資源與時間[3]。近年來,以Docker 容器為代表的操作系統級虛擬化技術因其輕量高效而備受關注[4]。容器相較于虛擬機具有更快的部署和銷毀速度、更好的服務性能以及更高的資源利用率等優點[5]。鑒于OpenStack 與Docker 的優勢,兩者的集成是云計算發展的必然,OpenStack可以為容器提供更加靈活、細粒度的管控,Docker 可以豐富OpenStack 生態系統,提高云平臺的資源利用率并優化云平臺的整體性能[6-7]。目前,OpenStack與Docker 的集成已廣泛應用于大數據分析[8]、網絡仿真[9]、云邊協同計算[10]等領域。
資源利用率的提高可以降低能耗并節約成本[11-12]。面向云計算領域的高資源利用率和低成本需求[13],設計高效的調度模型受到了學者們的廣泛關注。文獻[14]從CPU、內存、網絡帶寬和磁盤4 個維度出發,建立基于最小化數據中心能耗、最大化數據中心效用以及最小化服務器數量的多目標優化的虛擬機調度模型,能在降低能耗的同時提高數據中心效用。文獻[15]通過監控和預測虛擬機的資源使用,降低了物理機過載情況的發生,并通過虛擬機遷移與調度有效減少了運行的物理機數量,實現了云數據中心能耗的降低和資源利用率的提高。文獻[16]針對資源受限云系統中具有時間約束的用戶請求,提出一種時間敏感的資源分配和虛擬機調度方法,實現了多個異構節點之間的資源高效利用。文獻[17]基于OpenStack 云平臺,使用動態資源分配與節能算法,釋放了虛擬機占用的空閑資源,提高了云平臺的資源利用率并降低了系統能耗。以上文獻均是基于虛擬機對系統資源利用率提高問題進行研究。
在基于云計算的Docker 容器調度模型方面,學者們也進行大量研究并取得了一定的研究成果。文獻[3]將容器到虛擬機的部署問題轉化為容器集合與虛擬機集合之間的穩定匹配問題,并設計了相應的匹配規則,以實現通過容器提高云環境資源利用率并降低能耗,但該方案中虛擬機對容器的偏好規則僅考慮CPU 資源。文獻[18]以最大化設備資源利用率以及Docker 容器性能為目標,提出一種基于深度學習的容器調度方法,可自動為容器分配最優CPU 資源,但是該方法需要提前采集大量的訓練數據集進行建模,這會增加容器調度的實際應用難度。總體看來,當前基于云計算的Docker 容器調度研究較少,在資源利用率提升方面需做進一步研究。
鑒于OpenStack 與Docker 集成的優勢,如何有效調度Docker 容器以保障OpenStack 中資源的高效利用成為亟需解決的問題。Nova-Docker[19]采用OpenStack 中Nova 組件的調度模型,將容器作為虛擬機進行調度,首先使用過濾算法從OpenStack 的所有計算節點中選出滿足容器資源請求的節點作為候選節點,然后通過計算各個節點的權值為容器選擇最優計算節點。然而,與虛擬機不同,Docker 通過共享Linux 內核的方式來提供操作系統級別的虛擬化,將基于虛擬機的調度模型直接應用于Docker 具有不確定性[20]。Zun[21]作為Nova-Docker 的替代,在進行容器調度時隨機選取最優計算節點,未能考慮OpenStack中資源的合理利用。Yun[22]進一步對Nova-Docker 和Zun 的調度模型進行改進,針對容器的多樣化資源需求為容器選取最優計算節點,實現了OpenStack 中資源的合理利用。但是,以上3 種Docker 容器調度模型均基于用戶對容器的初始資源請求對容器進行調度并分配資源,未充分考慮容器運行時的實際資源使用情況。在多數情況下容器并不會以滿載的狀態運行,根據容器的初始資源請求對容器分配的資源在大部分時間內都是空閑的,這會導致嚴重的資源浪費[23]。
由于Yun不僅實現了OpenStack與Docker的集成,而且在部署效率、吞吐量、資源限制和兼容性方面均優于Nova-Docker 和Zun,因此本文基于Yun 設計并實現Docker 調度模型(Docker Scheduling Model,DSM)。該模型針對現有OpenStack 與Docker 集成方案采用的調度模型存在資源利用率不高的問題,設計資源可用度評估與優先級決策(Resource Availability-evaluation and Priority Decision-making,RAPD)調度機制對容器實施調度。
本文基于OpenStack 的Docker 調度模型如圖1所 示。DSM 通過與OpenStack 的Keystone、Glance以及Neutron 組件的API 進行交互,獲取創建容器所需的鏡像、網絡等資源;通過調用Docker Engine 提供的API 部署容器,實現對容器生命周期的高效靈活管控。DSM 主要包含初始化模塊、資源實時感知模塊、容器調度模塊、資源實時監測模塊和容器遷移模塊。

圖1 基于OpenStack 的Docker 調度模型Fig.1 Docker scheduling model based on OpenStack
初始化模塊負責接收用戶發送的創建容器所需的相關參數,詳細的用戶請求參數信息如表1 所示。通過對用戶請求參數進行解析,可以得到容器的基本配置參數(容器名稱、容器鏡像、容器初始運行命令、容器的網絡信息及容器的特權模式是否開啟)和容器的初始資源請求參數(CPU 請求規格和內存請求規格)。DSM 可基于容器的基本配置參數獲取創建容器所需的資源,容器的初始資源請求參數將作為容器資源請求參數,為容器調度模塊提供支持。

表1 用戶請求參數信息Table 1 User request parameter information
DSM 引入資源實時感知模塊,如圖2 所示。資源實時感知模塊負責采集OpenStack 中各個計算節點的資源信息,包括可用資源信息和資源利用率信息,并將各個計算節點的資源信息進行匯總。

圖2 資源實時感知模塊Fig.2 Real-time resource awareness module
資源實時感知模塊基于消息隊列實現對OpenStack 中計算節點資源信息的采集。消息隊列由消息中間件實現,基于高級消息隊列協議(Advanced Message Queuing Protocol,AMQP)開發。消息隊列的存在可以使消息發送方和消息接收方在時間、空間和同步等方面解耦,從而實現發送方和接收方消息的異步傳輸、數據流量緩沖和數據持久化[24]。基于AMQP 開發的消息隊列主要由消息發送方(Producer)、交換機(Exchange)、綁定(Binding)、隊列(Queue)和消息接收方(Consumer)構成。資源實時感知模塊的消息隊列設計如圖3 所示。資源實時感知模塊作為Consumer 監聽名為“dsm_awareness”的Queue,該Queue 以“dsm_resources_awareness”為binding key 與名為“dsm_resources”的Exchange 綁定。各個計算節點作為Producer 將routing key 為“dsm_resources_awareness”的消息(記錄了該計算節點的資源信息)發送至“dsm_resources”,“dsm_resources”會將該消息轉發至“dsm_awareness”進行保存,等待資源實時感知模塊從中獲取消息。

圖3 消息隊列設計Fig.3 Message queue design
同時,資源實時感知模塊會根據各個節點的資源利用率信息,計算該節點對應的負載,假設OpenStack 中所有計算節點的資源利用率為Ut=,t為資源的類型,m為計算節點的個數,Uti為第i個計算節點的資源t的利用率,則計算節點i的負載可通過式(1)計算得出:

其中:n為資源類型的數目;wt為用戶為資源t定義的優先級乘數,本文設置wcpu=wmemory=0.5,用戶可根據業務需求,通過配置文件修改wt值,使得某項資源的優先級高于其他資源。資源實時感知模塊通過匯總OpenStack 中各個計算節點的資源信息并計算各個節點的負載,為容器調度模塊提供支持。
容器調度模塊首先將容器的初始資源請求參數作為容器資源請求參數,并通過與資源實時感知模塊交互獲取OpenStack 中各個計算節點的資源信息以及負載信息,將三者作為容器調度依據;然后采用RAPD 調度機制對容器進行調度,通過資源可用度評估從所有計算節點中選出滿足容器資源請求規格的節點作為候選節點,并利用優先級決策從所有候選節點中為容器選擇最優計算節點,調用Docker Engine 提供的API 部署容器。
在容器部署成功后,資源實時監測模塊會獲取容器的實際資源使用參數,容器調度模塊將該參數作為容器資源請求參數,對容器實施重新調度,為其選取新的最優計算節點。將容器當前所在的計算節點記為源節點,將對容器重新調度后選取的最優計算節點記為目的節點,如果源節點和目的節點相同,則在不停止容器運行的情況下通過調用Docker Engine 提供的API 更新容器的資源規格為其實際資源使用規格,釋放容器占用的空閑資源,否則需要對容器執行遷移操作。
在容器部署成功后,資源實時監測模塊通過Docker 自身提供的“docker stats”命令實時獲取容器的資源使用信息。由于容器內服務的工作負載隨時間動態變化會呈現不同的資源需求[25],因此需要設定一個長時間間隔(本文設置為1 h,用戶可根據業務需求,通過配置文件自定義該時間間隔),資源實時監測模塊采集該時間間隔內容器的各項資源使用信息,最終各項資源數值的抖動分別穩定在一個固定區間內,資源實時監測模塊將每個區間的峰值作為容器對應資源的實際使用參數,并將容器的實際資源使用參數作為容器的資源請求參數,為容器調度模塊提供支持。
如果容器當前所在的計算節點(源節點)與對容器重新調度后選取的最優計算節點(目的節點)不一致,則需要觸發容器遷移模塊。該模塊負責將容器從源節點遷移到目的節點,保證遷移前后容器的基本配置、文件系統[26]、內存狀態和網絡環境的一致性。容器遷移的執行流程如圖4 所示。首先,源節點與目的節點建立連接,發送當前待遷移容器的基本配置信息,目的節點基于此信息,調用Docker Engine 提供的API 創建一個與源節點相同配置的容器。然后,在源節點上對容器設置檢查點,并向目的節點依次發送容器的文件系統和內存狀態信息,目的節點依次接收容器的文件系統數據和內存狀態信息文件,并恢復容器的運行。最后,目的節點在恢復容器的網絡環境后,會斷開與源節點的連接,至此,容器遷移實施完成。

圖4 容器遷移執行流程Fig.4 Execution flow of container migration
DSM 采用RAPD 調度機制對Docker 容器實施調度,該機制主要包含兩個階段:1)通過資源可用度評估階段對OpenStack 中所有的計算節點進行評估,選擇可滿足容器資源請求規格的計算節點作為候選節點;2)通過優先級決策階段從所有的候選節點中選擇優先級最高的計算節點作為最優計算節點。
該階段負責從OpenStack 的各個計算節點中找出滿足容器資源請求規格的節點作為候選節點。在該階段設計了CPU 評估器(CPUEvaluator)、內存評估器(MemoryEvaluator)、負載評估器(LoadEvaluator)這3 個評估器,分別根據計算節點的可用CPU、可用內存和負載評估其是否可以作為候選節點。資源可用度評估算法如算法1 所示。算法的輸入是所有的評估器(evaluators),待評估計算節點的對象(host,記錄了計算節點的CPU、內存、資源利用率和負載等信息)以及容器的資源請求規格(specifications),算法的輸出是一個布爾值(o),用于表征當前計算節點是否通過了所有的評估器成為了候選節點。
算法1資源可用度評估算法

DSM 基于Yun 實現,可以對容器CPU、內存使用量進行精確的限制,因此針對CPU 和內存資源,對應的CPU 評估器和內存評估器以計算節點的邏輯資源剩余量作為評估標準。如果容器的資源請求規格r大于計算節點相應資源的邏輯剩余量R,該計算節點將會被直接過濾。負載評估器會將當前計算節點的負載與設定的負載閾值(本文定義為70%)進行比較,如果節點的負載超過閾值,則將會被直接過濾。負載評估器的存在可以有效避免節點過載導致的系統響應時間變慢以及性能下降等問題。最終,通過所有評估器的計算節點將會作為候選節點,進入優先級決策階段。
在優先級決策階段設計了CPU 決策器(CPUMaker)和內存決策器(MemoryMaker)兩個決策器,分別根據每個候選計算節點的CPU 利用率和內存利用率決策該節點的優先級。將計算節點i的CPU 利用率用表示,值可以通過調用psutil[27]模塊的cpu_percent()函數獲得。計算節點i的“/proc/meminfo”文件中記錄了其總內存以及可用內存信息,分別記為,則計算節點i的內存利用率可通過式(2)計算:

為防止計算節點某項資源的利用率低而優先級高,使用Yun 的資源優先級系數自適應策略[22],默認每項資源的優先級系數為1.0,如果某項資源的利用率超過50%,則調整其優先級系數為1/2,如果利用率超過70%,則調整其優先級系數為1/4,如果利用率超過80%,則調整其優先級系數為1/8,通過實時感知當前計算節點的資源利用率,并動態調整相應資源的優先級系數,實現更均衡的資源利用,以提高計算節點的資源利用率。將計算節點i的優先級轉換為計算節點i的得分并使用式(3)表示:

其中:t為資源的類型;n為資源類型的數目;wt為用戶為資源t定義的優先級乘數;為計算節點i的資源t的優先級系數;為計算節點i的資源t的利用率;m為候選計算節點的個數。si越大的計算節點優先級越高,決策階段的目標是從候選節點中找出使si最大的計算節點i作為最優計算節點,如算法2 所示,算法的輸入是所有的決策器(makers)以及所有候選計算節點的對象(hosts),算法的輸出是一個列表(S),用于記錄所有候選計算節點的得分。
算法2優先級決策算法


為分析并驗證DSM 性能進行以下實驗:1)分析DSM 如何通過實時監測容器的資源使用確定容器的實際資源使用參數;2)采用Nova-Docker、Yun 和DSM 部署固定數量的容器,以驗證DSM 相比于Nova-Docker 和Yun 可以實現資源的高效利用;3)測試Nova-Docker、Yun 和DSM可以部署的容器數量的上限以及OpenStack 中各個計算節點的資源利用率的上限,以驗證DSM 相比于Nova-Docker 和Yun可以有效提升OpenStack 中計算節點的資源利用率。
基于OpenStack Mitaka 構建實驗環境,包含1 個控制節點和3 個Docker 計算節點。控制節點的操作系統為CentOS 7.2,各個計算節點的操作系統為CentOS 7.8,Docker 版本為17.06.0-ce。每個計算節點的資源總量信息如表2 所示。需要說明的是,由于Zun 在兼容性方面不支持OpenStack Mitaka,因此在此未將Zun 作為比較對象。

表2 Docker 計算節點信息Table 2 Docker compute node information
同時,引入3 種負載型容器和3 種應用型容器對DSM 進行驗證分析,每種容器的資源請求規格及工作負載如表3 所示。負載型容器使用Linux 壓力測試工具生成不同的容器系統CPU 和內存負載,容器會不斷地釋放并重新申請分配資源,以此模擬容器的資源使用隨時間動態變化的情況。應用型容器內運行不同的應用程序,每種應用程序都會產生資源消耗。

表3 容器資源規格及工作負載Table 3 Resource specifications and workloads of the containers
DSM 資源實時監測模塊通過監測容器在固定時間間隔(本文設置為1 h)內的各項資源使用信息,確定容器對應資源的實際使用參數,作為容器重新調度的依據。該實驗使用DSM 部署表3 中的1 個負載型容器(1 個工作進程,2 048 MB 內存)和1 個應用型容器(安裝RabbitMQ,發送和接收消息),分析DSM 如何通過實時監測容器的資源使用確定容器的實際資源使用參數。
圖5 給出了DSM 監測到的負載型容器的資源使用信息。在圖5(a)中,橫坐標表示采集輪次,以10 s為1 個間隔,共有360 個輪次,縱坐標代表容器的CPU 利用率,可以看出該容器的CPU 利用率的峰值為104%,DSM 會基于此信息確定該容器的實際CPU使用參數為1;在圖5(b)中,容器的內存使用量的峰值為2 053 MB,DSM 會基于此信息確定該容器的實際內存使用參數為2 053。DSM 監測到的應用型容器的資源使用信息如圖6 所示。在圖6(a)中,該容器的CPU 利用率的峰值為304%,DSM 會基于此信息確定該容器的實際CPU 使用參數為3;在圖6(b)中,容器的內存使用量的峰值為119 MB,DSM 會基于此信息確定該容器的實際內存使用參數為119。

圖5 負載型容器的資源使用信息Fig.5 Resource usage information of load-type container

圖6 應用型容器的資源使用信息Fig.6 Resource usage information of application-type container
DSM 采用RAPD 調度機制對容器進行調度,以提高OpenStack 中計算節點的資源利用率,該實驗分別采用Nova-Docker、Yun 和DSM 部署容器,通過比較部署后實驗環境中各個計算節點的資源利用率情況,以驗證本文提出的調度模型相比于其他兩種調度模型可以實現資源的高效利用。首先分別采用Nova-Docker、Yun 和DSM在實驗環境中的3 個Docker 計算節點上各進行一組測試,每組測試分別部署9 個負載型容器,涵蓋負載型容器下的所有容器。然后分別統計每組測試中3 個計算節點的容器數量、CPU 利用率和內存利用率,結果如圖7 所示。

圖7 負載型容器的資源利用率測試結果Fig.7 Resource utilization test results of load-type containers
由圖7 可以看出,Nova-Docker 和Yun 采用基于容器初始資源請求的調度模型對容器進行調度與部署,實驗環境中的3 個計算節點均部署了容器并有一定的資源消耗,而DSM 采用RAPD 調度機制,所有的負載型容器最終均部署于計算節點3,該計算節點的資源利用率最高。換言之,在調度完成后,Nova-Docker 和Yun 需要同時開啟3 個計算節點以支持9 個容器的運行,且容器會占用大量的空閑資源使其無法釋放,造成資源的嚴重浪費,而DSM 只需要開啟1 個計算節點便可以支持所有容器的運行,實現了資源的高效利用。
同樣地,首先分別采用Nova-Docker、Yun 和DSM 在實驗環境中的3 個Docker 計算節點上各進行一組測試,每組測試分別部署9 個應用型容器,涵蓋應用型容器下的所有容器。然后分別統計每組測試中3 個計算節點的容器數量、CPU 利用率和內存利用率,結果如圖8 所示。由圖8 可以看出,應用型容器的部署情況同負載型容器類似,相比于Nova-Docker 和Yun,DSM 將所有的應用型容器均調度至計算節點3,該節點的資源利用率最高。

圖8 應用型容器的資源利用率測試結果Fig.8 Resource utilization test results of application-type containers
Nova-Docker 和Yun 根據容器的初始資源請求對容器調度,未充分考慮容器運行時的實際資源使用情況,如果容器的資源使用量很小或長期未使用某項資源,則節點的資源利用率將會很低,且空閑的資源無法得到釋放。DSM 根據容器運行時的實際資源使用對容器進行重新調度,釋放了容器占用的空閑資源,并提高了計算節點的資源利用率。該實驗分別基于Nova-Docker、Yun 和DSM 部 署3.1 節中引 入的3 種負載型容器,測試Nova-Docker、Yun 和DSM 可以部署的容器數量的上限以及實驗環境中各個計算節點的資源利用率上限,實驗結果如圖9 所示。

圖9 最大容器部署數量下的資源利用率測試結果Fig.9 Resource utilization test results for the maximum deployment number of containers
由圖9 可以看出,相比于Nova-Docker 和Yun,DSM 部署了最多數量的容器,且各個計算節點的CPU 利用率和內存利用率均有顯著提升,實現了資源的高效利用。在CPU 利用率方面,相比于Nova-Docker 和Yun,DSM 在節點1的CPU利用率提升最多,分別提升了42.68 和46.89 個百分點,在節點2 的CPU 利用率提升最少,分別提升了38.54 和30.17 個百分點;在內存利用率方面,相比于Nova-Docker 和Yun,DSM 在節點2 的內存利用率提升最多,分別提升了53.01 和53.33 個百分點,在節點1 的內存利用率提升最少,分別提升了38.40 和28.69 個百分點。
為滿足云計算領域的高資源利用率需求及利用OpenStack 與Docker 集成的優勢,本文設計并實現基于OpenStack 的Docker 調度模型,并通過實驗驗證了相比于經典的Nova-Docker、Yun 集成方案采用的調度模型,該模型在CPU 利用率和內存利用率上具有明顯優勢。考慮到云計算環境中容器的多樣化資源需求,下一步將加入磁盤、網絡帶寬等資源作為Docker 容器調度依據,同時針對容器的差異化資源需求,為容器設置專有資源權重,優化容器調度機制,并將對某種資源需求較多的容器調度至資源相對充分的計算節點,在實現OpenStack 中計算節點資源負載均衡的同時提高資源利用率。