使用 Mesos 管理虛擬機

摘要

爲了知足渲染、基因測序等計算密集型服務的需求,UCloud 推出了「計算工廠」產品,讓用戶能夠快速建立大量的計算資源(虛擬機)。該產品的背後,是一套基於 Mesos 的計算資源管理系統。本文簡要介紹該系統的結構、Mesos 在 UCloud 的使用、咱們的解決方案以及遇到的問題。算法

業務需求

咱們的需求主要是兩方面:數據庫

  1. 同時支持虛擬機和容器。在「容器化」的浪潮下,爲何咱們還須要支持虛擬機呢?首先,一些業務有嚴格的安全隔離要求,容器雖好,但還作不到和虛擬機同等級的隔離性。其次,一些業務程序不能運行在 Linux 上,好比圖片、動畫的渲染軟件大都是 Windows 程序。
  2. 整合多地域多數據中心。咱們的資源來源於一些擁有閒置資源的合做夥伴,這些資源散佈於多個地域的多個數據中心中。咱們的平臺須要可以支持全局的調度,同時儘量減少運營、運維的成本。

簡單地說,咱們須要有一個平臺,統一封裝多個數據中心的計算資源,而且同時支持虛擬機、容器等多種形式的資源使用方式。安全

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

說到虛擬機,首先想到的就是 UCloud 本身的 UHost 和開源的 OpenStack,然而,這兩套系統都是針對大型公有云的場景,並且主要只針對於虛擬機這一種業務。它們功能豐富、模塊衆多,運維運營上都須要很大的成本。然而咱們的業務並不須要這麼多功能。網絡

最終,咱們選擇基於 Mesos 來實現這套平臺。架構

爲何選擇 Mesos

Mesos是Apache下的開源分佈式資源管理框架,它是一個分佈式系統的內核。框架

經過 Mesos,一個數據中心所提供的再也不是一臺臺服務器,而是一份份的資源。資源能夠是 CPU 核數、內存、存儲、GPU 等等。若是把一個數據中心當作一個操做系統的話,Mesos 就是這個操做系統的內核。運維

咱們選擇 Mesos 的緣由在於它擁有高度可擴展性,同時又足夠簡單。分佈式

做爲內核,Mesos 只提供最基礎的功能:資源管理、任務管理、調度等。而且每一種功能,都以模塊的方式實現,方便進行定製。架構上,Master 和 Agent 兩個模塊就實現了資源相關的全部工做,用戶只需根據本身的業務邏輯實現 Framework 和 Executor 便可。這樣就支持咱們可以把計算資源封裝成虛擬機、容器等各類形式。動畫

採用 Mesos 來進行容器編排的方案已經被不少廠商使用,相關的資料文檔也比較豐富。然而用 Mesos 來管理虛擬機,業內並無應用於生產環境的實踐。本文的餘下內容,主要向讀者分享一下 UCloud 用 Mesos 管理虛擬機的思路和實踐經驗。

Mesos 簡介

Mesos 採用 Master-Agent 架構。Master 負責總體資源的調度並對外提供 API。Agent 部署在全部機器上,負責調用 Executor 執行任務、向 Master 彙報狀態等。

Mesos 提供了一個雙層調度模型:

  1. Master 在 Framework 之間進行資源調度。
  2. 每一個 Framework 內部實現各自業務的資源調度。

總體架構以下圖:


圖2:Mesos 的雙層調度結構圖

架構設計

總體架構

在 Mesos 的雙層調度模型上,平臺的總體架構以下圖:

圖3:基於Mesos的資源管理平臺總體架構圖

結構以下:

  1. 每一個 IDC 一套或多套 Mesos 集羣;
  2. 每一個 Mesos 集羣一個 Cluster Server,與 Mesos Master 以及 Framework 交互,負責集羣內部的調度、狀態收集和任務下發
  3. 一個Mesos集羣上有多個Framework,一個 Framework 負責一種業務,好比 VM Scheduler 管理虛擬機,Marathon Framework 管理Docker任務
  4. VM Framework框架實現管理的 Excutor 基於Libvirt,實現虛擬機的建立,重啓,刪除等操做
  5. 全部 Cluster Server 統一貫 API Server 彙報,上報狀態、獲取任務
  6. API Server 負責主要業務邏輯,以及集羣間的調度、資源和任務的管理等等
  7. API Gateway 提供 API 給 UCloud 控制檯(Console)

基於 HTTP 的通訊

系統內的全部通訊都基於 HTTP。

首先,Mesos 內部基於 libprocess  各組件之間的通訊都都依賴 libprocess 庫,該庫用 C++ 實現了 Actor 模式。每一個 Actor 會監聽 HTTP 請求,向 Actor 發消息的過程就是把消息體序列化後放在 HTTP 報文中,而後請求這個 Actor。

其次,業務相關的各個組件,API Server、Cluster Server 等也都經過 Restful 的 API 提供服務。

HTTP 的優勢在於簡單可靠、易於開發調試和擴展。

VM Scheduler

對於 Docker 容器,咱們採用 Marathon Framework 進行管理。而對於虛擬機,咱們則採用本身開發的 VM Scheduler Framework 。

VM Scheduler 從 Master 獲取一個個的資源 offer 。一個資源 offer 包含了某個 Agent 上可用的資源。當有虛擬機任務須要執行是,Cluster Server 會把任務的具體信息發送給 VM Scheduler。

任務分爲兩類:

  1. 建立/刪除一個虛擬機。此時須要傳入虛擬機的配置信息、包括鏡像、網絡、存儲等。VM Scheduler 根據這些信息,匹配知足要求的 Resource Offer,而後生成 Task 提交給 Mesos Master 去執行。
  2. 操做一個虛擬機,如開關機、重啓、鏡像製做等。此時 VM Scheduler 會和 VM Executor 經過 Framework Message 通訊,告訴後者去執行具體的操做。

VM Executor

Task 是 Mesos 中資源分配的最小單位。Master 會告訴 Agent 須要執行哪些 Task,Agent 也會把 Task 的狀態彙報給 Master。根據 Task 的信息,Agent 會下載並啓動所需的 Executor,而後把具體的 Task 描述傳給它。

VM Executor 是咱們開發的對虛擬機的生命週期進行管理的 Executor,實現了對虛擬機建立、刪除、開關機、鏡像製做等功能。

VM Executor 啓動後,根據 Task 的描述,動態生成虛擬機須要的配置文件,而後調用 libvirt 進行虛擬機建立。當收到來自 VM Scheduler 的 Framework Message 時,又調用 libvirt 進行開關機等操做。

狀態的管理是實現虛擬機管理的關鍵部分。經過 Mesos 咱們只能拿到 Task 的狀態,RUNING 表示虛擬機建立成功,FAILED 表示虛擬機失敗,FINISHED 表示虛擬機成功銷燬。然而除此以外,一個虛擬機還存在「開機中」、「關機中」、「關機」、「鏡像製做中」等其餘狀態。咱們經過在 VM Executor 和 VM Scheduler 之間進行心跳,把這些狀態同步給 VM Scheduler。後者對狀態進行判斷,若是發現狀態改變了,就發送一條狀態更新的消息給 Cluster Server,而後再轉發給 API  Server,最終更新到數據庫。

虛擬機的調度

首先看一下一個 Task 在 Mesos 中是怎麼調度的:



圖4:Mesos 資源調度過程示意圖

上面的示例中:

  1. Agent 向 Master 彙報本身所擁有的資源
  2. Master 根據 Dominant Resource Fairness(DRF) 調度算法,把這份資源做爲一個 resource offer 提供給 Framework 1
  3. Framework 1 根據本身的業務邏輯,告訴 Master 它準備用這份資源啓動兩個 Task
  4. Master 通知 Agent 啓動這兩個 Task

對應到虛擬機的狀況,調度分兩個部分:

  1. 選擇集羣。默認狀況下,API Server 根據資源需求,從註冊上來的集羣中選擇一個擁足夠資源的集羣,而後把資源需求分配給該集羣。另外,還能夠針對不一樣的公司、項目等維度制定在某個集羣運行;
  2. 集羣內調度。Cluster Server 從 API Server 處獲取到資源需求,好比說須要 200 個核,因而根據 Mesos 當前資源使用狀況,建立出一個「資源計劃」,200個核被分配爲4個48核虛擬機和1個8核虛擬機。而後通知 Framework 按照這份計劃來建立5個Task。

資源的標識

服務器之間除了 CPU、內存、硬盤等可能不一樣外,還會存在其餘的差異。好比有時候業務要求必定要用某個型號的 CPU,有時候要求必定要擁有 SSD等等。爲了支持更多維度的調度,咱們利用了 Mesos 的 Resource 和 Attribute 來標識不一樣的資源。

Resource是 Mesos 中的一個概念,表示一切用戶須要使用的東西。Agent 默認會自動添加 cpus, gpus, mem, ports 和 disk 這5種資源。另外還能夠在 Agent 啓動時,經過參數指定其餘資源。

Attribute 以 Key-Value 形式的標籤,標識一個 Agent 擁有的屬性,一樣能夠在啓動時經過參數指定。

經過 Resource 和 Attribute 的靈活運用,能夠標識出更多的資源狀況,知足各類資源調度需求。好比經過 Resource 指定 SSD 大小、CPU型號,經過 Attribute 標識機架位、是否擁有外網 IP,是否支持超線程等等。Framework 收到一個 resource offer 後,與待執行的任務需求進行匹配,經過 resource 判斷資源是否夠用,再經過 Attribute 判斷是否知足其餘維度的需求,最終決定是否用這個 offer 來建立 Task。

鏡像、存儲和網絡管理

平臺提供了一些基礎鏡像,另外用戶也能夠基於本身的虛擬機建立本身的鏡像。這些鏡像文件統一存儲在一個基於 GlusterFS 的分部署存儲服務中,該服務掛載在每臺物理機上。

有些業務場景須要部分虛擬機可以共享同一份存儲,因而咱們仍是基於 GlusterFS 開發了用戶存儲服務,可以根據用戶的配置,在虛擬機建立時自動掛載好。

網絡方面,每一個用戶能夠建立多個子網,各個子網之間作了網絡隔離。建立虛擬機時,須要指定使用哪一個子網。

其餘問題

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

問題一:Marathon選主異常

當機器負載比較高,尤爲是 IO 較高時,咱們發現 Marathon 集羣有機率出現不能選主的狀況。

咱們懷疑是因爲Marathon節點和ZK的網絡不穩定,觸發了Marathon或Mesos的bug致使。因而經過iptables主動屏蔽Leader ZK端口的方式,成功復現出問題。

經過在Marathon的代碼中加上一些Leader選舉相關的最終日誌,成功定位到了問題,原來是因爲Mesos Driver的stop() 方法沒有成功引發 start() 方法退出阻塞致使。

因爲咱們的全部程序都是經過守護進程啓動的,因此咱們採用了一個最簡單的解決方案:修改Marathon代碼,當ZK異常發生時,直接自殺。自殺後守護進程會把程序再啓動起來。

問題二:go-marathon問題

咱們的服務採用 Golang 開發,使用 go-marathon 庫與 Marathon 進行交互。使用過程當中發現該庫有一些問題:

不支持多Marathon節點。因而咱們本身建立了一個分支,採用節點主動探測的方式,實現了多節點的支持。(原庫v5.0版本之後也支持了該功能)

使用設有 Timeout 的 http.Client 進行 go-marathon 的初始化時,訂閱 SSE 會產生超時問題。因而咱們作了修改,普通的 HTTP API 和 SSE 不使用同一個 http.Client,操做 SSE 的 http.Client 不設置 Timeout。

網絡異常時,go-marathon 的方法調用會 Hang 住。因而咱們全部對 go-marathon 方法的調用都加上超時控制。

結語

Mesos 在 UCloud 有着普遍的應用,對外有「計算工廠」和 UDocker 等產品,對內則支撐着公司內網虛擬機管理平臺。伴隨着持續的實踐,咱們對 Mesos 的理解和掌控也愈來愈深刻。咱們會持續輸出咱們的使用經驗,期待獲得各位讀者的反饋。

相關文章
相關標籤/搜索