鐘成:Kubernetes的核心設(shè)計(jì)實(shí)現(xiàn)
杭州是一座極有包容性的城市,古韻清雅的街道景點(diǎn)隨處可見(jiàn),現(xiàn)代建筑群設(shè)計(jì)感十足,傳統(tǒng)底蘊(yùn)與現(xiàn)代科技被這座古城兼容并蓄,***融合。HDG華為開(kāi)發(fā)者匯,就將杭州作為第四站,5位講師***揭秘華為的CloudOpera、PaaS、融合視頻3個(gè)生態(tài)圈,技術(shù)干貨無(wú)私分享,聽(tīng)眾疑問(wèn)現(xiàn)場(chǎng)解答,思想的小火花一直在碰撞,參會(huì)的開(kāi)發(fā)者大呼過(guò)癮。
華為PaaS開(kāi)發(fā)部高級(jí)工程師鐘成對(duì)黃玉奇的發(fā)言也做了補(bǔ)充。他表示,華為***次嘗試去構(gòu)筑PaaS生態(tài)圈,希望能有更多的開(kāi)發(fā)者關(guān)注這個(gè)平臺(tái)。在鐘成的演講中,他主要與眾開(kāi)發(fā)者探討了圍繞Kubernetes的核心設(shè)計(jì)實(shí)現(xiàn)的多個(gè)技術(shù)細(xì)節(jié),如怎么落地、在網(wǎng)絡(luò)和存儲(chǔ)環(huán)節(jié)如何操作、華為針對(duì)做哪些內(nèi)容做了改動(dòng)。社區(qū)應(yīng)用的親和性和反親和性這些內(nèi)容都是***對(duì)外披露。
現(xiàn)場(chǎng)實(shí)錄如下:
我廢話也不多說(shuō),直接開(kāi)始講了,我也沒(méi)有什么特別可介紹的,我叫鐘成,也是華為的,2012實(shí)驗(yàn)室的。
剛才黃玉奇已經(jīng)把Kubernetes主要的背景都介紹了,它有什么夠能或者怎么做,我這里稍微再展開(kāi)一些,講一些關(guān)于它底層設(shè)計(jì)的事。從大的方向來(lái)講,k8s這個(gè)東西是應(yīng)運(yùn)而生的,它出現(xiàn)在現(xiàn)在這個(gè)時(shí)代是因?yàn)楹芏嗪芏嗥髽I(yè)發(fā)現(xiàn)自己有很多計(jì)算機(jī),有很多集群在機(jī)房里面,但是并沒(méi)有非常好的手段管理它。傳統(tǒng)的軟件開(kāi)發(fā)是一種單體式的開(kāi)發(fā),這些軟件力度非常粗,比較大,而且要的東西比較長(zhǎng)。換成現(xiàn)在這個(gè)時(shí)代會(huì)變成一種互聯(lián)網(wǎng)式的開(kāi)發(fā),就是我會(huì)把我的過(guò)多軟件都微服務(wù)化,把這個(gè)邏輯打的比較碎,打的比較散,發(fā)布的周期可以變短。以前可能是做一個(gè)軟件,做一個(gè)系統(tǒng),你要做一兩年。現(xiàn)在一個(gè)功能可能一天或者一周就會(huì)生成一次,這方面就會(huì)有一些優(yōu)點(diǎn)和缺點(diǎn),這里都會(huì)講,就不詳細(xì)說(shuō)了。
這個(gè)是國(guó)外的一個(gè)組織對(duì)PaaS的定義,主要是完成這么幾個(gè)功能,一個(gè)是資源獲取自動(dòng)化,語(yǔ)言跟框架的自動(dòng)化,以及運(yùn)維管理的自動(dòng)化。從解決集群管理這個(gè)角度來(lái)說(shuō),業(yè)界是有好幾個(gè)方案,對(duì)于集群管理來(lái)說(shuō)主要就是調(diào)度器的設(shè)計(jì),當(dāng)你把這個(gè)下完之后,你怎么決定這個(gè)應(yīng)用到底跑在這個(gè)集群的什么地方。這里面列了有五種比較典型的方案,***種方案就是所謂的單體調(diào)度器的方案,就是我在這個(gè)系統(tǒng)中有一個(gè)調(diào)度器,由它來(lái)決定我這個(gè)應(yīng)用部署到什么地方。這種方案像目前為止Kubernetes就在采用這種方案。
第二種方案是我去采用兩層式的調(diào)度框架,下面這一層我只管資源,管到資源之后往上去報(bào)。比如說(shuō)當(dāng)上面請(qǐng)求資源的時(shí)候,我會(huì)給它挑出來(lái)往上報(bào),上面的幾個(gè)東西去挑,上面的幾個(gè)調(diào)度器去選。如果上面的調(diào)度器覺(jué)得這臺(tái)機(jī)器合適,那就拿去用。這就是myDOS的一個(gè)思路,myDOS就是Kubernetes。
第三個(gè)則是一個(gè)共享狀態(tài)的調(diào)度方案,這個(gè)方案是我把所有集群的狀態(tài)全部都同步到各個(gè)調(diào)度器里面去,由各個(gè)調(diào)度器進(jìn)行決策,決策完了之后我往下試圖進(jìn)行部署。由于上面我看到的這些東西都是一樣的,你***合下來(lái)的就需要有一個(gè)沖突解決,避免多個(gè)角度器之間互相打架,這也是一種方案。
還有一種方案是所謂的分布式調(diào)度,這種分布式調(diào)度我沒(méi)有一個(gè)中央的調(diào)度器,只是我在中間任何一點(diǎn)都可以調(diào)度一些東西,我任何一臺(tái)機(jī)器上都可以決定我是不是要接受這個(gè)應(yīng)用,是不是要跑這個(gè)服務(wù)。這個(gè)調(diào)度其看起來(lái)可能比較散,是它其實(shí)是很有用的。現(xiàn)在在亞馬遜的(03:57)里面就采用這種調(diào)度方案,對(duì)于非常短的一個(gè)任務(wù),它的本身生命周期只有三四秒,如果你再通過(guò)一個(gè)比較復(fù)雜的調(diào)度器,花個(gè)十秒鐘去調(diào)度的話,就比較得不償失了。
第五種是一種混合式的方案,我把***種跟第四種混合在一起。
這個(gè)是我后面列的表,各個(gè)系統(tǒng)調(diào)度方案的對(duì)應(yīng)表。包括它的一些調(diào)度的力度,多調(diào)度器,以及重調(diào)度的機(jī)器。
這個(gè)是k8s的一些優(yōu)勢(shì),已經(jīng)講過(guò)。然后講一下k8s的一些設(shè)計(jì)理念,它是一個(gè)全功能的,該了網(wǎng)絡(luò)、服務(wù)發(fā)現(xiàn)、負(fù)載均衡和資源管理這些東西。你可以認(rèn)為它是一個(gè)集成商的操作系統(tǒng),有了這個(gè)操作系統(tǒng)以后,用心就不用操心這些底層的應(yīng)用到底怎么被調(diào)度,怎么被運(yùn)行,你只要向它提交任務(wù)就可以了。這個(gè)我覺(jué)得是k8s比較大的思路,包括網(wǎng)絡(luò),包括下面的這些資源調(diào)度,全部都是它進(jìn)行管理的。而且它沒(méi)有任何綁定,可以支持多種IaaS提供商。
這個(gè)我也不怎么講了,這里有一個(gè)簡(jiǎn)單的動(dòng)畫,當(dāng)你創(chuàng)建一個(gè)IS的時(shí)候會(huì)選擇一個(gè)節(jié)點(diǎn),然后把它布起來(lái)。如果這個(gè)節(jié)點(diǎn)上的容器或者(06:21)死掉的話,會(huì)它進(jìn)行遷移,遷移到另外一臺(tái)機(jī)器上面去。
這個(gè)是k8s的網(wǎng)絡(luò)模型,這里稍微復(fù)雜一點(diǎn),但是也是可以看得出來(lái)。當(dāng)我在Pods部署了一組應(yīng)用之后,我怎么從外部去訪問(wèn)它。我會(huì)定義一個(gè)Frontend Service這么一個(gè)東西,這個(gè)Service會(huì)對(duì)應(yīng)下面的這些容器。這里有三個(gè)容器,這三個(gè)容器可以進(jìn)行訪問(wèn)。第二個(gè)Service則是一個(gè)Redis Service,這個(gè)Service是給內(nèi)部使用的,不是對(duì)外使用的。內(nèi)部可能又有三個(gè)容器Pods的實(shí)例進(jìn)行互相之間的訪問(wèn)。
目前k8s的網(wǎng)絡(luò)訪問(wèn)方式有四種,一個(gè)是ClusterIP,就是我在集群內(nèi)部定義一個(gè)跟我現(xiàn)在網(wǎng)站完全不一樣的IP,這個(gè)IP只有在內(nèi)部可以訪問(wèn),它是通過(guò)IP(07:31),你可以認(rèn)為它造出一個(gè)IP,這個(gè)IP內(nèi)部會(huì)進(jìn)行合適的路由。第二個(gè)是Nodport,就是說(shuō)我在集群的每個(gè)物理機(jī)上,每個(gè)部署的節(jié)點(diǎn)上面我去開(kāi)一個(gè)端口,這個(gè)端口是由我的k8s的(07:44)進(jìn)行管理,當(dāng)你外部有流量訪問(wèn)這個(gè)節(jié)點(diǎn)上的端口的時(shí)候,會(huì)把這個(gè)節(jié)點(diǎn)上的流量進(jìn)行轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)到運(yùn)營(yíng)的Pods上面去,這是第二種網(wǎng)絡(luò)方式。第三種是我結(jié)合Dodeport的這種功能,我在上面再放一層loadBalancer,類似于像ELB,我通過(guò)這個(gè)ELB訪問(wèn)所有節(jié)點(diǎn)上的某個(gè)具體的端口,再去訪問(wèn)具體的Service。
接下來(lái)我會(huì)談一下k8s的一些核心機(jī)制,這個(gè)會(huì)稍微偏向于代碼一些。這張大家在上面也看到過(guò),就是list-watch目的。前面大黃那邊有一張圖,就是k8s是一個(gè)典型的中心式的架構(gòu),所有的數(shù)據(jù)都是存在中心的API Service上面,API Service后面存了ETCD。這個(gè)架構(gòu)在分布式集群里面是比較少見(jiàn)的,一般的分布式集群的做法是什么呢,我會(huì)寫很多個(gè)進(jìn)程在很多機(jī)器上面,我這些進(jìn)程之間互相通過(guò)消息隊(duì)列。連接完了之后,A進(jìn)程做一件事情,做完之后把這個(gè)結(jié)果扔到隊(duì)列里面去,然后用B進(jìn)程進(jìn)行這個(gè)操作,***再到C進(jìn)程。你可以認(rèn)為是一環(huán)扣一環(huán),是消息隊(duì)列的模式。但是Kubernetes的做法有點(diǎn)不一樣,它的核心思想是我把所有的數(shù)據(jù)都放到ETCD里面去,由一個(gè)強(qiáng)的分布式數(shù)據(jù)庫(kù)來(lái)進(jìn)行存儲(chǔ),保證這個(gè)數(shù)據(jù)的強(qiáng)一致性,這是***個(gè)。
第二個(gè)我這些組建之間互相怎么通信呢?我通過(guò)中心的API Service進(jìn)行通信。這個(gè)通信方式和一般的生產(chǎn)者、消費(fèi)者也不大一樣,前面我講的是生產(chǎn)者、消費(fèi)者模型,就是A生產(chǎn),B消費(fèi)。A處理了這個(gè)消息之后,我把它存到數(shù)據(jù)庫(kù)里面去,就是下面的ETCD,ETCD會(huì)通知所有關(guān)注這個(gè)消息的人,把這個(gè)消息發(fā)給他,讓這些人去處理。我們可以從這里面看到,當(dāng)我從U客戶端創(chuàng)建一個(gè)pods之后,可能是創(chuàng)建一個(gè)Replicaset之后,它就會(huì)收到Replicaset創(chuàng)建的消息,然后它就會(huì)再去創(chuàng)建一個(gè)pods,你創(chuàng)建這個(gè)pods之后,這些pod其實(shí)是沒(méi)有被調(diào)度的。這時(shí)候由于一些變化,就會(huì)知道這些pods沒(méi)有調(diào)度,對(duì)它進(jìn)行處理,處理完之后去改變pod的狀態(tài),后面再這樣分拉下去。這種方式list-watch跟那個(gè)不是很一樣,理論上這個(gè)數(shù)據(jù)面比較廣,如果是消息隊(duì)列的話,A生產(chǎn)什么B就必須得消費(fèi)什么。但是list-watch的方式是,我所有的客戶端都可以關(guān)心自己想關(guān)心的東西,我可以通過(guò)watch這種方式去找到自己關(guān)心的那一部分,我可以關(guān)心node或者關(guān)心pods,我有選擇權(quán),所有的客戶端都有選擇權(quán)。
這里會(huì)稍微涉及到一些代碼,大家看代碼有問(wèn)題嗎,簡(jiǎn)單講一點(diǎn)。這個(gè)代碼也很簡(jiǎn)單,我在客戶端就是起了一個(gè)函數(shù),這個(gè)函數(shù)就是給它提供一組,你可以認(rèn)為這就是一個(gè)http發(fā)起請(qǐng)求的一個(gè)函數(shù)。當(dāng)你收到這個(gè)apiService這邊發(fā)生變化的事件之后,就會(huì)調(diào)度你這里的三個(gè)函數(shù),就是我發(fā)生這個(gè)事件是增加事件,還是更新事件,還是刪除事件。也就是說(shuō)當(dāng)我發(fā)起list-watch之后,apiService會(huì)不停的把事件發(fā)過(guò)來(lái),這是在同一條http連接上面,它會(huì)不停的把事件發(fā)過(guò)來(lái)。發(fā)過(guò)來(lái)之后,我Client不需要捕捉每一條事件,我只要把我的處理函數(shù)掛在這個(gè)鉤子上面,這個(gè)就是它的一個(gè)框架,掛在這個(gè)鉤子上面,當(dāng)有新的事件過(guò)來(lái)之后,我這里會(huì)做相應(yīng)的處理。同時(shí)我會(huì)在底層保存一份數(shù)據(jù)的全樣數(shù)據(jù)的副本。這個(gè)是客戶端的代碼。
服務(wù)端的機(jī)制也是比較類似,我會(huì)在底層也存儲(chǔ)一個(gè)store,當(dāng)有http數(shù)據(jù)過(guò)來(lái)的時(shí)候,它會(huì)在本地保存一個(gè)滑動(dòng)窗口,類似于CCD那個(gè)滑動(dòng)窗口,每次事件發(fā)生了,就會(huì)給每個(gè)Client做一個(gè)相應(yīng)通知。
前面一個(gè)過(guò)程就是整個(gè)k8s list-watch的一個(gè)機(jī)制,這個(gè)我認(rèn)為是它跟傳統(tǒng)分布式集群軟件***的區(qū)別,就是它底層的通信機(jī)制不一樣。后面則是一些具體調(diào)度器的機(jī)制,k8s的調(diào)度器我這里大致的講了一下當(dāng)你有一個(gè)pods要被調(diào)度的時(shí)候它會(huì)怎么做。它***步就會(huì)辨認(rèn)這個(gè)集群中所有的節(jié)點(diǎn),先去找哪些節(jié)點(diǎn)是不是合適。合適的意思就是說(shuō)它的資源足不足夠,能不能夠有足夠的網(wǎng)絡(luò),足夠的帶寬,先把我實(shí)在沒(méi)有辦法布的機(jī)器都過(guò)濾掉。第二步則是進(jìn)行打分,如果我有一千臺(tái)機(jī)器,里面有一百臺(tái)我這個(gè)應(yīng)用都可以布,我***給這一百個(gè)中間選一個(gè)。我怎么選呢?就是我給這一百個(gè)節(jié)點(diǎn)進(jìn)行打分。打分的依據(jù)包括了一些親和性或者反親和性的算法,也包括一些資源算法。也就是說(shuō)k8s現(xiàn)在調(diào)度器的機(jī)制是先進(jìn)行過(guò)濾,然后進(jìn)行排序打分的模式。
這個(gè)就是過(guò)濾跟排序的一些算法,這些算法其實(shí)都是千差變化的,就是說(shuō)你要想做的話,也可以實(shí)現(xiàn)一個(gè)k8s的調(diào)度器。就是你可以自己中間插入一些函數(shù),我想檢查哪些端口,或者有些什么條件之類的。其實(shí)很多業(yè)務(wù)邏輯都是寫在這個(gè)地方的,就是你可以自己去選擇這個(gè)集群怎么進(jìn)行部署。
這個(gè)就是講高可靠,這個(gè)就是那個(gè)社區(qū)的方案,接上面的那個(gè)問(wèn)題,就是k8s怎么實(shí)現(xiàn)自己的高可靠。它的想法比較簡(jiǎn)單,就是我把a(bǔ)piService分成多份,每一份都可以進(jìn)行獨(dú)立的訪問(wèn)。前面會(huì)掛一個(gè)為load balancer,就是我所有的工作節(jié)點(diǎn)都經(jīng)過(guò)這個(gè)load balancer來(lái)訪問(wèn)apiService。底層的ETCD,自身采用(14:56)的協(xié)議進(jìn)行數(shù)據(jù)同步。就是你的APIService從本質(zhì)上來(lái)說(shuō)是無(wú)狀態(tài)的,而調(diào)度器和控制器目前還沒(méi)有辦法做到真正的多調(diào)度,或者是多控制。這個(gè)也是受制于前面的list-watch的機(jī)制,因?yàn)樗举|(zhì)上是所有的調(diào)度器或者是資源管理器得到的這個(gè)消費(fèi)者數(shù)據(jù)是一樣的,所以目前來(lái)說(shuō)暫時(shí)還沒(méi)有能夠進(jìn)行拆分。最近我在社區(qū)里面跟ETCD的開(kāi)發(fā)者進(jìn)行討論,我們能不能改善這個(gè)機(jī)制,讓我們這個(gè)集群把所有真正的調(diào)度和控制全部可以多副本。現(xiàn)在只能通過(guò)分布式鎖,我是有單調(diào)度器和單控制器,就是每種類型的控制器只能有一個(gè)。
后面過(guò)一下社區(qū)的方向,這方面聯(lián)邦我就不講了,前面大黃講過(guò)了,這是聯(lián)邦的一個(gè)創(chuàng)建過(guò)程,這個(gè)也不講了。應(yīng)用親和和反親和,大家知道這個(gè)意思就可以了,這是一個(gè)需求,這個(gè)有好幾個(gè)層級(jí)。包括是集群聯(lián)邦層級(jí),包括集群內(nèi)部的層級(jí),其實(shí)都會(huì)有。
這里講了一個(gè)我對(duì)不同pods進(jìn)行親和和反親和,這里是一些具體的案例,這個(gè)也不展開(kāi)了,回頭可以具體去看。
這個(gè)是我們后面會(huì)投入的一些東西,華為這邊會(huì)做,也是我們?cè)谏鐓^(qū)里面會(huì)做的,主要是集群的規(guī)模和性能,還有調(diào)度和重調(diào)度,以及集群聯(lián)邦,主要是三大塊。
后面我也做一個(gè)小小的廣告,左邊的是我們的微信號(hào),后面是一個(gè)微信群,華為的微信群,大家可以在里面聊聊天,這個(gè)群是長(zhǎng)期開(kāi)設(shè)的。