Rancher的最新版本增長了對幾個常見編排引擎的支持。 除了Cattle以外新加支持三個Docker社區中使用最普遍的編排引擎,包括Swarm(Docker Native Orchestration)、Kubernetes和Mesos,它們將爲用戶提供了更多的功能及可用的編排選項。雖然Docker如今已經發展成爲容器化領域的事實標準,但在細分的docker編排引擎市場中目前並無明確的贏家。在本文中,咱們將討論三個編排引擎系統的功能和特性,並給出它們可能適用的場景用例的建議。
Docker Native Orchestration目前是相對來講項目較新,但它成長速度很快並不斷的加入新功能。因爲它是Docker官方自己推出的,所以有良好的工具和社區支持,是許多開發人員的默認選擇。
Kubernetes是當今最普遍使用的容器編排系統之一,而且獲得了Google的支持。
最後Mesos與Mesosphere(或Marathon,其開放源代碼版本)支持分層、分類的服務管理方法,許多管理功能可基於獨立的插件和應用程序。 由於架構的靈活性這使得它更容易深度定製化部署。固然,這也意味着須要更多的整合工做量。而Kubernetes的常見案例則更偏向於如何構建集羣和交付完整統一的綜合系統 。
node
Docker Engine 1.12 集成了原生的編排引擎,用以替換了以前獨立的Docker Swarm項目。Docker原生集羣(Swarm)同時包括了(Docker Engine \/ Daemons),這使原生docker能夠任意充當集羣的管理(manager)或工做(worker)節點角色。工做節點 (worker) 將負責執行運行你啓動的容器任務,而管理節點從用戶那裏得到任務說明,負責整合現有的集羣,維護集羣狀態。而且您能夠有推薦的數量不超過七我的管理節點以支持高可用。管理節點會保障集羣內部環境狀態的強一致性,它們基於 Raft協議實現狀態一致及備份 ,與全部一制性算法同樣,擁有更多manager管理節點( manager )意味着更多的性能開銷,同時在manager節點內部保持一致性的事實讓你在Docker原生編排沒有外部依賴性,集羣管理更容易。
mysql
Docker將單節點Docker的使用概念擴展到Swarm集羣。若是你熟悉docker那你學習swarm至關容易。你也能夠至關簡單將docker環境到遷移到運行swarm集羣,(譯者按:若是現有系統使用Docker Engine,則能夠平滑將Docker Engine切到Swarm上,無需改動現有系統)。
你只須要在其中的一個docker節點運行使用 docker swarm init命令建立一個集羣,在您要添加任何其餘節點,經過docker swarm join命令加入到剛纔建立的集羣中。以後您能夠象在一個獨立的docker環境下同樣使用一樣的Docker Compose的模板及相同的docker命令行工具。
nginx
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
git
從概念上講,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。github
在以上設置中,kubelet的主要功能就是獲取節點上 pod\/container 的指望狀態(運行什麼容器、運行的副本數量、網絡或者存儲如何配置等等),kubelet將使用主(master)節點上的controller manager操做指定的節點上 pod\/containers。調度器(scheduler)負責資源分配和平衡資源,在具備最多可用資源的工做節點(worker node)上放置容器。 API控制器負責您的本地kubectl CLI將向集羣發出命令。 最後,kubeproxy組件用於爲Kubernetes中定義的服務提供負載平衡和高可用性。
web
從頭開始設置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目前尚未這些特性。
sql
大規模集羣的另外一個常見的編排設置選擇是在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容器)提供支持。
docker
與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來得到底層基礎架構的可擴展性 - 但請注意,將高級功能(例如負載平衡)擴展到該範圍仍將保留。然而,在那個規模,不多有現成的解決方案,若是有的話它也須要不斷仔細調整及不斷的改造。
推薦閱讀
☑ 如何快速利用Harbor搭建本身的企業級registry server?
☑ 項目中調用Rancher Rest API實踐
☑ 開發Go項目最簡單的方式-一個基於Docker的go工具