容器時代,叢集排程誰家強?
如今,企業IT系統叢集規模越來越大,各路計算系統、儲存系統、應用系統隨著業務的飛速發展,一個接一個地“噌噌”搭建起來。但同時問題也來了,比如部署運維繁瑣、新系統上線週期長、叢集整體利用率偏低等。這時候,企業迫切需要一套強大的叢集資源排程系統來幫忙。考慮到時下叢集負載容器化如火如荼,各路面向容器的排程系統眼花繚亂,小編打算挑幾位人氣頗高、來自“開源界”的資源排程高手——Docker Swarm、Apache Mesos和Google Kubernetes,講講TA們在大規模容器場景下如何各施本領的故事。
在高手出場前,讓我們先快速回顧一下有關容器技術的背景知識。
從容器(Container)到Docker
1. 容器(Container)
提到虛擬化,很多人都會立刻想到虛擬機器,其實它只是虛擬化的一種實現。容器是另一種虛擬化,一種作業系統級別的虛擬化。從本質上來說,容器就是提供一個與宿主機作業系統共享核心但與系統中的其它程序資源相隔離的執行環境。其輕量級部署執行和秒級啟動特性,幫助開發者快速構建、釋出、部署和例項化應用程式。
容器化最直接的好處在於簡化DevOps,當應用採用了微服務架構(Micro-services architecture),每個容器就是一個微服務,而容器的靈活性意味著微服務可以隨負載增長而快速橫向擴充套件,且namespace(包含一個應用程式能夠互動的所有資源)與資源隔離阻止了微服務例項之間的互相干擾。
2. Docker
Docker是時下流行的容器技術之一,起先是基於LXC(Linux Container)的開源容器管理引擎, 現在runC(標準化容器執行引擎,符合OCI標準的開放容器專案)更讓它欣欣向榮向前發展。
與傳統“重量級”的虛擬機器相比,Docker在LXC之上融合AUFS分層映象管理機制,拋棄傳統虛擬機器試圖模擬完整機器的思路,而是以應用為單元進行“集裝封箱”,是“輕量級”的虛擬化技術。
Docker Engine可以自動化部署應用到可移植的的容器中,這些容器獨立於硬體、語言、框架、打包系統。一個標準的Docker容器包含一個軟體元件及其所有的依賴,包括二進位制檔案,庫,配置檔案,指令碼等,實現持續整合與部署,快速迭代應用程式。
Docker容器可以封裝任何有效負載,幾乎可以在任何伺服器之間進行一致性執行。開發者構建的應用只需一次構建即可多平臺執行。運營人員只需配置他們的服務,即可執行所有應用。
Docker的終極目標是簡化容器的建立,並讓這些容器可以作為開發者和系統管理者標準化、配置、交付應用的最佳方案。如果說Docker交付執行環境如同海運,那麼OS如同一個貨輪,每一個在OS上的App都如同一個集裝箱,使用者可以通過標準化手段自由組裝執行環境, 同時集裝箱的內容可由使用者自定義,也可由專業人員製造。這樣,交付一個應用,就是一系列標準化元件的集合交付。
高手登場了
身為一個容器排程高手,TA一定會選擇最適合的Host來啟動容器,並讓容器之間緊密協同;對於失效容器立即自動替換,一切錯誤處理盡在掌控中;當高併發突然來襲,能迅速擴充套件容器來應對等等。那麼今天的這三位主角——Docker Swarm、Apache Mesos、Google Kubernetes,在大規模叢集容器場景的挑戰下,又會表現出怎樣的特徵和本領?
1. Docker Swarm篇
Docker Swarm是Docker公司在2014年12月初發布的一套管理Docker叢集的工具。它將一群Docker宿主機變成一個單一的虛擬主機,而且使用標準的Docker API介面作為其前端訪問入口,這樣一來,各種形式的Docker工具都可以很容易與Swarm進行整合。
Swarm架構特點
一套Docker Swarm架構由一個Swarm manager和若干Swarm節點組成,見下圖。Swarm manager上執行Swarm daemon,使用者只需跟Swarm manager通訊,然後Swarm manager根據discovery service的資訊選擇一個Swarm節點來執行容器。
值得注意的是Swarm daemon 只是一個任務排程器(scheduler)和路由器(router),它本身不執行容器,只接受 Docker client 傳送過來的請求,排程合適的Swarm節點來執行容器。這意味著,即使Swarm daemon 由於某些原因掛掉了,已經執行起來的容器也不會有任何影響。
Swarm排程策略
Swarm支援以下三種排程策略來選擇節點執行容器:spread,binpack和random。使用spread策略,Swarm會選擇一個正在執行的容器數量最少的那個節點來執行容器;而binpack 則相反,Swarm會盡可能把所有容器放在一個節點上執行;random策略,顧名思義,不會做任何計算,只是單純隨機選擇一個節點來啟動容器,這種策略一般只做除錯用。
Swarm過濾器
在選擇節點執行容器時,Swarm支援兩種節點過濾器(Constraint和Health),三種容器配置過濾器(Affinity、Dependency和Port)。
Constraint (限制過濾器)是一個跟具體節點相關聯的鍵值對,可以看做是每個節點的標記,這個標記可以在啟動docker daemon時指定。
Health(健康過濾器)阻止容器運行於unhealthy節點上。
Affinity(關聯過濾器)讓容器執行在有關聯關係的節點上,包括容器關聯、映象關聯和標記關聯。
Dependency(依賴過濾器)可以讓一個容器“依賴”另一個容器執行,“依賴”是指兩個容器共享卷,彼此互連,處於同一網路堆疊。
Port(埠過濾器)讓容器運行於此埠可用的節點,避免埠衝突導致容器執行失敗。
2. Apache Mesos篇
Apache Mesos是2009年加州大學伯克利分校AMPLab首先開發出的一款開源叢集管理軟體,主要用於搭建高效擴充套件的分散式系統來支援各式各樣不斷增長的Framework。畢竟像Hadoop和MPI這些Framework都是獨立發展起來的,不太可能實現很好顆粒度的跨框架資源共享。但Mesos有增設一層“薄薄”的資源共享層,為各種Framework提供了通用介面來訪問叢集資源。下圖為Mesosphere公司基於Mesos“核心”搭建的DCOS(資料中心作業系統)架構示意。
在Apache Mesos的術語中,使用Mesos API在叢集中排程任務的Mesos應用程式稱為Framework(框架)。下圖為執行在Mesos上的各種Framework,不同顏色代表不同型別的應用。(圖片摘自Mesosphere官網)
Mesos“兩級排程機制”
Mesos以Framework的形式,提供兩級排程機制。Mesos有兩大關鍵元件:Mesos Master和Mesos Slave。Master是整個排程系統的核心,可理解為一個輕量級的Monolithic scheduler,負責接入Mesos的各種Framework和管理Slave,並將Slave上的資源按自定義策略分配給Framework 。而Slave負責接收並執行Master的命令,管理節點上的task,併為各task分配資源,同時Slave還將當前系統資源彙報給Master進行分配。
下圖為Mesos“兩級排程機制”示意圖,圖中只展示了Hadoop和MPI兩種框架型別。(圖片摘自網路)
Marathon是註冊到Mesos的一款很重要的Framework,主要負責管理長時應用(long-running applications),由Mesosphere公司一手設計並主動維護的。如果把Mesos比作資料中心kernel的話,那麼Marathon就是init或者upstart的daemon。
下圖為Mesos應用Marathon的架構示意。
可見該集群系統共有4大核心元素:ZooKeeper、Marathon、Mesos Master和Mesos Slave。ZooKeeper幫助Marathon查詢Mesos Master的地址,多例項可用來處理失效。Marathon啟動、監控和擴充套件容器。Mesos Master將指定任務傳送給Slave節點,而且當Slave節點有空閒的CPU/RAM時,Master會向Marathon提出邀約。Mesos Slave負責執行容器並提交可用資源清單。
Marathon的4大特性
- Constraints
Marathon可以通過Constraints來控制其app在何處執行。也就是說通過Constraints,可以限制應用部署在指定的一個或多個Slave節點上。這類應用一般是有狀態應用,或儲存型應用,必須將應用的資料目錄掛載出來,又或是應用需要部署在有特殊配置的Slave節點上,例如,應用需要使用GPU資源,而只有特定的Slave節點有GPU資源。Constraints由三個部分組成:欄位名(field name),操作(operator), 可選引數(optional parameter)。
- 健康檢查
Marathon對釋出到它之上的應用支援基於TCP/HTTP協議的健康檢查,大體邏輯是Marathon會週期性掃描應用的健康檢查路徑,如果響應時間連續n次超出閾值,那麼Marathon會直接重啟這個應用,即所謂的Fast failed。只要應用響應過慢,就應該殺掉它,響應過慢的應用會大大拖慢全域性服務的響應速度,因此不再需要容器內部的失敗重啟,而是直接殺掉容器。
- 服務發現和負載均衡
服務發現的功能實現是為DCOS中的服務提供便捷的網路通訊,它的側重點在於對服務進行註冊,更新,查詢等功能。DCOS的服務發現功能採用的是Mesos-DNS,一種Apache Mesos提供的基於DNS的服務發現策略,它可以結合多種Framework來工作(不止是Marathon)。
Mesos-DNS 是無狀態的,可以自由複製,因此通過為每個Slave部署Mesos-DNS 的方式來保證高可用。而且採用Mesos-DNS策略,通過輔助指令碼利用Marathon RESTful API定時產生HAProxy配置檔案,通過diff生成的HAProxy配置檔案與已有的HAProxy來判斷是否進行過載HAProxy操作,從而實現負載均衡。
3. Google Kubernetes篇
Kubernetes是一個容器叢集的編排管理系統,主要面向跨Docker主機場景之下容器叢集的統一管理,據Wikipedia介紹,最初是由Google在2014年提出的開源專案,其開發設計思想深受Google的Borg系統影響。
Kubernetes架構特點
Kubernetes是一個典型的Master/Slave架構,見下圖。
Kubernetes Master
Kubernetes Master節點提供了叢集統一檢視的中心控制點,包括元件有:
API Server: 作為Kubernetes集群系統的統一管理入口,封裝了核心物件的增刪改查操作,以RESTful介面方式提供給外部客戶和內部元件呼叫。
Scheduler: 負責叢集的資源排程,為新建的Pod分配物理機。Pod是Kubernetes叢集裡最小的可部署單元,它表示同屬於一個應用的容器群的邏輯集合。
Controller Manager:負責執行各種控制器,目前有Endpoint Controller和Replication Controller兩類。Endpoint Controller:定期關聯Service和Pod,保證Service到Pod的對映總是最新的。Service也是Kubernetes的基本操作單元,是Pod的路由代理抽象,用於解決Pod之間的服務發現問題。Replication Controller:它是Pod的複製抽象,用於解決Pod的擴縮容問題。定期關聯Replication Controller和Pod,保證Replication Controller定義的複製數量與實際執行Pod的數量總是一致的。
注:Pod、Replication Controller和Service是Kubernetes最基本的三個操作物件。而Service和Replication Controller都是建立在Pod之上的抽象,通過Label與Pod關聯,Label就是為Pod加上可用於搜尋或關聯的一組key/value標籤。
Kubernetes Slave
Kubernetes Slave節點又稱作Minion,它是一個工作節點,負責執行Master節點交付的任務。Minions能執行一個或多個Pod,它包括元件有:
Kubelet: 在每個Minion上負責管控Docker容器,如啟動/停止、監控執行狀態等。它會定期從Etcd獲取分配到本機的Pod,並根據Pod資訊啟動/停止相應的容器。同時,它也會接收API Server的HTTP請求,彙報Pod的執行狀態。
Proxy: 負責為Pod提供代理。它會定期從Etcd獲取所有的Service,並根據Service資訊建立代理。當某個客戶Pod要訪問其他Pod時,訪問請求會經過本機Proxy做轉發。
Docker: Kubernetes使用的容器技術來建立容器。
Kubernetes功能特性
Kubernetes為容器化的應用提供資源排程、部署啟動、執行監控、服務發現、錯誤處理和擴容縮容等一系列功能,本質上可以看作是基於容器技術的mini-PaaS平臺。由於Kubernetes更關注對服務級別的控制而非僅僅對容器級別的控制,把服務看成一個整體,這種增強的協同工作方式,讓開發者的生產力得到提高,服務的可用性也進一步增強,大規模叢集部署工作也更加敏捷。
最終點評:高手沒有最強,只有最“適合”
以上三大高手中,Docker Swarm是最簡單的排程器。而且它與Docker環境的整合度很高,它使用Docker Engine同樣的API,使用Docker Compose描述檔案,因此對還不是很熟悉更復雜排程器的開發者很適合。尤其當開發者想要搭建特殊工作流時,Swarm能提供一個快速開始且高配置度的排程平臺。此外,Swarm並未與特定的雲供應商繫結,背後是一個完全開源的強大社群作支援。
而Mesos加Marathon更適合Mesos叢集。事實上,它也使用類似Docker Compose的描述檔案來指定任務,很適合在叢集中部署容器的情況。Mesosphere推出的以Mesos為核心的一整套DCOS解決方案,則為生產環境下的容器排程提供了便捷而強有力的支援。
Kubernetes採用了與標準Docker完全不同的邏輯原理,它是圍繞Pod和Service等核心概念另闢一種使用容器的有趣新方式,當然它也從未停止過思考與其它生態圈的連線問題。不過Google推出Kubernetes主要還是為Google自己生態圈裡的開發者提供一種簡單便捷的叢集排程方案,一種邏輯選擇。
沒有最強大的容器排程高手,但有根據你的需要,你實際的叢集環境,最適合你的那一款選型。下圖是一個Swarm專案,在Swarm頂端允許部署Kubernetes,Mesos + Marathon,未來還將支援Cloud Foundry,Nomad以及更多的容器排程框架。Swarm叢集在其它manager(比如Mesos + Marathon,Kubernetes)的管理下,容器實現跨叢集遷移。事實上,這種“大聯合”可以讓你“隨心所欲”地對容器進行排程和編排。