从HashiCorp Nomad对上百万容器进行调度所学到的经验
?
Docker在2013年三月實現(xiàn)了開源發(fā)布,它的出現(xiàn)讓軟件開發(fā)行業(yè)對于現(xiàn)代化應(yīng)用的打包以及部署方式發(fā)生了巨大的變化。緊隨著Docker的發(fā)布,各種具有競爭性、致敬性以及支持性的容器技術(shù)紛紛涌現(xiàn),為這一領(lǐng)域帶來了極大的關(guān)注度,同時也引起了人們的反思。這一系列文章將解答讀者的各種困惑,對如何在企業(yè)中實際使用容器進行分析。
這一系列文章首先將對容器背后的核心技術(shù)進行觀察,了解開發(fā)者目前如何使用容器,隨后將分析在企業(yè)中部署容器的核心挑戰(zhàn),例如如何將容器技術(shù)與持續(xù)集成和持續(xù)交付管道進行集成,并對監(jiān)控方式進行改進,以支持不斷變化的負載,以及使用短期容器的潛在需求。本系列文章的總結(jié)部分將對容器技術(shù)的未來進行分析,并探討無核化技術(shù)(unikernels)目前在處于技術(shù)前沿的組織中所扮演的角色。
本文是本系列文章“實際應(yīng)用中的容器 —— 遠離炒作”中的其中一篇。你可以通過RSS訂閱該系列文章,以獲取更新的通知。
高效的調(diào)度器需要具備三種品質(zhì)。第一項是能夠滿足多個開發(fā)團隊要求同時部署應(yīng)用的需求。第二項是能夠快速地在跨全球的基礎(chǔ)設(shè)施范圍內(nèi)分發(fā)應(yīng)用。最后一項則是重新調(diào)度應(yīng)用程序,讓有故障的節(jié)點重新成為健康的節(jié)點,提供集群范圍的應(yīng)用程序可用性管理,以及自恢復(fù)的能力。、以Nomad、Mesos和Kubernetes為代表的調(diào)度器的目標是讓組織能夠以更快的步調(diào)部署更多的應(yīng)用程序,同時提高資源的使用率。調(diào)度器可將應(yīng)用程序與基礎(chǔ)設(shè)施進行分離,因此在一個host上可運行多個應(yīng)用,而不再受到一個host僅運行一個應(yīng)用的限制。這就提高了集群中資源的利用率,并節(jié)省基礎(chǔ)設(shè)施方面的成本。
由HashiCorp的設(shè)計的百萬級容器挑戰(zhàn)(Million Container Challeng)是用于檢測其調(diào)度器產(chǎn)品Nomad在5000個host上對100萬容器進行調(diào)度的效率的一種測試手段。這一挑戰(zhàn)的目的是觀察Nomad在超大規(guī)模部署的情況下的表現(xiàn),并對其進行優(yōu)化。現(xiàn)代化企業(yè)配備的數(shù)據(jù)中心規(guī)模之大是前所未有的,他們所使用的工具也必須滿足客戶的需求。在完成這一測試并進行了性能優(yōu)化之后,Nomad在Google Cloud上可做到在5分鐘之內(nèi)對跨5000個host上的100個容器進行調(diào)度。本文將描述從對100萬個容器進行調(diào)度的實現(xiàn)中所學(xué)到的知識。
(點擊放大圖像)
樂觀并發(fā)調(diào)度器能夠以線性增長率擴展調(diào)度的吞吐量
調(diào)度器一般來說可以分為三個類別:集中式(monolithic)調(diào)度器、基于offer的調(diào)度器,以及狀態(tài)共享(shared state)調(diào)度器。集中式調(diào)度器在一個單一的、中心化的地方處理調(diào)度邏輯,通常會綁定在一臺單一的機器上。基于offer的調(diào)度器(例如Mesos)同樣在一個單一的地方進行調(diào)度決策,但可以通過將資源分配給多個各自具備任務(wù)的框架而實現(xiàn)并行化。而狀態(tài)共享調(diào)度器則在多個地方處理調(diào)度決定,通過并發(fā)控制,以并行方式進行調(diào)度而獲得統(tǒng)一的狀態(tài)。
Nomad是一種樂觀并發(fā)的共享狀態(tài)調(diào)度器,這意味著所有服務(wù)器都可以并行地參與調(diào)度決策。主節(jié)點將提供額外的協(xié)調(diào)功能,這是實現(xiàn)并發(fā)決策,并確??蛻舳瞬粫a(chǎn)生過量訂閱所不可缺少的。在這次百萬級容器挑戰(zhàn)中,共有5臺Nomad服務(wù)運行在Google Cloud上的n1-standard-32實例上,形成了一個CPU總數(shù)達到160的Nomad服務(wù)器集群。主節(jié)點使用了一半的CPU核進行調(diào)度工作,因此總共可以并行進行140個調(diào)度決策。這種并行性使得Nomad能夠在總時間5分鐘的挑戰(zhàn)中做到每秒大約對3750個容器進行調(diào)度。
在對Nomad的設(shè)計進行分析之前,有必要解釋一下Nomad的術(shù)語:作業(yè)(job)是指對提交至調(diào)度器的某項工作的聲明,而作業(yè)是由多個任務(wù)(task)所組成的。一個任務(wù)即是指將要運行的應(yīng)用程序,在這示例中即表示通過一個Docker容器運行一個簡單的Go服務(wù)。
Nomad的樂觀并發(fā)設(shè)計受到了Google?Omega的啟發(fā),后者引入了并發(fā)、共享狀態(tài)、以及無鎖樂觀并發(fā)控制等方式,以應(yīng)對在其上一代調(diào)度器Borg中所遇到的挑戰(zhàn)。并發(fā)性使調(diào)度器實現(xiàn)了伸縮性,體現(xiàn)在為大量任務(wù)(容器或應(yīng)用程序)找到居所,以及為多個開發(fā)團隊提供服務(wù)。多個開發(fā)團隊可同時提交作業(yè),而調(diào)度器則能夠并行地處理這些作業(yè)的任務(wù)。對于那些無法實現(xiàn)并行調(diào)度的調(diào)度器來說,一旦某個團隊提交了一項作業(yè),就會阻塞其他團隊同時對其他作業(yè)進行調(diào)度的操作。在像Google這樣規(guī)模的公司中,開發(fā)者提交作業(yè)以及機器獲取作業(yè)的數(shù)量都是非常龐大的,因此這種類型的并行設(shè)計就顯得非常關(guān)鍵。Nomad的出現(xiàn)受益于一些最新的研究成果,它最終為開源社區(qū)帶來了一個頂尖水準的調(diào)度器。
(點擊放大圖像)
如果讀者想了解Nomad的調(diào)度設(shè)計的更多信息,請閱讀開源網(wǎng)站上對其架構(gòu)詳細的描述。
貪心調(diào)度算法與擴散調(diào)度算法之間的權(quán)衡
調(diào)度算法共有兩種主要的算法,即貪心(bin pack)算法與擴散(spread)算法。Nomad所使用的是貪心算法,這意味著它會嘗試用盡當前節(jié)點的全部資源,隨后再將新的任務(wù)傳遞至某個不同的節(jié)點。與之相反,擴散算法會盡量保證所有節(jié)點的使用率保持均衡。貪心算法的優(yōu)點在于它可支持更多不同的工作量,最大化資源的利用和使用率,這最終將使基礎(chǔ)設(shè)施的成本降至最低。而擴散算法的優(yōu)點在于它能夠?qū)L(fēng)險進行分散,如果某臺機器產(chǎn)生了故障,該算法可減少響應(yīng)及恢復(fù)的復(fù)雜性。如果某臺機器僅運行一至兩個任務(wù),那么為這些任務(wù)找到新的節(jié)點非常容易。與之相反,如果某個發(fā)生故障的機器運行著200個任務(wù),那么調(diào)度器就必須為這200個任務(wù)找到新的位置。
使用貪心算法時,隨著節(jié)點上處理的任務(wù)越多,之后的任務(wù)就越有可能匯聚到這個節(jié)點上,直到這臺機器的能力達到極限為止。這種方式確保了某個節(jié)點將最大化地處理任務(wù),之后調(diào)度器才會將新的任務(wù)發(fā)送至某個新的節(jié)點上。此外,如果需要為某個占用大量資源的任務(wù)找到合適的節(jié)點,這種方式也能更方便地找到一個具有足夠可用資源的節(jié)點,也能夠更方便地關(guān)閉某些沒有使用的機器。
簡單的作業(yè)規(guī)范使對作業(yè)提交的管理具有可伸縮性
使調(diào)度器具備對上百萬容器進行調(diào)度的能力只是整個挑戰(zhàn)中的一部分。另一個挑戰(zhàn)在于能否讓開發(fā)者方便地提交大規(guī)模的作業(yè)。Nomad的作業(yè)規(guī)范采用了一種聲明式的風(fēng)格,非常易于使用。
在下面這個示例中,“bench-docker-classlogger”這個作業(yè)在定義中表示它希望Nomad能夠為“classlogger_tg_1”這個任務(wù)組調(diào)度20個實例,在該任務(wù)組中包含了“classlogger_1”這個任務(wù)。這個任務(wù)對應(yīng)著一個Docker鏡像,它需求20MHZ的CPU、15M的內(nèi)存以及10M的磁盤空間。當這個作業(yè)被提交至Nomad后,它會在整個服務(wù)器集群中調(diào)度20個可用資源的實例,在這些位置運行20個Docker鏡像。如果實例數(shù)量從20提升至50,那么Nomad只需再調(diào)度30個任務(wù)即可。
作業(yè)的規(guī)范還允許開發(fā)者對于任務(wù)可在何種類型的host上進行調(diào)度加以限制。舉例來說,某個開發(fā)者希望將某些任務(wù)限制在Windows機器上、某個規(guī)格的機器、或?qū)⑺凶鳂I(yè)分散在不同的host上運行。最后,重啟策略這部分定義了Nomad如何對失敗的任務(wù)進行重啟。在這個示例中,該Nomad作業(yè)設(shè)置了一個重啟管理器,可防止某個任務(wù)在5分鐘內(nèi)重啟超過3次。
job "bench-docker-classlogger" {datacenters = ["us-central1"]group "classlogger_tg_1" {count = 20constraint {attribute = "${node.class}"value = "class_1"}restart {mode = "fail"attempts = 3interval = "5m"delay = "5s"}task "classlogger_1" {driver = "docker"config {image = "hashicorp/nomad-c1m:0.1"network_mode = "host"}resources {cpu = 20memory = 15disk = 10}}} }重要的是,作業(yè)規(guī)范是聲明式的,它定義了被提交作業(yè)的理想狀態(tài)。用戶只需表示需要運行該作業(yè),而無需表達應(yīng)當在何處運行該作業(yè)。Nomad的職責(zé)是確保實際的狀態(tài)滿足了用戶所設(shè)想的狀態(tài)。這就使對大型群集與大量作業(yè)提交的管理變得簡單許多,因為用戶不必再設(shè)法讓實際狀態(tài)去匹配理想狀態(tài),Nomad已經(jīng)自動地完成了這一工作。
無論是在開發(fā)者還是機器在層面,可伸縮性都是必須考慮到的部分。在機器層面上,Nomad的樂觀并發(fā)設(shè)計使大規(guī)模化變得可能。而在開發(fā)者或組織層面上,簡單的作業(yè)規(guī)范使作業(yè)的提交很容易實現(xiàn)大規(guī)?;?。
在進行大規(guī)模的容器調(diào)度時,服務(wù)發(fā)現(xiàn)是必不可少的
要使在5000個host上調(diào)度100個容器的能力體現(xiàn)出實用性,你必須做到在這些容器已確定位置后發(fā)現(xiàn)他們的具體位置。從邏輯上說,以手動方式對這種規(guī)模的服務(wù)配置進行更新是不可能的,因此必須借助自動化方案的力量。
以HashiCorp的Consul或ZooKeeper為代表的服務(wù)發(fā)現(xiàn)工具使服務(wù)能夠?qū)⒆陨砼c他們的地址注冊在某個中央注冊表中。群集中的其他服務(wù)則通過這個中央注冊表發(fā)現(xiàn)他們所需要連接的服務(wù)。舉例來說,如果在30個host上調(diào)度了50個API的任務(wù),那么每個任務(wù)都會它將的地址與端口注冊在服務(wù)注冊表中。群集中的其他服務(wù)則可以通過這個注冊表查詢這50個實例的地址與端口,以用于配置及負載均衡。如果某個任務(wù)失敗了,調(diào)度器就可以在不同的地址重新調(diào)度它,這個新的地址會在服務(wù)注冊表中進行更新,整個集群都將收到這個變更信息。而如果某個host產(chǎn)生了故障,調(diào)度器就需要改變運行在該host上的所有任務(wù)的地址,這些任務(wù)都需要在服務(wù)注冊表中更新他們的信息。
在大規(guī)模環(huán)境中,一個基于調(diào)度器的應(yīng)用交付工作流更能表現(xiàn)出高度的動態(tài)能力。作業(yè)的調(diào)度能力只是應(yīng)用交付中的一項挑戰(zhàn)而已,整個系統(tǒng)需要具備健壯的服務(wù)發(fā)現(xiàn)、健康檢查以及配置信息,以確保系統(tǒng)的整體處于健康狀態(tài)。Consul或ZooKeeper這樣的服務(wù)發(fā)現(xiàn)工具對于這些動態(tài)系統(tǒng)的維護可謂至關(guān)重要。
調(diào)度器帶來了應(yīng)用與組織層面上的大規(guī)?;?/h2>
在進行測試的過程中,Nomad也進行了一些技術(shù)改進。我們對基數(shù)樹進行了優(yōu)化,以進一步提升調(diào)度器的性能。我們還為調(diào)度器加入了一些健壯的特性,例如重試,以及設(shè)定了分配的上限,以應(yīng)對Docker崩潰的情況。我們也克服了libcontainer中的某些奇怪行為,該問題產(chǎn)生于在單一節(jié)點上運行大量容器的情況下。我們將以上這些難以重現(xiàn)的條件都添加至Nomad,任何用戶都可以通過最新版本的Nomad重新進行這些測試。容器仍然是一種新興起的技術(shù),這也是為什么Nomad選擇通過VM、chroot(2)與raw-exec中支持容器化的原因。
跨基礎(chǔ)設(shè)施進行高速調(diào)度的實用性不僅體現(xiàn)在集群的大規(guī)?;?。大多數(shù)公司都設(shè)置了大量的團隊或組織,他們需要對資源展開競爭。傳統(tǒng)的方法是為每個組創(chuàng)建唯一的、分段的集群。雖然這種方式確實提供了隔離性,防止了出現(xiàn)交集的情況,但它往往會導(dǎo)致每個團隊的集群利用率不足。
通過將單一集群中的資源作為池提供,公司就能夠統(tǒng)一并簡化他們的基礎(chǔ)設(shè)施,同時為團隊提供了更大的靈活性。如果某個團隊在某一時刻需要使用更多的資源,他們就可以將這部分工作快速地擴展至集群中未使用的部分。正是快速的、集群范圍的資源部署才使得這一點成為可能。
能夠在5分鐘之內(nèi)對100萬個容器進行調(diào)度的能力可解決絕大部分企業(yè)在可伸縮性方面的要求。Nomad還將繼續(xù)進行性能改進,但這種改進將是邊緣性的,其規(guī)模會越來越小。除了性能上的可伸縮性之外,組織上的可伸縮性則是下一個挑戰(zhàn)。能夠應(yīng)對quota、安全性、charge back更多問題的特性將使調(diào)度器工作流更易于在大型組織中得到應(yīng)用。
關(guān)于作者
Kevin Fishner在HashiCorp擔(dān)任客戶成功總監(jiān),他在為客戶提供HashiCorp的各種開源與商業(yè)產(chǎn)品方面有著豐富的經(jīng)驗。雖然他目前是一位工程師,但在求學(xué)期間主攻的卻是哲學(xué)專業(yè)??赏ㄟ^@KFishner訪問他的Twitter。
?
Docker在2013年三月實現(xiàn)了開源發(fā)布,它的出現(xiàn)讓軟件開發(fā)行業(yè)對于現(xiàn)代化應(yīng)用的打包以及部署方式發(fā)生了巨大的變化。緊隨著Docker的發(fā)布,各種具有競爭性、致敬性以及支持性的容器技術(shù)紛紛涌現(xiàn),為這一領(lǐng)域帶來了極大的關(guān)注度,同時也引起了人們的反思。這一系列文章將解答讀者的各種困惑,對如何在企業(yè)中實際使用容器進行分析。
這一系列文章首先將對容器背后的核心技術(shù)進行觀察,了解開發(fā)者目前如何使用容器,隨后將分析在企業(yè)中部署容器的核心挑戰(zhàn),例如如何將容器技術(shù)與持續(xù)集成和持續(xù)交付管道進行集成,并對監(jiān)控方式進行改進,以支持不斷變化的負載,以及使用短期容器的潛在需求。本系列文章的總結(jié)部分將對容器技術(shù)的未來進行分析,并探討無核化技術(shù)(unikernels)目前在處于技術(shù)前沿的組織中所扮演的角色。
?
總結(jié)
以上是生活随笔為你收集整理的从HashiCorp Nomad对上百万容器进行调度所学到的经验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker网络和服务发现
- 下一篇: golang orm 框架之 gorm