解析使用 Mesos 管理虛擬機

摘要

為了滿足渲染、基因測序等計算密集型服務(wù)的需求,UCloud 已推出了“計算工廠”產(chǎn)品,讓用戶可以快速創(chuàng)建大量的計算資源(虛擬機)。該產(chǎn)品的背后,是一套基于 Mesos 的計算資源管理系統(tǒng)。本文主要介紹該系統(tǒng)的結(jié)構(gòu)、Mesos 在 UCloud 的使用、我們的解決方案以及遇到的問題。

業(yè)務(wù)需求

我們的需求主要是兩個方面:

1. 同時支持虛擬機和容器。在“容器化”的浪潮下,為什么我們還需要支持虛擬機呢?首先,一些業(yè)務(wù)有嚴格的安全隔離要求,容器雖好,但還做不到和虛擬機同等級的隔離性。其次,一些業(yè)務(wù)程序不能運行在 Linux 上,比如圖片、動畫的渲染軟件大都是 Windows 程序。

2. 整合多地域多數(shù)據(jù)中心。我們的資源來源于一些擁有閑置資源的合作伙伴,這些資源散布于多個地域的多個數(shù)據(jù)中心中。我們的平臺需要能夠支持全局的調(diào)度,同時盡可能減小運營、運維的成本。

簡單地說,我們需要有一個平臺,統(tǒng)一封裝多個數(shù)據(jù)中心的計算資源,并且同時支持虛擬機、容器等多種形式的資源使用方式。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖1:計算資源管理平臺的需求示意圖

說到虛擬機,首先想到的就是 UCloud 自己的 UHost 和開源的 OpenStack,然而,這兩套系統(tǒng)都是針對大型公有云的場景,而且主要只針對于虛擬機這一種業(yè)務(wù)。它們功能豐富、模塊眾多,運維運營上都需要很大的成本。然而我們的業(yè)務(wù)并不需要這么多功能。

最終,我們選擇了基于 Mesos 來實現(xiàn)這套平臺。

為什么選擇 Mesos

Mesos是Apache下的開源分布式資源管理框架,它是一個分布式系統(tǒng)的內(nèi)核。

通過 Mesos,一個數(shù)據(jù)中心所提供的不再是一臺臺服務(wù)器,而是一份份的資源。資源可以是 CPU 核數(shù)、內(nèi)存、存儲、GPU 等等。如果把一個數(shù)據(jù)中心當做一個操作系統(tǒng)的話,Mesos 就是這個操作系統(tǒng)的內(nèi)核。

我們選擇 Mesos 的原因在于它擁有高度可擴展性,同時又足夠簡單。

作為內(nèi)核,Mesos 只提供最基礎(chǔ)的功能:資源管理、任務(wù)管理、調(diào)度等。并且每一種功能,都以模塊的方式實現(xiàn),方便進行定制。架構(gòu)上,Master 和 Agent 兩個模塊就實現(xiàn)了資源相關(guān)的所有工作,用戶只需根據(jù)自己的業(yè)務(wù)邏輯實現(xiàn) Framework 和 Executor 即可。這樣就支持我們能夠把計算資源封裝成虛擬機、容器等各種形式。

采用 Mesos 來進行容器編排的方案已經(jīng)被很多廠商使用,相關(guān)的資料文檔也比較豐富。然而用 Mesos 來管理虛擬機,業(yè)內(nèi)并沒有應(yīng)用于生產(chǎn)環(huán)境的實踐。本文的余下內(nèi)容,主要向讀者分享一下 UCloud 用 Mesos 管理虛擬機的思路和實踐經(jīng)驗。

Mesos 簡介

Mesos 采用 Master-Agent 架構(gòu)。Master 負責整體資源的調(diào)度并對外提供 API。Agent 部署在所有機器上,負責調(diào)用 Executor 執(zhí)行任務(wù)、向 Master 匯報狀態(tài)等。

Mesos 提供了一個雙層調(diào)度模型:

1. Master 在 Framework 之間進行資源調(diào)度;

2. 每個 Framework 內(nèi)部實現(xiàn)各自業(yè)務(wù)的資源調(diào)度。

整體架構(gòu)如下圖:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖2:Mesos 的雙層調(diào)度結(jié)構(gòu)圖

架構(gòu)設(shè)計

整體架構(gòu)

在 Mesos 的雙層調(diào)度模型上,平臺的整體架構(gòu)如下圖:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖3:基于Mesos的資源管理平臺整體架構(gòu)圖

結(jié)構(gòu)如下:

1. 每個 IDC 一套或多套 Mesos 集群;

2. 每個 Mesos 集群一個 Cluster Server,與 Mesos Master 以及 Framework 交互,負責集群內(nèi)部的調(diào)度、狀態(tài)收集和任務(wù)下發(fā);

3. 一個Mesos集群上有多個Framework,一個 Framework 負責一種業(yè)務(wù),比如 VM Scheduler 管理虛擬機,Marathon Framework 管理Docker任務(wù);

4. VM Framework框架實現(xiàn)管理的 Excutor 是基于Libvirt,實現(xiàn)虛擬機的創(chuàng)建、重啟、刪除等操作;

5. 所有 Cluster Server 統(tǒng)一向 API Server 匯報,上報狀態(tài)、獲取任務(wù);

6. API Server 負責主要業(yè)務(wù)邏輯,以及集群間的調(diào)度、資源和任務(wù)的管理等等;

7. API Gateway 提供 API 給 UCloud 控制臺(Console)。

基于 HTTP 的通信

系統(tǒng)內(nèi)的所有通信都基于 HTTP。

首先,Mesos 內(nèi)部基于 libprocess 各組件之間的通信都依賴 libprocess 庫,該庫用 C++ 實現(xiàn)了 Actor 模式。每個 Actor 會監(jiān)聽 HTTP 請求,向 Actor 發(fā)消息的過程就是把消息體序列化后放在 HTTP 報文中,然后請求這個 Actor。

其次,業(yè)務(wù)相關(guān)的各個組件API Server、Cluster Server 等也都通過 Restful 的 API 提供服務(wù)。

HTTP 的優(yōu)點在于簡單可靠、易于開發(fā)調(diào)試和擴展。

VM Scheduler

對于 Docker 容器,我們采用 Marathon Framework 進行管理。而對于虛擬機,我們則采用自己開發(fā)的 VM Scheduler Framework 。

VM Scheduler 從 Master 獲取一個個的資源 Offer 。一個資源 Offer 包含了某個 Agent 上可用的資源。當有虛擬機任務(wù)需要執(zhí)行的時候,Cluster Server 會把任務(wù)的具體信息發(fā)送給 VM Scheduler。

任務(wù)分為兩類:

1. 創(chuàng)建/刪除一個虛擬機。此時需要傳入虛擬機的配置信息、包括鏡像、網(wǎng)絡(luò)、存儲等。VM Scheduler 根據(jù)這些信息,匹配滿足要求的 Resource Offer,然后生成 Task 提交給 Mesos Master 去執(zhí)行。

2. 操作一個虛擬機,如開關(guān)機、重啟、鏡像制作等。此時 VM Scheduler 會和 VM Executor 通過 Framework Message 通信,告訴后者去執(zhí)行具體的操作。

VM Executor

Task 是 Mesos 中資源分配的最小單位。Master 會告訴 Agent 需要執(zhí)行哪些 Task,Agent 也會把 Task 的狀態(tài)匯報給 Master。根據(jù) Task 的信息,Agent 會下載并啟動所需的 Executor,然后把具體的 Task 描述傳給它。

VM Executor 是我們開發(fā)的對虛擬機的生命周期進行管理的 Executor,實現(xiàn)了對虛擬機創(chuàng)建、刪除、開關(guān)機、鏡像制作等功能。

VM Executor 啟動后,根據(jù) Task 的描述,動態(tài)生成虛擬機需要的配置文件,然后調(diào)用 libvirt 進行虛擬機創(chuàng)建。當收到來自 VM Scheduler 的 Framework Message 時,又調(diào)用 libvirt 進行開關(guān)機等操作。

狀態(tài)的管理是實現(xiàn)虛擬機管理的關(guān)鍵部分。通過 Mesos 我們只能拿到 Task 的狀態(tài),RUNING 表示虛擬機創(chuàng)建成功,F(xiàn)AILED 表示虛擬機失敗,F(xiàn)INISHED 表示虛擬機成功銷毀。然而除此之外,一個虛擬機還存在“開機中”、“關(guān)機中”、“關(guān)機”、“鏡像制作中”等其他狀態(tài)。我們通過在 VM Executor 和 VM Scheduler 之間進行心跳,把這些狀態(tài)同步給 VM Scheduler。后者對狀態(tài)進行判斷,如果發(fā)現(xiàn)狀態(tài)改變了,就發(fā)送一條狀態(tài)更新的消息給 Cluster Server,然后再轉(zhuǎn)發(fā)給 API Server,最終更新到數(shù)據(jù)庫。

虛擬機的調(diào)度

首先看一下一個 Task 在 Mesos 中是怎么調(diào)度的:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖4:Mesos 資源調(diào)度過程示意圖

上面的示例中:

1. Agent 向 Master 匯報自己所擁有的資源;

2. Master 根據(jù) Dominant Resource Fairness(DRF) 調(diào)度算法,把這份資源作為一個 Resource Offer 提供給 Framework 1;

3. Framework 1 根據(jù)自己的業(yè)務(wù)邏輯,告訴 Master 它準備用這份資源啟動兩個 Task;

4. Master 通知 Agent 啟動這兩個 Task。

對應(yīng)到虛擬機的情況,調(diào)度分兩個部分:

1. 選擇集群。默認情況下,API Server 根據(jù)資源需求,從注冊上來的集群中選擇一個擁足夠資源的集群,然后把資源需求分配給該集群。另外,還可以針對不同的公司、項目等維度制定在某個集群運行;

2. 集群內(nèi)調(diào)度。Cluster Server 從 API Server 處獲取到資源需求,比如說需要 200 個核,于是根據(jù) Mesos 當前資源使用情況,創(chuàng)建出一個“資源計劃”,200個核被分配為4個48核虛擬機和1個8核虛擬機。然后通知 Framework 按照這份計劃來創(chuàng)建5個Task。

資源的標識

服務(wù)器之間除了 CPU、內(nèi)存、硬盤等可能不同外,還會存在其他的差別。比如有時候業(yè)務(wù)要求一定要用某個型號的 CPU,有時候要求一定要擁有 SSD等等。為了支持更多維度的調(diào)度,我們利用了 Mesos 的 Resource 和 Attribute 來標識不同的資源。

Resource是 Mesos 中的一個概念,表示一切用戶需要使用的東西。Agent 默認會自動添加 cpus、gpus、mem、ports 和 disk 這5種資源。另外還可以在 Agent 啟動時,通過參數(shù)指定其他資源。

Attribute 以 Key-Value 形式的標簽,標識一個 Agent 擁有的屬性,同樣可以在啟動時通過參數(shù)指定。

通過 Resource 和 Attribute 的靈活運用,可以標識出更多的資源情況,滿足各種資源調(diào)度需求。比如通過 Resource 指定 SSD 大小、CPU型號,通過 Attribute 標識機架位、是否擁有外網(wǎng) IP,是否支持超線程等等。Framework 收到一個 Resource Offer 后,與待執(zhí)行的任務(wù)需求進行匹配,通過 Resource 判斷資源是否夠用,再通過 Attribute 判斷是否滿足其他維度的需求,最終決定是否用這個 Offer 來創(chuàng)建 Task。

鏡像、存儲和網(wǎng)絡(luò)管理

平臺提供了一些基礎(chǔ)鏡像,另外用戶也可以基于自己的虛擬機創(chuàng)建自己的鏡像。這些鏡像文件統(tǒng)一存儲在一個基于 GlusterFS 的分部署存儲服務(wù)中,該服務(wù)掛載在每臺物理機上。

有些業(yè)務(wù)場景需要部分虛擬機能夠共享同一份存儲,于是我們還是基于 GlusterFS 開發(fā)了用戶存儲服務(wù),能夠根據(jù)用戶的配置,在虛擬機創(chuàng)建時自動掛載好。

在網(wǎng)絡(luò)方面,每個用戶可以創(chuàng)建多個子網(wǎng),各個子網(wǎng)之間做了網(wǎng)絡(luò)隔離。創(chuàng)建虛擬機時,需要指定使用哪個子網(wǎng)。

其他問題

在使用 Mesos 的過程中,我們也遇到了其他一些問題。

問題一:Marathon選主異常

當機器負載比較高,尤其是 IO 較高時,我們發(fā)現(xiàn) Marathon 集群有概率出現(xiàn)不能選主的情況。

我們懷疑是由于 Marathon 節(jié)點和 ZK 的網(wǎng)絡(luò)不穩(wěn)定,觸發(fā)了 Marathon 或 Mesos 的 Bug導(dǎo)致。于是通過 iptables 主動屏蔽 Leader ZK 端口的方式,成功復(fù)現(xiàn)出問題。

通過在 Marathon 的代碼中加上一些 Leader 選舉相關(guān)的最終日志,成功定位到了問題,原來是由于 Mesos Driver 的 stop() 方法沒有成功引起 start() 方法退出阻塞導(dǎo)致。

由于我們的所有程序都是通過守護進程啟動的,所以我們采用了一個最簡單的解決方案:修改 Marathon 代碼,當 ZK 發(fā)生異常時,直接自殺。自殺后守護進程會把程序再啟動起來。

問題二:go-marathon問題

我們的服務(wù)采用 Golang 開發(fā),使用 go-marathon 庫與 Marathon 進行交互。使用過程中發(fā)現(xiàn)該庫有一些問題:

不支持多 Marathon 節(jié)點。于是我們自己創(chuàng)建了一個分支,采用節(jié)點主動探測的方式,實現(xiàn)了多節(jié)點的支持。(原庫 v5.0 版本以后也支持了該功能)

使用設(shè)有 Timeout 的 http.Client 進行 go-marathon 的初始化時,訂閱 SSE 會產(chǎn)生超時問題。于是我們做了修改,普通的 HTTP API 和 SSE 不使用同一個 http.Client,操作 SSE 的 http.Client 不設(shè)置 Timeout。

網(wǎng)絡(luò)異常時,go-marathon 的方法調(diào)用會 Hang 住。于是我們所有對 go-marathon 方法的調(diào)用都加上超時控制。

結(jié)語

Mesos 在 UCloud 有著廣泛的應(yīng)用,對外有“計算工廠”和 UDocker 等產(chǎn)品,對內(nèi)則支撐著公司內(nèi)網(wǎng)虛擬機管理平臺。伴隨著持續(xù)的實踐,我們對 Mesos 的理解和掌控也越來越深入。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容