1. 程式人生 > >Swarm Kubernetes Marathon 編排引擎對比剖析_Kubernetes中文社群

Swarm Kubernetes Marathon 編排引擎對比剖析_Kubernetes中文社群

Docker Native Orchestration

20161117150554

基本結構

Docker Engine 1.12 集成了原生的編排引擎,用以替換了之前獨立的Docker Swarm專案。Docker原生叢集(Swarm)同時包括了(Docker Engine \/ Daemons),這使原生docker可以任意充當叢集的管理(manager)或工作(worker)節點角色。工作節點 (worker) 將負責執行執行你啟動的容器任務,而管理節點從使用者那裡獲得任務說明,負責整合現有的叢集,維護叢集狀態。並且您可以有推薦的數量不超過七個人管理節點以支援高可用。管理節點會保障叢集內部環境狀態的強一致性,它們基於 Raft協議實現狀態一致及備份 ,與所有一制性演算法一樣,擁有更多manager管理節點( manager )意味著更多的效能開銷,同時在manager節點內部保持一致性的事實讓你在Docker原生編排沒有外部依賴性,叢集管理更容易。

可用性

Docker將單節點Docker的使用概念擴充套件到Swarm叢集。如果你熟悉docker那你學習swarm相當容易。你也可以相當簡單將docker環境到遷移到執行swarm叢集,(譯者按:如果現有系統使用Docker Engine,則可以平滑將Docker Engine切到Swarm上,無需改動現有系統)。

你只需要在其中的一個docker節點執行使用 docker swarm init命令建立一個叢集,在您要新增任何其他節點,通過docker swarm join命令加入到剛才建立的叢集中。之後您可以象在一個獨立的docker環境下一樣使用同樣的Docker Compose的模板及相同的docker命令列工具。

功能集

Docker Native Orchestration 使用與Docker Engine和Docker Compose來支援。您仍然可以使用象原先在單節點一樣的連結(link),建立卷(volume)和定義公開埠(expose)功能。 除了這些,還有兩個新的概念,服務( services )和網路( networks )。

docker services (服務)是管理在節點上啟動的一定數量的始終保持執行的一組容器,並且如果其中一個容器死了,它支援自動更換。有兩種型別的服務,複製(replicated)或全域性(global)。 複製(replicated)服務在叢集中維護指定數量的容器(意味著這個服務可以隨意 scale),全域性(global)服務在每個群集節點上執行容器的一個例項(譯者按:不多, 也不少)。 要建立複製(replicated)服務,請使用以下命令。

docker service create \
 –name frontend \
 –replicas 5 \
 -network my-network \
 -p 80:80/tcp nginx:latest.

您可以使用docker network create–driver overlay NETWORK_NAME 建立命名的overylay網路。使用指定的overylay網路,您可以在你的容器內建立孤立(isolated)的,平面化的(flat),加密(encrypted)的跨節點的主機虛擬網路。

你可以使用constraints加labels 來做一些基礎的容器排程工作。 使用constraints 引數您可以向服務新增關聯有指定標籤的節點上啟動容器。

docker service create \
 –name frontend \
 –replicas 5 \
 -network my-network \
 --constraint engine.labels.cloud==aws \
 --constraint node.role==manager \
 -p 80:80/tcp nginx:latest.

此外,您可以使用 reserve CPU 和reserve memory標記來定義服務中的每個容器使用的資源量,以便在群集上啟動多個服務時,以最小化資源爭用放置容器(譯者按:容器會被部署到最適合它們的位置,最少的容器執行,最多的CPU或者記憶體可用,等等)。

--limit-cpu value Limit CPUs (default 0.000) \
 --limit-memory value Limit Memory (default 0 B) \
 --reserve-cpu value Reserve CPUs (default 0.000) \
 --reserve-memory value Reserve Memory (default 0 B)

您可以使用以下命令進行基本的滾動部署。這將更新服務的容器映象,但這樣做,每次2個容器,每兩組之間有10s的間隔。但是不支援執行狀況檢查和自動回滾。

docker service update \
 –name frontend \
 –replicas 5 \
 -network my-network \
 --update-delay 10s \
 --update-parallelism 2 \
 -p 80:80/tcp nginx:other-version.

Docke 支援使用卷驅動( volume drivers )程式支援永續性卷掛載,並且使用Native orchestration 為其service create命令擴充套件支援了mount選項。 將以下程式碼段新增到上面的命令將會將NFS掛載到您的容器中。請注意這需要在Docker外部的主機上已經設定好NFS,一些其他驅動程式添加了對Amazon EBS卷驅動程式或Google容器引擎卷驅動程式的支援能夠在不需要主機設定的情況下工作。 此外,這個因為這些功能還沒有很好的文件,可能需要一些測試並參考github issue以在docker專案得到執行。

--mount type=volume,src=/path/on/host,volume-driver=local, \
 dst=/path/in/container,volume-opt=type=nfs, \
 volume-opt=device=192.168.1.1:/your/nfs/path

Kubernetes

20161117150603

基本結構

從概念上講,Kubernetes類似於Swarm的唯一點就是它也使用一個RAFT的Master節點來保證強一制性。同時為達成目的Kubernetes採用了ETCD。此外它將使用一個外部的擴充套件的網路層,是像overlay ,weave網路等。使用這些外部工具,您可以啟動Kubernetes主要的元件; 象API伺服器(API Server),控制器管理器(Controller Manager)和排程程式(Scheduler),這些通常作為Kubernetes pod在主(master)節點上執行。除了這些,你還需要在每個節點(node)上執行kubelet和kubeproxy。工作節點(Worker nodes)只執行Kubelet和Kubeproxy以及一個網路層提供者象是flanneld。

20161117150609

在以上設定中,kubelet的主要功能就是獲取節點上 pod\/container 的期望狀態(執行什麼容器、執行的副本數量、網路或者儲存如何配置等等),kubelet將使用主(master)節點上的controller manager操作指定的節點上 pod\/containers。排程器(scheduler)負責資源分配和平衡資源,在具有最多可用資源的工作節點(worker node)上放置容器。 API控制器負責您的本地kubectl CLI將向叢集發出命令。 最後,kubeproxy元件用於為Kubernetes中定義的服務提供負載平衡和高可用性。

可用性

從頭開始設定Kubernetes是一個困難的過程,因為它需要設定etcd,網路外掛,DNS伺服器和證書頒發機構一系統操作。 從頭開始建立Kubernetes的詳細文件您可瀏覽這裡,但幸運的是在Rancher已經整合做好這一切的設定。在之前的文章中我們已經有過介紹如何在Rancher中設定 kubernetes。

除了初始設定,Kubernetes仍然有一些陡峭的學習曲線,因為它使用自己的術語和概念。Kubernetes使用資源型別,如Pods、Deployments、Replication Controllers、Services、Daemon sets等來定義部署。 這些概念都不是Docker詞典的一部分,因此您需要在開始建立第一個部署之前熟悉它們。 此外,其中的一些概念與Docker衝突, 例如Kubernetes Services 概念上並不等同於Docker Services ,(Docker Services更貼近地對映到Kubernetes世界中的Deployments) ,還有您使用kubectl而不是docker CLI與來用於群集互動, 同時您還必須使用Kubernetes配置檔案,而不是docker compose檔案。

Kubernetes有這樣一套獨立於核心Docker的概念本身並不是一件壞事。 Kubernetes提供比Docker更豐富的功能集。 然而,Docker也在迅速將新增更多的功能來與Kubernetes競爭,它們具有不同的實現方式及衝突的概念。這將肯定導致重現象CoreOS與rkt之間這種類似功能但競爭的解決方案情況。 但今天來看,Docker Swarm和Kubernetes的目標還是非常不同的用例(Kubernetes更適合於使用於有專門的叢集管理團隊的面向服務的架構的大型生產部署),然而隨著Docker Native Orchestration的成熟,與它同臺競爭的時刻一定會到來。

功能集

Kubernetes的完整功能集太大了,不能涵蓋在本文中,但我們將討論一些基本概念和一些有趣的區別。 首先,Kubernetes使用Pods的概念作為其縮放的基本單位,而不是單個容器。 每個pod是一組容器(設定可以是1),這一組容器它們總是在同一節點上啟動,共享相同的卷並分配一個虛擬IP(VIP),以便它們可以在叢集中定址。 單個pod的Kubernetes規範檔案如下所示。

kind: Pod
 metadata:
 name: mywebservice
 spec:
 containers:
 - name: web-1-10
 image: nginx:1.10
 ports:
 - containerPort: 80

接下來展開 Deployment 設定,這些鬆散對映服務到Docker原生編排。您可以像Docker Native中的服務一樣擴充套件部署執行請求數量的容器。需要的是注意,Deployment僅類似於Docker本地中的複製服務,如Kubernetes使用守護程式集概念( Daemon Set) 來支援其等效的全域性排程(globally scheduled)服務。部署還支援使用HTTP或TCP可達性或自定義exec命令進行狀況檢查以確定 容器\/pod執行是否正常,同時支援使用執行狀況檢查的自動回滾部署,以保障每個pod部署成功。

kind: Deployment
 metadata:
 name: mywebservice-deployment
 spec:
 replicas: 2 # We want two pods for this deployment
 template:
 metadata:
 labels:
 app: mywebservice
 spec:
 containers:
 - name: web-1-10
 image: nginx:1.10
 ports:
 - containerPort: 80

接下來它為部署提供簡單的負載平衡。 部署中的所有pod將在服務進入和退出時註冊到服務(service),service 也抽象出多個Deployment,因此如果您想執行滾動部署,您將使用相同的service註冊兩個Kubernetes Deployment,然後逐步將pod新增到其中一個的同時從其他Deployment減少pod。 您甚至可以進行藍綠部署,在那裡您可以一次性將服務指向新的Kubernetes Deployment。 最後,服務對您的Kubernetes叢集中的服務發現也很有用,叢集中的所有服務都獲得VIP,並且象docker link 風格的環境變數很好的整合的DNS伺服器暴露給叢集中的所有pod。

除了基本的服務,Kubernetes支援Jobs, Scheduled Jobs, and Pet Sets,Jobs建立一個或多個pod,並等待直到它們終止。作業確保你有指定數量的pod完成作業。例如,您可以開始一個作業(job),在最後一天開始處理1小時的商業智慧資料。它將啟動一個包含前一天的24個pod的作業,一旦它們都執行完成,作業才完成。scheduled job名稱暗示了計劃作業是在給定計劃之上自動執行的作業。在我們的例子中,我們可能使我們的BI處理器是每日計劃的工作。 scheduled 作業非常適合向叢集發出批量處理風格的工作負載,這些負載不是總是一直啟動的服務,而是需要執行完成然後自動清理的任務。

Kubernetes提供給基本服務的另一個擴充套件是Pet Sets,(編者按:它是 Kubernetes 1.3 引入的物件型別,目的是改善對有狀態服務的支援)。Pet Sets支援通常非常難以容器化的有狀態服務的工作負載。這包括資料庫和有實時性連線需求的應用程式。Pet Sets為集合中的每個“Pet”提供穩定的主機名設定。Pet是可被索引; 例如,pet5將獨立於pet3可定址,並且如果pet3容器\/pod死掉,則它將使用相同索引資訊(index)和主機名(hostname)的新主機上重新啟動。

Pet Sets還提供了穩定的儲存持久卷,也就是說,如果PET1死亡,它將重新啟動在另一個節點並重新掛載原來資料卷。此外,您還可以使用NFS或其他網路檔案系統在容器之間共享卷,即使它們在不同的主機上啟動。這解決了從單主機到分散式Docker環境轉換時最困難的問題之一。

Pet Sets還提供對等體發現(peer-discovery),通常的服務,你可以發現其他服務(通過Docker link等),然而,發現服務內的其他容器是不可能的。這使得基於gossip協議的服務,如Cassandra和Zookeeper非常難以啟動。

最後,Pet Sets提供啟動和排序,這是持久,可擴充套件的服務如Cassandra的必要條件。Cassandra依賴一組種子節點,當您擴充套件服務時,必須確保種子節點是第一個啟動的節點和最後一個要刪除的節點。在撰寫本文時,Pet Sets是Kubernetes的一大特色,因為在沒有這種支援的情況下,持久的有狀態工作負載幾乎不可能在Docker的生產規模上執行。

Kubernetes還在群集級別上提供了名稱空間(namespaces),隔離工作負載的安全管理(secrets management)和自動擴充套件(auto-scaling)支援。 所有這些特性更意味著Kubernetes也支援大型,多樣化的工作負載,Docker Swarm目前還沒有這些特性。

馬拉松(Marathon)

20161117150621

基本結構

大規模叢集的另一個常見的編排設定選擇是在Apache Mesos之上執行Marathon。Mesos是一個開源叢集管理系統,支援各種各樣主機上的工作負載。Mesos在群集中的每個主機上執行的Mesos代理,向master主機報告其可用資源。 Mesos 利用多臺 Mesos master 來實現高可用性(high-availability),包括一個活躍的 master (譯者按:叫做 leader 或者 leading master)和若干備份 master 來避免宕機。 通過 Apache ZooKeeper 選舉出活躍的 leader,然後通知叢集中的其他節點,包括其他Master,slave節點和排程器(scheduler driver)。在任何時間,master節點之一使用主選舉過程是活動著的。master可以向任何Mesos agent發出任務,並報告這些任務的狀態。雖然您可以通過API發出任務,但正常的方法是在Mesos之上使用一個framework框架。Marathon就是一個這樣的framework框架,它為執行Docker容器(以及本地Mesos容器)提供支援。

可用性

與Swarm相比,Marathon有一個相當陡峭的學習曲線,因為它不與Docker分享大部分概念和術語。然而,馬拉松( Marathon )功能並不豐富,因此比起Kubernetes更容易學習。管理Marathon部署的複雜性主要來自於它是架構在Mesos之上的事實,因此有兩層工具要管理。此外, 馬拉松 (Marathon)的一些更高階功能(如負載平衡)僅支援在Marathon之上執行的附加框架提供。 某些功能(如身份驗證)只有在DC\/OS上執行馬拉松(Marathon時)才可使用,而後者又在Mesos上執行 – 這為堆疊新增另一層抽象。

功能集

要在Marathon中定義服務,您需要使用其內部JSON格式,如下所示。 一個簡單的定義,如下面的一個將建立一個服務,執行兩個nginx容器例項。

{
 "id": "MyService"
 "instances": 2,
 "container": {
 "type": "DOCKER",
 "docker": {
 "network": "BRIDGE",
 "image": "nginx:latest"
 }
 }
 }

一個略微更完整些的版本如下所示,我們現在新增埠對映和健康檢查。 在埠對映中,我們指定一個容器埠,這是docker容器公開的埠。 主機埠定義主機公共介面上的哪個埠對映到容器埠。 如果為主機埠指定0,則在執行時分配隨機埠。 類似地,我們可以可選地指定服務埠。服務埠用於服務發現和負載平衡,如本節後面所述。 使用健康檢查,我們現在既可以做滾動(預設)和藍綠部署

{
 "id": "MyService"
 "instances": 2,
 "container": {
 "type": "DOCKER",
 "docker": {
 "network": "BRIDGE",
 "image": "nginx:latest"
 "portMappings": [
 { "containerPort": 8080, "hostPort": 0, "servicePort": 9000, "protocol": "tcp" },
 ]
 }
 },
 "healthChecks": [
 {
 "protocol": "HTTP",
 "portIndex": 0,
 "path": "/",
 "gracePeriodSeconds": 5,
 "intervalSeconds": 20,
 "maxConsecutiveFailures": 3
 }
 ]
 }

在單一服務之外,您還可以定義馬拉松 (Marathon)應用程式組( Application Groups )用於巢狀樹結構的服務。在組中定義應用程式的好處是能夠將整個組縮放在一起。這是非常有用的在微服務棧場景中因為單獨去調整每個服務是相對困難的。到這一步,我們進一步假設所有服務將以相同的速率擴充套件,如果您需要一個服務的“n”個例項,您將獲得所有服務的“n”個例項。

{
 "id": "/product",
 "groups": [
 {
 "id": "/product/database",
 "apps": [
 { "id": "/product/mongo", ... },
 { "id": "/product/mysql", ... }
 ]
 },{
 "id": "/product/service",
 "dependencies": ["/product/database"],
 "apps": [
 { "id": "/product/rails-app", ... },
 { "id": "/product/play-app", ... }
 ]
 }
 ]
 }

在定義基本的服務之外,馬拉松 (Marathon )還可以做基於指定容器的約束條件排程,詳見這裡,包括指定該服務的每個例項必須在不同的物理主機 “constraints”: [[“hostname”, “UNIQUE”]].您可以使用的CPU和mem標籤指定容器的資源利用率。每個Mesos代理報告其總資源可用性,因此排程程式可以以智慧方式在主機上放置工作負載。

預設情況下,Mesos依賴於傳統的Docker埠對映和外部服務發現和負載均衡機制。 而最近的測試版功能添加了使用基於DNS服務發現支援Mesos DNS或負載均衡使用Marathon LB。

Mesos DNS是一個在Mesos之上執行的應用程式,它查詢Mesos API以獲取所有正在執行的任務和應用程式的列表。然後,它為執行這些任務的節點建立DNS記錄。之後所有Mesos代理需要手動更新使用Mesos DNS伺服器作為其主DNS伺服器。Mesos DNS使用主機名或IP地址用於Mesos agent向master主機註冊,埠對映可以查詢為SRV記錄。

Marathon DNS使用agent的主機名,所以必須確保主機網路相應埠開啟且不能發生衝突。Mesos DNS提供了與眾不同的方法來為有狀態負載引用,例如我們將能夠結合使用Kubernetes pet sets。此外與Kubernetes有群集內任何容器可定址的VIP機制不同,Mesos必須手動將\/etc\/resolve.conf更新到Mesos DNS伺服器集,並在DNS伺服器變更時需要更新配置。 Marathon-lb使用Marathon Event bus 跟蹤所有服務的啟動和撤銷狀態。然後它在agent節點上啟動HAProxy例項,以將流量中繼到必需的服務節點。

馬拉松(Marathon)的測試版支援持久卷,以外部永續性卷(external persistent volumes) 。然而,這兩個特徵都處於非常原始的狀態。持久卷只支援容器在單個節點上重新啟動時支援持久化資料卷,但是會刪除卷如果刪除使用它們的應用的時候,當然磁碟上的實際資料不會被刪除,volume必須手動刪除。外部永續性卷的支援則限制在必須在DC\/OS之上執行,並且當前只允許您的服務擴充套件到單個例項。

總結

現在我們看了Docker容器編排的三個選項:Docker Native(Swarm),Kubernetes和Mesos\/Marathon。很難選擇一個系統來推薦,因為最好的系統高度依賴於你的具體用例需求,部署規模和應用歷史原因。此外,所有三個系統現在還都在大量開發中,上面總結的一些功能中包括了測試版本,有可能會很快更改,刪除或被替換。

Docker Native給你提供了最快的適應的通道,並且它很少甚至沒有對Docker的依賴之外的供應商鎖定問題。唯一的對Docker本身的依賴不是一個大問題,因為docker 已經成為了事實上的容器標準。鑑於在編排引擎的市場競爭中目前還沒有明確的贏家,而且Docker本機是最靈活的方法,因此它是簡單的Web及無狀態應用程式的不錯選擇,但是,Docker Native目前是初始的狀態,如果你需要得到複雜的,大規模的應用程式到生產,你需要選擇一個Mesos\/Marathon或Kubernetes。

在Mesos\/Marathon和Kubernetes之間也不是一個容易的選擇,因為兩者都有自己的優點和缺點。在兩者之中Kubernetes肯定是更豐富和成熟的,但它也是一個非常有固執的(有個性的)軟體(譯者按:Kubernetes有些固執己見對於容器如何組織和網路強制了一些概念),我們認為很多這些意見是有意義的。同時Kubernetes沒有馬拉松的靈活性,尤其當你考慮那些沒有Docker,沒有容器化的應用程式可以執行在Mesos(例如Hadoop叢集)的豐富的歷史。 如果你正在做一個綠色領域實施,也沒有強烈的意向如何佈局叢集,或你的需求想法與谷歌相同,那麼Kubernetes是一個更好的選擇。相反,如果你有大的,複雜的遺留工作負載,並將逐漸轉移到容器化,那Mesos\/Marathon是要走的路。

另一個問題是規模:Kubernetes已經測試了數千個節點,而Mesos已經測試了成千上萬的節點。如果您正在啟動具有數萬個節點的叢集,則需要使用Mesos來獲得底層基礎架構的可擴充套件性 – 但請注意,將高階功能(例如負載平衡)擴充套件到該範圍仍將保留。然而,在那個規模,很少有現成的解決方案,如果有的話它也需要不斷仔細調整及不斷的改造。