巔峯對決之Swarm、Kubernetes、Mesos

這篇文章對比了三大主流調度框架:Swarm、Kubernetes和Mesos。文章不僅從理論上討論了各個框架的優缺點,還從兩個實際的案例出發,分析了每個框架具體使用方法。

@Container容器技術大會將於6月4日在上海光大會展中心國際大酒店舉辦,來自攜程、PPTV、螞蟻金服、京東、浙江移動、海爾電器、唯品會、eBay、道富銀行、麻袋理財、土豆網、阿里百川、騰訊遊戲、點融網等公司的技術負責人將帶來實踐經驗分享,3月21日之前購票只需238元,歡迎感興趣的同學搶購。

這篇文章對比了三大主流調度框架:Docker Swarm、Google Kubernetes和Apache Mesos(基於Marathon框架)。在解釋了調度和容器的基本概念後,文章探討了每個框架的特點,並從以下兩個用例來對比他們:一個只使用了兩個容器的網站應用,和一個能具有可擴展性的投票應用。

什麼是調度(scheduling)?什麼是容器(container)?

調度

一個集羣調度工具有多個目的:使得集羣的資源被高效利用,支持用戶提供的配置約束(placement constraint),能夠迅速調度應用以此保證它們不會處於待定狀態(pending state),有一定程度的“公平”(fairness),具有一定的魯棒性和可用性。爲了達到這些目的,在一篇關於Omega(一個由Google開發的,針對大型計算集羣的可擴展調度框架)的白皮書中,提到了三個主要的調度架構[48]:
01.png

Schematic overview of scheduling architectures, © Google, Inc. [48]

一體式調度(Monolithic scheduling)

一體式調度框架由單一的調度代理(scheduling agent)組成,它負責處理所有的請求,這種框架通常應用於高性能計算。一體式框架通常實現了一個單一的算法來處理所有的作業(job),因此根據作業的類型來運行不同的調度邏輯是困難的。

Apache Hadoop YARN[55]是一個非常流行的架構,儘管它將許多調度功能都分發到每一個應用模塊中,但它依然是一體式的調度架構,因爲,實際上,所有的資源請求都會被髮送到一個單一的全局調度模塊。

兩級調度(Two-level scheduling)

兩級調度框架會利用一箇中央協調器(central coordinator)來動態地決定各個調度模塊可以調用多少資源。這項技術被應用於Mesos[50]和Hadoop-on-Demand(現在被YARN取代了)。

在這類架構裏,分配器會將給定的資源一次性分配個一個框架,因此避免了資源使用的衝突,並且通過控制資源分配的順序和大小來實現一種相對的資源公平分配。然而,一個資源每次只能被一個框架使用,因此併發控制被稱之爲悲觀的(pessimistic),這種控制策略是不易於出錯的(less error-prone),但是相對於將一個資源同時分配個多個框架的樂觀併發式控制來說,速度是更慢的。

共享狀態調度(Shared-state scheduling)

Omega 賦予了每一個調度器(scheduler)對整個集羣的全部訪問權限,也就是說調度器們可以自由地競爭。因爲所有的資源分配都發生在各個調度器中,所以也就沒有了中央資源分配器。也就是說,沒有了中央策略引擎,每一個調度器能夠自己做決定。

通過支持獨立的調度器實現和公佈整個資源分配的狀況,Omega不僅支持擴展多個調度器,還能夠支持它們自己的調度策略[54]

哪一個纔是最好的調度架構?

世界上並不存在一個通用的唯一方案來解決集羣計算的所有問題,因此不同的公司爲了適應需求,各自開發了不同的產品。Google(Omege和Kubernetes的主要貢獻者)假設開發者們會遵守關於作業優先級的規則,因此Google認爲架構應該把控制權交給開發者;而Yahoo!(YARN的主要貢獻者)更推崇強制容量、公平和截止時間的框架。

容器革命(The container revolution)

容器是虛擬機的一種替代品,它能夠幫助開發者構建、遷移、部署和實例化應用[3]。一個容器是進程的集合,這些進程獨立於包含有進程依賴的機器。

各個容器儘管共享了一個操作系統實例,但是它們獨立運行,互不影響。容器並不需要一個完整的操作系統,這個特性使得它們比虛擬機更加輕量。

因爲容器能夠在數秒內啓動(比虛擬機快多了),因此容器僅分配了少量的資源(少於2GB的RAM)並且能通過擴展來滿足應用的需求。容器經常被應用於微服務(microservices),每一容器代表一個服務,這些服務通過網絡來進行互聯。這種架構使得每一個模塊都能夠被獨立地部署和擴展。

資源的數量和所期望的容器生命週期是普通調度器和容器調度器的主要區別。傳統集羣設計,比如說Hadoop,更關注於運行大規模作業[55],然而容器集羣則會運行幾十個小的實例來解決問題,這些實例需要被組織化和網絡化,以此來優化共享數據和計算的能力。

Docker

Docker是一個主流容器管理工具,它是第一個基於Linux容器(LXC)的[2],但是現在被runC[46]所取代了(runC是是一個由Open Containers Initiative開發的CLI工具,它能夠創建和運行容器[36])。Docker容器支持分層的文件系統,因此它能夠和宿主機共享系統內核。這個特性意味着即便一個Docker鏡像基於一個1GB的操作系統,在同一個主機上運行10個容器實例並不需要消耗10GB的空間,相比之下,每一臺虛擬機都需要一個完整的1GB操作系統。
02.png

Virtual machines architecture compared to containers, © Docker Inc. [23]

Docker的鏡像可以理解爲一個操作系統的快照。如果你想要創建一個新的鏡像,你需要啓動一個基礎鏡像,然後做一些修改,最後提交修改,形成新的鏡像。這些鏡像能夠發佈在私有或者公有的庫上[10]供其他開發者使用,開發者只需要將鏡像pull下來即可。

使用鏡像可以非常方便的創建操作系統的快照,並且使用它們來創建新的容器,這些功能非常的輕量和易用,這些都是Docer CLI和商業模式的核心。[12]

容器包含了所有運行所需要的東西(代碼,運行時,系統工具,庫),因此Docker給予開發者一個輕量的,穩定的環境來快速地進行創建和運行作業。

容器調度簡介(Description of container schedulers)

容器調度工具的主要任務就是負責在最合適的主機上啓動容器,並且將它們關聯起來。它必須能夠通過自動的故障轉移(fail-overs)來處理錯誤,並且當一個實例不足以處理/計算數據時,它能夠擴展容器來解決問題。

這篇文章比較了三個主流容器調度框架:Docker Swarm [13], Apache Mesos (running the Marathon framework) [50] and Google Kubernetes [31]。在這一節,將會討論各個框架的設計和特點。

Docker Swarm

Docker Swarm是一個由Docker開發的調度框架。由Docker自身開發的好處之一就是標準Docker API的使用[17]。Swarm的架構由兩部分組成:
03.png

Docker Swarm architecture, ©Alexandre Beslic (Docker Inc.) [14]
其中一個機器運行了一個Swarm的鏡像(就像運行其他Docker鏡像一樣),它負責調度容器[4],在圖片上鯨魚代表這個機器。Swarm使用了和Docker標準API一致的API,這意味着在Swarm上運行一個容器和在單一主機上運行容器使用相同的命令。儘管有新的flags可用,但是開發者在使用Swarm的同時並不需要改變他的工作流程。

Swarm由多個代理(agent)組成,把這些代理稱之爲節點(node)。這些節點就是主機,這些主機在啓動Docker daemon的時候就會打開相應的端口,以此支持Docker遠程API[5]。其中三個節點顯示在了圖上。這些機器會根據Swarm調度器分配給它們的任務,拉取和運行不同的鏡像。

當啓動Docker daemon時,每一個節點都能夠被貼上一些標籤(label),這些標籤以鍵值對的形式存在,通過標籤就能夠給予每個節點對應的細節信息。當運行一個新的容器時,這些標籤就能夠被用來過濾集羣,具體的細節在後面的部分詳談。

策略(Strategies)

Swarm採用了三個策略(比如說,策略可以是如何選擇一個節點來運行容器)[22]:

策略名:節點選擇
  • spread:最少的容器,並且忽視它們的狀態
  • binpack:最擁擠(比如說,擁有最少數量的CPU/RAM)
  • random:隨機選擇

如果多個節點被選中,調度器會從中隨機選擇一個。在啓動管理器(manager)時,策略需要被定義好,否則“spread”策略會被默認使用。

過濾器(Filters)

爲了在節點子集中調度容器,Swarm提供了兩個節點過濾器(constraint和health),還有三個容器配置過濾器(affinity,dependency和port)。

約束過濾器(Constraint filter)

每一個節點都關聯有鍵值對。爲了找都某一個關聯多個鍵值對的節點,你需要在docker daemon啓動的時候,輸入一系列的參數選項。當你在實際的生產環境中運行容器時,你可以指定約束來完成查找,比如說一個容器只會在帶有環境變量key=prod的節點上運行。如果沒有節點滿足要求,這個容器將不會運行。

一系列的標準約束已經被設置,比如說節點的操作系統,在啓動節點時,用戶並不需要設置它們。

健康過濾器(Health filter)

健康過濾器用來防止調度不健康的節點。在翻看了Swarm的源代碼後,只有少量關於這個概念的信息是可用的。

吸引力過濾器(Affinity filter)

吸引力過濾器是爲了在運行一個新的容器時,創建“吸引力”。涉及到容器、鏡像和標籤的吸引力存在有三類。

對容器來說,當你想要運行一個新的容器時,你只需要指定你想要鏈接的容器的名字(或者容器的ID),然後這些容器就會互相鏈接。如果其中一個容器停止運行了,剩下的容器都會停止運行。

鏡像吸引力將會把想要運行的容器調度到已經擁有該鏡像的節點上。

標籤吸引力會和容器的標籤一起工作。如果想要將某一個新的容器緊挨着指定的容器,用戶只需要指定一個key爲container,value爲<container_name>的吸引力就可以了。

吸引力和約束的語法接受否定和軟強制(soft enforcement),即便容器不可能滿足所有的需求。[18]

依賴過濾器(Dependency filter)

依賴過濾器能夠用來運行一個依賴於其他容器的容器。依賴意味着和其他容器共享磁盤卷,或者是鏈接到其他容器,亦或者和其他容器在同一個網絡棧上。

端口過濾器(Port filter)

如果你想要在具有特定開發端口的節點上運行容器,你就可以使用端口過濾器了。如果集羣中沒有任何一個節點該端口可用的話,系統就會給出一個錯誤的提示信息。

Apache Mesos & Mesosphere Marathon

Mesos的目的就是建立一個高效可擴展的系統,並且這個系統能夠支持很多各種各樣的框架,不管是現在的還是未來的框架,它都能支持。這也是現今一個比較大的問題:類似Hadoop和MPI這些框架都是獨立開的,這導致想要在框架之間做一些細粒度的分享是不可能的。[35]

因此Mesos的提出就是爲了在底部添加一個輕量的資源共享層(resource-sharing layer),這個層使得各個框架能夠適用一個統一的接口來訪問集羣資源。Mesos並不負責調度而是負責委派授權,畢竟很多框架都已經實現了複雜的調度。

取決於用戶想要在集羣上運行的作業類型,共有四種類型的框架可供使用[52]。其中有一些支持原生的Docker,比如說Marathon[39]。Docker容器的支持自從Mesos 0.20.0就已經被加入到Mesos中了[51]。

我們接下來將會重點關注如何在讓Mesos和Marathon一起工作,畢竟Marathon主要是由Mesosphere維護[41],並且提供了很多關於調度的功能,比如說約束(constraints)[38],健康檢查(health checks)[40],服務發現(service discovery)和負載均衡(load balancing)[42]。
04.png

Apache Mesos architecture using Marathon, © Adrian Mouat [49]

我們可以從圖上看到,集羣中一共出現了4個模塊。ZooKeeper幫助Marathon查找Mesos master的地址[53],同時它具有多個實例可用,以此應付故障的發生。Marathon負責啓動,監控,擴展容器。Mesos maser則給節點分配任務,同時如果某一個節點有空閒的CPU/RAM,它就會通知Marathon。Mesos slave運行容器,並且報告當前可用的資源。

約束(Constraints)

約束使得操作人員能夠操控應用在哪些節點上運行,它主要由三個部分組成:一個字段名(field name)(可以是slavve的hostname或者任何Mesos slave屬性),一個操作符和一個可選的值。5個操作符如下:

操作符:角色(role)
  • UNIQUE:使得屬性唯一,比如說越蘇[“hostname”,”UNIQUE”]使得每個host上只有一個應用在運行。
  • CLUSTER:使得運行應用的slaves必須共享同一個特定屬性。比如說約束 [“rack id”, “CLUSTER”, “rack-1”] 強制應用必須運行在rack-1上,或者處於掛起狀態知道rack-1有了空餘的CPU/RAM。
  • GROUP_BY:根據某個特性的屬性,將應用平均分配到節點上,比如說特定的host或者rack。
  • LIKE:使得應用只運行在擁有特定屬性的slaves上。儘管只有CLUSTER可用,但由於參數是一個正則表達式,因此很多的值都能夠被匹配到。
  • UNLIKE:和LIKE相反。

健康檢查(Health checks)

健康檢查是應用依賴的,需要被手動實現。這是因爲只有開發者知道他們自己的應用如何判斷健康狀態。(這是一個Swarm和Mesos之間的不同點)

Mesos提供了很多選項來聲明每個健康檢查之間需要等待多少秒,或者多少次連續的健康檢查失敗後,這個不健康的任務需要被終結。

服務發現和負載均衡(Service discovery and load balancing)

爲了能夠發送數據到正在運行的應用,我們需要服務發現。Apache Mesos提供了基於DNS的服務發現,稱之爲Mesos-DNS[44],它能夠在多個框架(不僅僅是Marathon)組成的集羣中很好的工作。

如果一個集羣只由運行容器的節點組成,Marathon足以承當起管理的任務。在這種情況下,主機可以運行一個TCP的代理,將靜態服務端口的連接轉發到獨立的應用實例上。Marathon確保所有動態分配的服務端口都是唯一的,這種方式比手動來做好的多,畢竟多個擁有同樣鏡像的容器需要同一個端口,而這些容器可以運行在同一個主機上。

Marathon提供了兩個TCP/HTTP代理。一個簡單的shell腳本[37]還有一個更復雜的腳本,稱之爲marathon-ld,它擁有更多的功能[43]。

Google Kubernetes

Kubernetes是一個Docker容器的編排系統,它使用label和pod的概念來將容器換分爲邏輯單元。Pods是同地協作(co-located)容器的集合,這些容器被共同部署和調度,形成了一個服務[28],這是Kubernetes和其他兩個框架的主要區別。相比於基於相似度的容器調度方式(就像Swarm和Mesos),這個方法簡化了對集羣的管理.

Kubernetes調度器的任務就是尋找那些PodSpec.NodeName爲空的pods,然後通過對它們賦值來調度對應集羣中的容器[32]。相比於Swarm和Mesos,Kubernetes允許開發者通過定義PodSpec.NodeName來繞過調度器[29]。調度器使用謂詞(predicates)[29]和優先級(priorites)[30]來決定一個pod應該運行在哪一個節點上。通過使用一個新的調度策略配置可以覆蓋掉這些參數的默認值[33]。

命令行參數plicy-config-file可以指定一個JSON文件(見附錄A)來描述哪些predicates和priorities在啓動Kubernetes時會被使用,通過這個參數,調度就能夠使用管理者定義的策略了。
05.png

Kubernetes architecture (containers in grey, pods in color), © Google Inc. [31]

謂詞(Predicates)

謂詞是強制性的規則,它能夠用來調度集羣上一個新的pod。如果沒有任何機器滿足該謂詞,則該pod會處於掛起狀態,知道有機器能夠滿足條件。可用的謂詞如下所示:
  • Predicate:節點的需求
  • PodFitPorts:沒有任何端口衝突
  • PodFitsResurce:有足夠的資源運行pod
  • NoDiskConflict:有足夠的空間來滿足pod和鏈接的數據卷
  • MatchNodeSelector:能夠匹配pod中的選擇器查找參數。
  • HostName:能夠匹配pod中的host參數

優先級(Priorities)

如果調度器發現有多個機器滿足謂詞的條件,那麼優先級就可以用來判別哪一個纔是最適合運行pod的機器。優先級是一個鍵值對,key表示優先級的名字,value就是該優先級的權重。可用的優先級如下:
  • Priority:尋找最佳節點
  • LeastRequestdPriority:計算pods需要的CPU和內存在當前節點可用資源的百分比,具有最小百分比的節點就是最優的。
  • BalanceResourceAllocation:擁有類似內存和CPU使用的節點。
  • ServicesSpreadingPriority:優先選擇擁有不同pods的節點。
  • EqualPriority:給所有集羣的節點同樣的優先級,僅僅是爲了做測試。

結論

以上三種框架提供了不同的功能和歸來來自定義調度器的邏輯。從這節來看,顯而易見,由於Swarm的原生API,Swarm是三個中最容易使用的。

以Docker的方式來運行容器[15]意味着一個容器是短暫存在的,並且每一個容器只運行一個進程。根據這條原則,多個容器提供一個服務或者代表一個應用是極度正常的。

因此編排和調度容器成爲了最應當解決的問題,這也解釋了爲什麼,即便這項技術不是很成熟,但仍有那麼多的調度器被開發出來,並且提供了不同的功能和選項。

調度器對比

從上一節我們可以看到,爲了讓容器一起協調工作,成爲一個真正的服務,在很多情況下,容器調度器都是有必要存在的。

首先,我們會從一個簡單的例子(只有兩個容器運行)來對比每個調度器。爲了方便,我們使用Docker提供的初學者教程中的案例項目,這個項目會運行一個快餐車的網站[47],並且將它部署到集羣上。

然後,我們會從另外一個例子來對比不同調度器的擴展性:基於AWS的投票應用。這個例子基於Docker提供的“try Swarm at scale”教程[7]。應用中所有的模塊都運行在容器中,而容器運行在不同的節點,並且這個應用被設計成可擴展的:
06.jpeg

Voting application architecture, © Docker Inc [7]

負載均衡負責管理運行Flask應用[1]的web服務器和關聯隊列的數量。Worker層掃描Redis隊列,將投票出列,並且將重複項提交到運行在其他節點的Postgres容器。

快餐車應用(Food Trucks Application)

在這一節我們主要對比每個調度器的默認配置,比如說由於用戶需求極速增長所帶來的單容器瓶頸問題,還有如何處理一個需要重啓的容器。

我們想要運行的多容器環境是由一個運行擁有Flask進程的容器[1],和其他運行有Elasticsearch進程的容器組成。

Swarm

Docker公司提供了多個工具,我們已經看到了Docker引擎和Swarm,但Doccker Compose纔是多容器環境的關鍵。有了這個工具,我們能夠僅僅使用一個文件來定義和運行多個容器。

對於我們現在的例子,我們可以使用一個docker-compose.yml文件來指定兩個需要運行的鏡像(一個定製的Flask鏡像和一個Elasticsearch鏡像)和Swarm之間的關聯。

一個主要的問題就是Swarm可以像單主機Docker實例一樣,從一個Dockerfile來構建鏡像,但是構建的鏡像只能在單一節點上運行,而不能夠被分佈到集羣上的其他節點上。因此,應用被認爲是一個容器,這種方式不是細粒度的。

如果我們使用docker-compose scale來擴展其中一個容器(附錄 B),這個新的容器將會根據調度器規則進行調度。如果容器負載過重,Docker Swarm並不會自動擴展容器,這對於我們的例子來說是一個大問題:我們必須經常去檢查下用戶訪問量是否達到瓶頸。

如果一個容器宕機了,Swarm並不會跟蹤一個服務應該有多少個實例在運行,因此它不會創建一個新的容器。其外,想要在某些容器上滾動更新也是不可能的,一個符合Docker思想的特性是非常有用的:能夠快速啓動和停止無狀態的容器。

Mesos & Marathon

與直接使用docker-compose.yml文件不同,我們需要給Marathon一個具體的定義。第一個定義應用於Elasticsearch(附錄C),我們使用所有的默認配置,並不使用調度器的特性;在這種情況下,定義非常的簡單,並且類似於我們之間的docker-compose.yml文件。應用於Flask的定義(附錄D)使用了更多Mesos的特性,包括指定CPU/RAM信息和健康檢查。

Mesos提供了一個更加強大的定義文件,因爲容器和需求都可以被描述。相比於Swarm,這種方式並不簡單,但是它能夠很簡單的擴展服務,比如說,通過修改應用定義中的容器實例來擴展。(在Flask定義中設置數量爲2)

Kubernetes

Kubernetes在YAML或者JSON(附錄E)中使用了另外一種描述來表示pod。它包含了一個ReplicationController來保證應用至少有一個實例在運行。當我們在Kubernetes集羣中創建了一個pod時,我們需要創建一個叫做負載均衡的Kubernetes服務,它負責轉發流量到各個容器。如果只有一個實例,使用這種服務也是非常有用的,因爲它能否將流量準確的轉發到擁有動態IP的pod上。

相比於Swarm,Kubernetes添加了pod和replica的邏輯。這個更加複雜的結構爲調度器和編排工具提供了更加豐富的功能,比如說負載均衡,擴展或者收縮應用的能力。並且你還能夠更新正在運行中的容器實例,這是一個非常有用的、符合Docker哲學的功能。

結論

Docker Compose是調度多容器環境的標準方式,Docker Swarm直接使用這種方式。而對於Mesos和Kubernetes,它們提供了一個額外的描述文件,它整合了標準描述和額外的信息,因此它能夠爲用戶提供更好的調度。

我們可以看到,Mesos的調度器能夠和Docker容器很好的工作,但是對於我們當前的用例來說,Kubernetes纔是最適合運行這種微服務架構的框架。通過提供類似於Compose的描述,同時提供relication controller,Kubernetes能夠爲用戶提供一個穩定的服務,並且具有可擴展性。

投票系統(Voting application)

這個部署架構同樣是來自Docker的教程[7],爲了構建集羣,我們創建了一個Amazon Virtual Public Cloud(VPC)並且在VPC上部署節點。我們之所以使用Amazon的服務,是因爲它能夠支持這三個調度器,並且在Amazon上,Docker能通過一個部署文件來啓動一個Docker式的集羣。

Swarm

創建集羣的主要步驟有:連接集羣中所有的節點,創建一個網絡使得節點之間能夠便捷地交流(類似於Kubernetes自動提供的),通過在每個特定容器上運行鏡像來完成最後部署
07.jpeg

Voting application organization, © Docker Inc [7]
08.png

EC2 machines to run the scalable application in a cluster.

我們使用命令行參數restart=unless-stopped來運行docker daemon能夠在某一個容器意外停止時重啓它。如果一整個節點崩了,那麼節點上的容器並不會在其他節點上重新啓動。

這個集羣擁有一個負載均衡器[25],它能防止將請求轉發到一個不再存在的節點上,因此如果frontend1崩了,所有的請求就會自動流向frontend2。因爲負載均衡器本身就是一個容器,通過參數restart=unless-stopped能夠確保它意外停止時能夠重啓。

這個集羣部署的主要問題就是,Postgres節點是單一的,如果這個節點崩了,那麼整個應用程序就崩了。爲了提高集羣的故障容錯率,我們需要添加另外一個Swarm的管理器,以防止前一個崩潰了。

這個調度器的效率類似於直接在單個機器上運行容器。Swarm的調度策略非常的簡單(我們從上一節可以看出),因此調度器選擇節點時非常的迅速,彷彿集羣中只有一臺機器。如果想要看到進一步的性能測試,可以參考Docker在Swarm上運行3000個容器的擴展測試[16]。

Mesos & Marathon

Mesos & Marathon是商業產品,因此也提供了部署的服務。Mesosphere[45]提供了一個社區版本在幾分鐘內創建一個高可用性的集羣。我們只需要給出master的數量,公開的代理節點,私有的代理節點,然後一個Mesos集羣就誕生了。

Mesos集羣的配置相比於Swarm複雜的多,這是因爲它有很多的模塊(Mesos marathon,Mesos slaves,Marathon和Zookeeper實例等)。因此提前配置好的集羣是一個不錯的方法,並且能夠直接運行一個高可用的集羣(有三個master)對於建立高容錯的集羣來說很有幫助。
09.png

Deploying a cluster using Mesos & Marathon can be done in 2 minutes.

一但集羣開始運行,Meoso master提供了一個Web的接口來顯示所有的集羣信息。在集羣上運行容器的操作類似於Swarm和之間的例子。

相比於Swarm,Mesos的容錯性更強,這是因爲Mesos能夠在JSON文件中對某個應用使用監看檢查。因爲自動擴展功能是商業版獨有的,因此這裏集羣並不能自動擴展,但是我們還是有其他的辦法來實現它,比如說Amazon EC2 Auto Scaling Groups。

Kubernetes

Kubernetes擁有一套命令行管理工具和一個集羣啓動腳本。Kubernetes也提供了一個用戶接口(類似於Mesossphere提供的)[34],但這個接口並沒有拆分開來,而是屬於調度器的一部分。

我們需要創建一個replication controller來定義pod的容器和pod的最小運行數量。從第一個案例來看,我們可以在一個文件中描述所有集羣關於replications的信息。

集羣可以通過調度器策略(policies)來擴展,並且Google聲明Kubernetes能夠支持100個節點,每個幾點上有30個pod,每個pod擁有1-2個容器[27]。Kubernetes的性能要比Swarm差,是因爲它擁有更加複雜的架構,性能比Mesos差,是因爲它結構層次更深(less bare metal),但是很多人在正在努力提升它的性能。

未來要做的

由於我們比較的調度器都比較新穎,暫時還沒有可用的基準工具來評價它們之間的擴展性如何。因此,未來還需要在這麼一個環境中對比調度器:有多個集羣,集羣時常出現問題,但是集羣間又有大量的連接。

這裏對比的調度器主要是用來創建可擴展的Web服務,這個用例要求調度器有高容錯性,但是沒有提到當處理成千上萬容器時,調度器的速度如何。比如說,在關於Mesos&Marathon的可擴展性測試上,並沒有具體的數字來說明容器數量。唯一的用例提到了擁有80個節點和640個虛擬CPU的集羣。

在同樣硬件上對比同樣的案例,一個基準程序(benchmark)意味着同一時間段運行的大量節點和應用能夠被較爲公平的比較。這個新的基準程序能夠告訴我們不同調取器在其他案例上的具體信息,比如說批處理。

結論

Docker Swarm是最簡單的調取器,它擁有易於理解的策略和過濾器,但是由於它不能處理節點的失敗問題,所以在實際的生產環境中,不推薦使用。Swarm和Docker環境很好的結合在一起,它使用了Docker引擎一樣的API,並且能夠和Docker Compose很好的一起工作,因此它非常適合那些對其他調度器不太瞭解的開發者。

Swarm非常輕量,並且提供了多個驅動,使得它它能夠和未來所有的集羣解決方式一起工作[11]。Swarm是一個調度解決方案,非常易於使用,比如它爲開發者提供了高緯度的配置方式,讓他們能夠快速實現具體的工作流。Docker Swarm並沒有綁定到某一個具體的雲服務提供商,它是完全開源的,並且擁有一個非常強勁的社區。

如果你已經擁有一個Mesos 集羣,Mesos & Marathon將會是一個完美的組合方案。它能夠像其他Mesos框架一樣調度行任務,同時擁有一個類似於Docker Compose的描述文件來制定任務,這些特性使得它成爲在集羣上運行容器的極佳方案。Mesosphere[45]提供的完整解決方案同樣也是一個適合生產環節的、簡單而強大的方式。

儘管Kubernetes的邏輯和標準的Docker哲學不同,但是它關於pod和service的概念讓開發者在使用容器的同時思考這些容器的組合是什麼,真是非常有趣的。Google在它的集羣解決方案上[26]提供了非常簡單的方式來使用Kubernetes,這使得Kubernetes對於那些已經使用了Google生態環境的開發者來說,是一個合理的選擇。
10.png

Swarm frontends, © Docker Inc. [6]

容器的調度並不存在一個最佳的方案,從Swarm frontends可以看到[20],這個項目使得Kubernetes和Mesos+Marathon能夠部署在Swarm之上,並且它將會逐步支持Cloud Foundry,Nomad,和其他的容器器。具體選擇哪個調取器,還是取決於你的需求和集羣。

從最後一張圖片可以看到,Swarm集羣能夠被其它調取器管理,其中容器會分配到不同的集羣中。這些組合使得容器能夠按照你所想的被調度和編排。

Appendix

A — policy-config-file.json

{
"kind": "Policy",
"apiVersion": "v1",
"predicates": [
{
"name": "PodFitsPorts"
},
{
"name": "PodFitsResources"
},
{
"name": "NoDiskConflict"
},
{
"name": "MatchNodeSelector"
},
{
"name": "HostName"
}],
"priorities": [
{
"name": "LeastRequestedPriority",
"weight": 1
},
{
"name": "BalancedResourceAllocation",
"weight": 1
},
{
"name": "ServiceSpreadingPriority",
"weight": 1
},
{
"name": "EqualPriority",
"weight": 1
}]
} 

B — docker-compose.yml

es:
image: elasticsearch
container_name: "es"
web:
image: prakhar1989/foodtrucks-web
command: python app.py
ports:
- "5000:5000"
volumes:
- .:/code

C — Mesos app definition (Elasticsearch)

{
"id": "es",
"container": {
"type": "DOCKER",
"docker": {
  "network": "HOST",
  "image": "elasticsearch"
}
}
}

D — Appendix — Mesos app definition (Flask)

{
"id": "web",
"cmd": "python app.py",
"cpus": 0.5,
"mem": 64.0,
"instances": 2,
"container": {
"type": "DOCKER",
"docker": {
  "image": "prakhar1989/foodtrucks-web",
  "network": "BRIDGE",
  "portMappings": [
    { "containerPort": 5000, "hostPort": 0, "servicePort": 5000, "protocol": "tcp" }
  ]
},
"volumes": [
  {
    "containerPath": "/etc/code",
    "hostPath": "/var/data/code",
    "mode": "RW"
  }
},
"healthChecks": [
{
  "protocol": "HTTP",
  "portIndex": 0,
  "path": "/",
  "gracePeriodSeconds": 5,
  "intervalSeconds": 20,
  "maxConsecutiveFailures": 3
}
]
}

E — Kubernetes pod definition

apiVersion: v1
kind: ReplicationController
metadata:
name: app
labels:
name: app
spec:
replicas: 1
selector:
name: app
template:
metadata:
  labels:
    name: app
spec:
  containers:
  - name: es
    image: elasticsearch
    ports:
    - containerPort: 6379
  - name: web
    image: prakhar1989/foodtrucks-web
    command:
      - python app.py
    volumeMounts:
    - mountPath: /code
      name: code
    ports:
    - containerPort: 5000

References

[1] Armin Ronacher. Flask, a microframework for Python. 2014. url: http: //flask.pocoo.org/(visited on 01/23/2016).
[2] Canonical. Linux Containers. 2015. url: https://linuxcontainers.org/(visited on 01/21/2016).
[3] Cisco; Red Hat. “Linux Containers: Why They’re in Your Future and What Has to Happen First”. In: (2014). url: http://www.cisco.com/c/dam/en/ ... t.pdf
[4] Docker Inc. Create a swarm for development — configure a manager. 2015. url: https://docs.docker.com/swarm/ ... nager (visited on 01/13/2016).
[5] Docker Inc. Create a swarm for development — create swarm nodes. 2015. url: https://docs.docker.com/swarm/ ... nodes (visited on 01/15/2016).
[6] Docker Inc. Deploy and Manage Any Cluster Manager with Docker Swarm. 2015. url: https://blog.docker.com/2015/1 ... warm/(visited on 01/23/2016).
[7] Docker Inc. Docker Compose. 2015. url: https://docs.docker.com/swarm/swarm_at_scale/ (visited on 02/21/2016).
[8] Docker Inc. Docker Compose. 2015. url: https://github.com/docker/swar ... .json (visited on 02/21/2016).
[9] Docker Inc. Docker Compose — Swarm. 2015. url: https://github.com/docker/comp ... RM.md(visited on 01/23/2016).
[10] Docker Inc. Docker Hub. 2015. url: https://hub.docker.com/explore/ (visited on 01/21/2016).
[11] Docker Inc. Docker Machine — Drivers. 2015. url: https://docs.docker.com/machine/drivers/ (visited on 01/21/2016).
[12] Docker Inc. Docker Pricing. 2015. url: https://www.docker.com/pricing (visited on 01/21/2016).
[13] Docker Inc. Docker Swarm. 2015. url: https://github.com/docker/swarm (visited on 01/15/2016).
[14] Docker Inc. Docker Swarm. 2015. url: http://www.slideshare.net/Docker/docker-swarm-020 (visited on 01/15/2016).
[15] Docker Inc. Docker Swarm. 2015. url: https://docs.docker.com/engine ... ices/ (visited on 01/21/2016).
[16] Docker Inc. Docker Swarm. 2015. url: https://blog.docker.com /
2015/11/scale-testing-docker-swarm-30000-containers/ (visited
on 01/15/2016).
[17] Docker Inc. Docker Swarm API. 2015. url: https://docs.docker.com/swarm/api/swarm-api/(visited on 01/15/2016).
[18] Docker Inc. Docker Swarm filters — how to write filter expressions. 2015.
url: https://docs.docker.com/swarm/ ... sions
(visited on 01/15/2016).
[19] Docker Inc. Docker Swarm filters — use a constraint filter. 2015. url:
https://docs.docker.com/swarm/ ... ilter (visited on 01/15/2016).
[20] Docker Inc. Docker Swarm frontends. 2015. url: https://github.com/docker/swarm-frontends(visited on 01/23/2016).
[21] Docker Inc. Docker Swarm — health.go. 2015. url: https://github.com/docker/swar ... th.go (visited on 01/15/2016).
[22] Docker Inc. Docker Swarm strategies. 2015. url: https://docs.docker.
com/swarm/scheduler/strategy/ (visited on 01/15/2016).
[23] Docker Inc. How is Docker different from virtual machines? 2015. url:
https://www.docker.com/what-docker (visited on 01/21/2016).
[24] Elasticsearch Inc. Elasticsearch. 2016. url: https://www.elastic.co
(visited on 01/23/2016).
[25] Evan Hazlett. Interlock. 2015. url: https://github.com/ehazlett/interlock (visited on 02/21/2016).
[26] Google. Google Container Engine. 2015. url: https://cloud.google.com/container-engine/docs/(visited on 01/23/2016).
[27] Google. Kubernetes Large Cluster. 2015. url: http://kubernetes.io/v1.1/docs ... .html (visited on 01/15/2016).
[28] Google. Kubernetes — pods. 2015. url: http://kubernetes.io/v1.1/docs ... .html (visited on 01/15/2016).
[29] Google. Kubernetes predicates. 2015. url: https://github.com/kubernetes/ ... ease-1.1/plugin/pkg/scheduler/algorithm/predicates/predicates.go (visited on 01/15/2016).
[30] Google. Kubernetes priorities. 2015. url: https://github.com/kubernetes/ ... ease-1.1/plugin/pkg/scheduler/algorithm/priorities/priorities.go (visited on 01/15/2016).
[31] Google. Kubernetes scheduler. 2015. url: http://kubernetes.io (visited
on 01/15/2016).
[32] Google. Kubernetes scheduler. 2015. url: http://kubernetes.io/v1.1/docs ... .html (visited on 01/15/2016).
[33] Google. Kubernetes scheduler policy config. 2015. url: http://kubernetes.io/v1.1/exam ... .json(visited on 01/15/2016).
[34] Google. Kubernetes User Interface. 2015. url: http://kubernetes.io/v1.1/docs/user-guide/ui.html(visited on 01/15/2016).
[35] Benjamin Hindman et al. “Mesos: A platform for fine-grained resource
sharing in the data center”. In: (2011). url: https://www.cs.berkeley.edu/~alig/papers/mesos.pdf
[36] Linux Foundation. Open Containers Initiative. 2015. url: https://www.
opencontainers.org/ (visited on 01/21/2016).
[37] Mesosphere. Marathon — bridge. 2015. url: https://github.com/mesosphere/ ... ridge (visited on 01/15/2016).
[38] Mesosphere. Marathon — constraints. 2015. url: https://mesosphere.github.io/m ... .html (visited on 01/15/2016).
[39] Mesosphere. Marathon — GitHub repository. 2015. url: https://github.com/mesosphere/marathon(visited on 01/15/2016).
[40] Mesosphere. Marathon — health checks. 2015. url: https://mesosphere.github.io/m ... .html (visited on 01/15/2016).
[41] Mesosphere. Marathon — releases. 2015. url: https://github.com/mesosphere/marathon/releases(visited on 01/15/2016).
[42] Mesosphere. Marathon — service discovery and load balancing. 2015. url:
https://mesosphere.github.io/m ... .html (visited on 01/15/2016).
[43] Mesosphere. Marathon-lb. 2015. url: https://github.com/mesosphere/marathon-lb (visited on 01/15/2016).
[44] Mesosphere. Mesos DNS. 2015. url: https://github.com/mesosphere/mesos-dns (visited on 01/15/2016).
[45] Mesosphere. Mesosphere. 2016. url: https://mesosphere.com/ (visited
on 01/23/2016).
[46] Open Containers Initiative. runC. 2015. url: https://github.com/opencontainers/runc (visited on 01/21/2016).
[47] Prakhar Srivastav. FoodTrucks: San Francisco’s finger-licking street food
now at your fingertips. 2016. url: https://github.com/prakhar1989/FoodTrucks (visited on 01/23/2016).
[48] Malte Schwarzkopf et al. “Omega: flexible, scalable schedulers for large
compute clusters”. url: http://web.eecs.umich.edu/~mos ... a.pdf
[49] “Swarm v. Fleet v. Kubernetes v. Mesos”. In: (2015). url: http://radar.oreilly.com/2015/ ... html.
[50] The Apache Software Foundation. Apache Mesos. 2015. url: http://mesos.apache.org/ (visited on 01/15/2016).
[51] The Apache Software Foundation. Apache Mesos — Docker Containerizer. 2015. url: http://mesos.apache.org/docume ... izer/
(visited on 01/15/2016).
[52] The Apache Software Foundation. Apache Mesos — Frameworks. 2015. url: http://mesos.apache.org/docume ... orks/ (visited
on 01/15/2016).
The Apache Software Foundation. Apache ZooKeeper. 2015. url: https://cwiki.apache.org/confl ... ption(visited on 01/21/2016).
[54] Abhishek Verma et al. “Large-scale cluster management at Google with
Borg”. In: Proceedings of the Tenth European Conference on Computer
Systems — EuroSys ’15 (2015), p. 13. url: http://static.googleuserconten ... 8.pdf
[55] Vinod Kumar Vavilapalli et al. “Apache Hadoop YARN:Yet Another
Resource Negotiator”. In: (2013), p. 16. url: http://www.socc2013.org/home/p ... i.pdf

原文鏈接:Comparison of Container Schedulers(翻譯:楊潤青)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章