摘要:目前為止,我們有已經研究過幾個非常有代表性的調度系統和。當時學習完這些調度系統的架構后,腦子里面形成個大大的疑問是二次調度的架構么和相比它的擴展性如何為什么所有調度系統都是無法橫向擴展的后面我們就針對這兩個問題深入討論一下。
小編序:
在上周發布的《從“鴻溝理論”看云原生,哪些技術能夠跨越鴻溝?》一文中,靈雀云CTO陳愷表示:Kubernetes在云計算領域已經成為既定標準,進入主流市場,最新版本主要關注在穩定性、可擴展性方面,在開發人員中變得非常流行。Kubernetes會越來越多往下管理所有基礎設施,往上管理所有種類的應用。我們會看到,越來越多的周邊技術向它靠攏,在其之上催化出一個龐大的云原生技術生態。
那么,現在最新最流行的 Kubernetes 架構是什么樣子呢?本文給大家介紹一下 Kubernetes 整體架構,并深入探討其中 2 個比較關鍵的問題。
Kubernetes 架構解析
首先,Kubernetes 的官方架構圖是這樣的:
這個架構圖看起來會比較復雜,很難看懂,我把這個官方的架構圖重新簡化了一下,就會非常容易理解了:
ETCD :是用來存儲所有 Kubernetes 的集群狀態的,它除了具備狀態存儲的功能,還有事件監聽和訂閱、Leader選舉的功能,所謂事件監聽和訂閱,各個其他組件通信,都并不是互相調用 API 來完成的,而是把狀態寫入 ETCD(相當于寫入一個消息),其他組件通過監聽 ETCD 的狀態的的變化(相當于訂閱消息),然后做后續的處理,然后再一次把更新的數據寫入 ETCD。所謂 Leader 選舉,其它一些組件比如 Scheduler,為了做實現高可用,通過 ETCD 從多個(通常是3個)實例里面選舉出來一個做Master,其他都是Standby。
API Server:剛才說了 ETCD 是整個系統的最核心,所有組件之間通信都需要通過 ETCD,實際上,他們并不是直接訪問 ETCD,而是訪問一個代理,這個代理是通過標準的RESTFul API,重新封裝了對 ETCD 接口調用,除此之外,這個代理還實現了一些附加功能,比如身份的認證、緩存等。這個代理就是 API Server。
Controller Manager:是實現任務調度的,關于任務調度可以參考之前的文章,簡單說,直接請求 Kubernetes 做調度的都是任務,比如 Deployment 、Deamon Set 或者 Job,每一個任務請求發送給Kubernetes之后,都是由Controller Manager來處理的,每一個任務類型對應一個Controller Manager,比如 Deployment對應一個叫做 Deployment Controller,DaemonSet 對應一個 DaemonSet Controller。
Scheduler:是用來做資源調度的,Controller Manager會把任務對資源要求,其實就是Pod,寫入到ETCD里面,Scheduler監聽到有新的資源需要調度(新的Pod),就會根據整個集群的狀態,給Pod分配到具體的節點上。
Kubelet:是一個Agent,運行在每一個節點上,它會監聽ETCD中的Pod信息,發現有分配給它所在節點的Pod需要運行,就在節點上運行相應的Pod,并且把狀態更新回到ETCD。
Kubectl: 是一個命令行工具,它會調用 API Server發送請求寫入狀態到ETCD,或者查詢ETCD的狀態。
如果還覺得不清楚,我們就用部署服務的例子來解釋一下整個過程。假設要運行一個多實例的Nginx,在Kubernetes內部,整個流程是這樣的:
1.通過kubectl命令行,創建一個包含Nginx的Deployment對象,kubectl會調用 API Server 往ETCD里面寫入一個 Deployment對象。
2.Deployment Controller 監聽到有新的 Deployment對象被寫入,就獲取到對象信息,根據對象信息來做任務調度,創建對應的 Replica Set 對象。
3.Replica Set Controller監聽到有新的對象被創建,也讀取到對象信息來做任務調度,創建對應的Pod來。
4.Scheduler 監聽到有新的 Pod 被創建,讀取到Pod對象信息,根據集群狀態將Pod調度到某一個節點上,然后更新Pod(內部操作是將Pod和節點綁定)。
5.Kubelet 監聽到當前的節點被指定了新的Pod,就根據對象信息運行Pod。
這就是Kubernetes內部如何實現整個 Deployment 被創建的過程。這個過程只是為了向大家解釋每一個組件的職責,以及他們之間是如何相互協作的,忽略掉了一些繁瑣的細節。
目前為止,我們有已經研究過幾個非常有代表性的調度系統:Hadoop MRv1、YARN、Mesos和Kubernetes。當時學習完這些調度系統的架構后,腦子里面形成2個大大的疑問:
1.Kubernetes是二次調度的架構么?和Mesos相比它的擴展性如何?
2.為什么所有調度系統都是無法橫向擴展的?
后面我們就針對這兩個問題深入討論一下。
Kubernetes 是否是二層調度?
在 Google 的一篇關于內部 Omega 調度系統的論文中,將調度系統分成三類:單體、二層調度和共享狀態三種,按照它的分類方法,通常Google的 Borg被分到單體這一類,Mesos被當做二層調度,而Google自己的Omega被當做第三類“共享狀態”。
論文的作者實際上之前也是Mesos的設計者之一,后來去了Google設計新的 Omega 系統,并發表了論文,論文的主要目的是提出一種全新的“Shard State”的模式,來同時解決調度系統的性能和擴展性問題。但我覺得 Shared State 模型太過理想化,根據這個模型開發的Omega系統,似乎在Google內部并沒有被大規模使用,也沒有任何一個大規模使用的調度系統采用 Shared State 模型。
因為Kubernetes的大部分設計是延續 Borg的,而且Kubernetes的核心組件(Controller Manager和Scheduler)缺省也都是綁定部署在一起,狀態也都是存儲在ETCD里面的,所以通常大家會把Kubernetes也當做“單體”調度系統,實際上我并不贊同。
我認為 Kubernetes 的調度模型也完全是二層調度的,和 Mesos 一樣,任務調度和資源的調度是完全分離的,Controller Manager承擔任務調度的職責,而Scheduler則承擔資源調度的職責。
實際上Kubernetes和Mesos調度的最大區別在于資源調度請求的方式:
主動 Push 方式。是 Mesos 采用的方式,就是 Mesos 的資源調度組件(Mesos Master)主動推送資源 Offer 給 Framework,Framework 不能主動請求資源,只能根據 Offer 的信息來決定接受或者拒絕。
被動 Pull 方式。是 Kubernetes 的方式,資源調度組件 Scheduler 被動的響應 Controller Manager的資源請求。
這兩種方式帶來的不同,我主要從一下 5 個方面來分析。另外注意,我所比較兩者的優劣,都是從理論上做的分析,工程實現上會有差異,一些指標我也并沒有實際測試過。
1.資源利用率:Kubernetes 勝出
理論上,Kubernetes 應該能實現更加高效的集群資源利用率,原因資源調度的職責完全是由Scheduler一個組件來完成的,它有充足的信息能夠從全局來調配資源,然后而Mesos 卻做不到,因為資源調度的職責被切分到Framework和Mesos Master兩個組件上,Framework 在挑選 Offer 的時候,完全沒有其他 Framework 工作負載的信息,所以也不可能做出最優的決策。
舉個例子,比如我們希望把對耗費 CPU的工作負載和耗費內存的工作負載盡可能調度到同一臺主機上,在Mesos里面不太容易做到,因為他們分屬不同的 Framework。
2.擴展性:Mesos勝出
從理論上講,Mesos 的擴展性要更好一點。原因是Mesos的資源調度方式更容易讓已經存在的任務調度遷移上來。舉個例子,假設已經有了一個任務調度系統,比如 Spark,現在要遷移到集群調度平臺上,理論上它遷移到 Mesos 比 Kubernetes 上更加容易。
如果遷移到 Mesos ,沒有改變原來的工作流程和邏輯,原來的邏輯是:來了一個作業請求,調度系統把任務拆分成小的任務,然后從資源池里面挑選一個節點來運行任務,并且記錄挑選的節點 IP 和端口號,用來跟蹤任務的狀態。遷移到 Mesos 之后,還是一樣的邏輯,唯一需要變化的是那個資源池,原來是自己管理的資源池,現在變成 Mesos 提供的Offer 列表。
如果遷移到 Kubernetes,則需要修改原來的基本邏輯來適配 Kubernetes,資源的調度完全需要調用外部的組件來完成,并且這個變成異步的。
3.靈活的任務調度策略:Mesos 勝出
Mesos 對各種任務的調度策略也支持的更好。舉個例子,如果某一個作業,需要 All or Nothing 的策略,Mesos 是能夠實現的,但是 Kubernetes 完全無法支持。所以All or Nothing 的意思是,價格整個作業如果需要運行 10 個任務,這 10個任務需要能夠全部有資源開始執行,否則就一個都不執行。
4.性能:Mesos 勝出
Mesos 的性能應該更好,因為資源調度組件,也就是 Mesos Master 把一部分資源調度的工作甩給 Framework了,承擔的調度工作更加簡單,從數據來看也是這樣,在多年之前 Twitter 自己的 Mesos 集群就能夠管理超過 8萬個節點,而 Kubernetes 1.3 只能支持 5千個節點。
5.調度延遲:Kubernetes 勝出
Kubernetes調度延遲會更好。因為Mesos的輪流給Framework提供Offer機制,導致會浪費很多時間在給不需要資源的 Framework 提供Offer。
為什么不支持橫向擴展?
可能大家已經注意到了,幾乎所有的集群調度系統都無法橫向擴展(Scale Out),比如早期的 Hadoop MRv1 的管理節點是單節點,管理的集群上限是 5000 臺機器,YARN 資源管理節點同時也只能有一個節點工作,其他都是備份節點,能夠管理的機器的上限1萬個節點,Mesos通過優化,一個集群能夠管理 8 萬個節點,Kubernetes 目前的 1.13 版本,集群管理節點的上限是 5000 個節點。
所有的集群調度系統的架構都是無法橫向擴展的,如果需要管理更多的服務器,唯一的辦法就是創建多個集群。集群調度系統的架構看起來都是這個樣子的:
中間的 Scheduler(資源調度器)是最核心的組件,雖然通常是由多個(通常是3個)實例組成,但是都是單活的,也就是說只有一個節點工作,其他節點都處于 Standby 的狀態。為什么會這樣呢?看起來不符合互聯網應用的架構設計原則,現在大部分互聯網的應用通過一些分布式的技術,能夠很容易的實現橫向擴展,比如電商應用,促銷時,通過往集群里面添加服務器,就能夠提升服務的吞吐量。如果是按照互聯網應用的架構,看起來應該是這樣的:
Scheduler 應該是可以多活的,有任意多的實例一起對外提供服務,無論是資源的消費者,還是資源的提供者在訪問 Scheduler 的時候,都需要經過一個負載均衡的組件或者設備,負責把請求分配給某一個 Scheduler 實例。為什么這種架構在集群調度系統里面變得不可行么?為了理解這件事情,我們先通過一個互聯網應用的架構的例子,來探討一下具備橫向擴展需要哪些前提條件。
橫向擴展架構的前提條件
假設我們要實現這樣一個電商系統:
1.這是一個二手書的交易平臺,有非常多的賣家在平臺上提供二手書,我們暫且把每一本二手書叫做庫存;
2.賣家的每一個二手書庫存,根據書的條碼,都可以找到圖書目錄中一本書,我們把這本書叫做商品;
3.賣家在錄入二手書庫存的時候,除了錄入是屬于哪一個商品,同時還需要錄入其他信息,比如新舊程度、價錢、發貨地址等等。
4.買家瀏覽圖書目錄,選中一本書,然后下單,訂單系統根據買家的要求(價格偏好、送貨地址等),用算法從這本書背后的所有二手書庫存中,匹配一本符合要求的書完成匹配,我們把這個過程叫訂單匹配好了。
這樣一個系統,從模型上看這個電商系統和集群調度系統沒啥區別,這個里面有資源提供者(賣家),提供某種資源(二手書),組成一個資源池(所有二手書),也有資源消費者(買家),提交自己對資源的需求,然后資源調度器(訂單系統)根據算法自動匹配一個資源(一本二手書)。
但是很顯然,這個電商系統是可以設計成橫向擴展架構的,為什么呢?這個電商系統和集群調度系統的區別到底在什么地方? 在回答這個問題之前,我們先來回答另外一個問題:這個電商系統橫向擴展的節點數是否有上限,上限是多少,這個上限是有什么因素決定的?
系統理論上的并發數量決定了橫向擴展的節點數
假設系統架構設計的時候,不考慮任何物理限制(比如機器的資源大小,帶寬等),能夠并發處理 1000個請求,那么很顯然,橫向擴展的節點數量上限就是1000,因為就算部署了 1001個節點,在任何時候都有一個節點是處于空閑狀態,部署更多的節點已經完全無法提高系統的性能。我們下面需要想清楚的問題其實就變成了:系統理論上能夠并發處理請求的數量是多少,是有什么因素決定的。
系統的并發數量是由“獨立資源池”的數量決定的
“獨立資源池”是我自己造出來的一個詞,因為實在想不到更加合適的。還是以上面的電商系統為例,這個訂單系統的理論上能夠處理的并發請求(訂購商品請求)數量是由什么來決定的呢?先看下面的圖:
在訂單系統在匹配需求的時候,實際上應該是這樣運行的,在訂單請求來了之后,根據訂單請求中的購買的商品來排隊,購買同一個商品的請求被放在一個隊列里面,然后訂單的調度系統開始從隊列里面依次處理請求,每次做訂單匹配的時候,都需根據當前商品的所有庫存,從里面挑選一個最佳匹配的庫存。
雖然在實現這個系統的時候,這個隊列不見得是一個消息隊列,可能會是一個關系型數據庫的鎖,比如一個購買《喬布斯傳》的訂單,系統在處理的時候需要先從所有庫存里面查詢出《喬布斯傳》的庫存,將庫存記錄鎖住,并做訂單匹配且更新庫存(將生成訂單的庫存商品設置為”不可用”狀態)之后,才會將數據庫鎖釋放,這時候所有后續購買《喬布斯傳》的訂單請求都在隊列中等待。
也有些系統在實現的時候采用“樂觀鎖”,就是每次訂單處理時,并不會在一開始就鎖住庫存信息,而是在最后一步更新庫存的時候才會鎖住,如果發生兩個訂單匹配到了同一個庫存物品,那么其中一個訂單處理就需要完全放棄然后重試。這兩種實現方式不太一樣,但是本質都是相同的。
所以從上面的討論可以看出來,之所以所有購買《喬布斯傳》的訂單需要排隊處理,是因為每一次做訂單匹配的時候,需要《喬布斯傳》這個商品的所有庫存信息,并且最后會修改(占用)一部分庫存信息的狀態。在該訂單匹配的場景里面,我們就把《喬布斯傳》的所有庫存信息叫做一個“獨立資源池”,訂單匹配這個“調度系統”的最大并發數量就完全取決于獨立資源池的數量,也就是商品的數量。我們假設一下,如果這個二手書的商城只賣《喬布斯傳》一本書,那么最后所有的請求都需要排隊,這個系統也幾乎是無法橫向擴展的。
集群調度系統的“獨立資源池”數量是 1
我們再來看一下集群調度系統,每一臺服務器節點都是一個資源,每當資源消費者請求資源的時候,調度系統用來做調度算法的“獨立資源池”是多大呢?答案應該是整個集群的資源組成的資源池,沒有辦法在切分了,因為:
1.調度系統的職責就是要在全局內找到最優的資源匹配。
2.另外,哪怕不需要找到最優的資源匹配,資源調度器對每一次資源請求,也沒辦法判斷應該從哪一部分資源池中挑選資源。
正是因為這個原因,“獨立資源池”數量是 1,所以集群調度系統無法做到橫向擴展。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/32935.html
摘要:它最基本的功能是實現了虛擬交換機,可以把虛擬網卡和虛擬交換機的端口連接,這樣一個交換機下的多個網卡網絡就打通了,類似的功能。最基礎的分布式虛擬交換機,這樣可以將多臺機器上的容器組織在一個二層網絡下,看上去就好像所有容器接在一臺交換機上。 【編者的話】Kubernetes經過了幾年的發展,存在著很多的網絡方案。然而網絡虛擬化在Kubernetes出現前就一直在發展,其中基于OpenVsw...
摘要:此文已由作者劉超授權網易云社區發布。所以當我們評估大數據平臺牛不牛的時候,往往以單位時間內跑的任務數目以及能夠處理的數據量來衡量。的問題調度在大數據領域是核心中的核心,在容器平臺中是重要的,但不是全部。 此文已由作者劉超授權網易云社區發布。 歡迎訪問網易云社區,了解更多網易技術產品運營經驗 最近總在思考,為什么在支撐容器平臺和微服務的競爭中,Kubernetes 會取得最終的勝出,事實...
摘要:平臺上的微服務架構應用再來看一下我眼中的基于當前最流行的微服務架構的設計是什么樣的,即我們平臺上要運行的典型應用是什么樣的。 showImg(https://segmentfault.com/img/remote/1460000010900878); 8月19日的數人云Container Meetup上,張龍老師做了《基于Kubernetes的PaaS平臺的設計和思考》的精彩分享,分別...
摘要:在本系列的第一部分中,我將介紹監控的挑戰和主要數據來源。稍后,我將深入探討和部署,并使用下面列出的數據源的實際示例。監控挑戰使團隊更容易管理容器,在自動維護所需狀態的同時調度和配置容器。 作者:Sean Porter 我們的行業長期以來一直依賴基于微服務的架構來更快、更安全地交付軟件。微服務的出現和無處不在自然為容器技術鋪平了道路,使我們能夠重新思考如何構建和部署我們的應用程序。Doc...
摘要:前言本文給大家分享的題目是基于微服務以及的高可用架構探索與實現。比如說年大地震的時候我正好在東京,當時在做一個金融系統的相關工作。那次大地震導致很多很多的問題,雖然大地震不是在東京發生,但是還是給我們的系統造成了影響。 前言 本文給大家分享的題目是《基于DevOps、微服務以及K8S的高可用架構探索與實現》。整個企業的高可用架構面臨很多的挑戰,面向微服務、容器化以及敏態交付,是我們現在...
閱讀 1107·2021-11-24 10:24
閱讀 2593·2021-11-22 13:54
閱讀 999·2021-09-24 09:55
閱讀 3602·2019-08-30 15:54
閱讀 1318·2019-08-30 15:44
閱讀 1095·2019-08-30 14:23
閱讀 3202·2019-08-29 13:45
閱讀 1283·2019-08-29 11:19