K8S因?yàn)橐肓藢?duì)底層硬件的抽象層句携,我們部署應(yīng)用程序不用太多關(guān)注底層的硬件資源疗锐,因此對(duì)傳統(tǒng)的部署和運(yùn)維都帶來(lái)了比較大的變化衡载,今天我們接著上一篇文章搔耕,看看K8S對(duì)應(yīng)用程序的部署具體帶來(lái)了哪些“顛覆”。
我們先從抽象這個(gè)概念說(shuō)起痰娱,計(jì)算機(jī)整個(gè)體系結(jié)構(gòu)中弃榨,無(wú)不充斥了各種類型的抽象,筆者之前說(shuō)過(guò)猜揪,抽象是人類認(rèn)知事物的基本手段惭墓,抽象可以讓我們從紛繁復(fù)雜的事物中,找到某個(gè)角度的規(guī)律而姐,進(jìn)而形成對(duì)事物認(rèn)知的知識(shí)腊凶,這樣的角度越來(lái)越多,我們對(duì)事物的認(rèn)知也會(huì)更加全面拴念,然而抽象最大的好處是钧萍,符合直覺(jué),因?yàn)槌橄笫钦驹凇叭恕钡慕嵌葋?lái)進(jìn)行信息的聚合活動(dòng)政鼠。
回到計(jì)算機(jī)體系中风瘦,我們說(shuō)操作系統(tǒng)是硬件的抽象(當(dāng)然還有驅(qū)動(dòng)程序,但是大部分硬件的驅(qū)動(dòng)程序都包含在操作系統(tǒng)中公般,并且筆者也不打算把操作系統(tǒng)分為內(nèi)核和外部應(yīng)用万搔,因?yàn)檫@不是講操作系統(tǒng)的文章)胡桨,而編程語(yǔ)言是對(duì)操作系統(tǒng)提供的抽象,讓我們?cè)诖蠖鄶?shù)情況下不用太關(guān)心操作系統(tǒng)提供的接口(除非你是寫(xiě)高性能計(jì)算框架瞬雹,編譯器昧谊,或者基礎(chǔ)設(shè)施層代碼的同學(xué))⌒锇疲可以看到抽象可以提供巨大的易用性呢诬,而Kubernetes就是對(duì)一組計(jì)算機(jī)集群的抽象,或者說(shuō)Kubernetes是大規(guī)模分布部署的計(jì)算機(jī)集群操作系統(tǒng)胖缤。
為了讓大家對(duì)上邊這句話有一個(gè)感性的認(rèn)識(shí)尚镰,咱來(lái)畫(huà)個(gè)圖說(shuō)明一下:
操作系統(tǒng)為我們提供了使用底層硬件資源的抽象接口,比如我們可以基于操作系統(tǒng)接口哪廓,來(lái)讓計(jì)算機(jī)執(zhí)行某種任務(wù)狗唉,并產(chǎn)生結(jié)果;而Kubernetes和服務(wù)器上的操作系統(tǒng)的角色類似撩独,將計(jì)算任務(wù)調(diào)度到底層集群中任意一臺(tái)還有空余計(jì)算空間的機(jī)器上敞曹,因此我們可以看到,Kubernetes其實(shí)也是扮演了這種“操作接口”综膀,最大的區(qū)別是,操作系統(tǒng)抽象的是一組計(jì)算機(jī)局齿,或者叫集群剧劝。
正是因?yàn)镵ubernetes提供的這層抽象,開(kāi)發(fā)人員在編寫(xiě)應(yīng)用程序的時(shí)候抓歼,特別是分布式系統(tǒng)讥此,不再需要在代碼里編寫(xiě)處理基礎(chǔ)設(shè)施差異的功能,取而代之的是依賴于代碼運(yùn)行之上的Kubernetes提供的能力谣妻,這些之前需要自己處理的邏輯萄喳,下推到依賴Kubernetes抽象的關(guān)注點(diǎn)包括但不限于:
- 服務(wù)發(fā)現(xiàn),提供分布式多實(shí)例部署的應(yīng)用程序之間相互調(diào)用地址解析能力的組件蹋半。
- 水平擴(kuò)展他巨,隨著應(yīng)用程序流量的波動(dòng),可以靈活的增加或者減少處理實(shí)例的機(jī)制减江,幫助企業(yè)在服務(wù)等級(jí)和花費(fèi)兩個(gè)維度達(dá)成平衡染突。
- 負(fù)載均衡,將請(qǐng)求流量均衡的分布到應(yīng)用的多個(gè)分布部署的實(shí)例上辈灼。
- 容錯(cuò)能力份企,也叫自愈能力,保證系統(tǒng)健康平穩(wěn)運(yùn)行巡莹。當(dāng)出現(xiàn)應(yīng)用的某個(gè)實(shí)例故障司志,或者應(yīng)用依賴的某個(gè)組件故障甜紫,通過(guò)重啟或者移動(dòng)應(yīng)用到健康的計(jì)算節(jié)點(diǎn)的方式來(lái)提供可用性和可靠性保障。
- 選主能力骂远,在需要提供Active-Passive部署模式的應(yīng)用中棵介,K8S提供了一種確定哪些實(shí)例是Active,而哪些是Passive實(shí)例的機(jī)制吧史,并且當(dāng)主實(shí)例出現(xiàn)問(wèn)題邮辽,Passive實(shí)例可以馬上承接后續(xù)的計(jì)算任務(wù)和流量。
通過(guò)使用K8S提供的如上這些能力贸营,我們?cè)诰帉?xiě)應(yīng)用代碼的時(shí)候吨述,就可以把寶貴的時(shí)間花費(fèi)在開(kāi)發(fā)新功能武氓,優(yōu)化現(xiàn)有邏輯上萤皂,而不用浪費(fèi)在和不同的底層部署平臺(tái)的適配上,這不光讓開(kāi)發(fā)人員人員開(kāi)發(fā)效率更高斜筐,也會(huì)讓開(kāi)發(fā)人員心情更加愉悅冰啃,寫(xiě)出質(zhì)量更高的代碼邓夕。
對(duì)新事物有好奇心的小伙伴可能會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題,你說(shuō)Kubernetes是個(gè)操作系統(tǒng)阎毅,那么我們是如何安裝這個(gè)操作系統(tǒng)呢焚刚?我們能理解單臺(tái)服務(wù)器初始化的過(guò)程,我們不論是通過(guò)手動(dòng)扇调,還是在自舉的時(shí)候從外部加載操作系統(tǒng)完成安裝矿咕,最終都會(huì)有安裝操作系統(tǒng)這么個(gè)過(guò)程,但是如果你需要在1000臺(tái)機(jī)器上安裝1個(gè)操作系統(tǒng)狼钮,這個(gè)貌似不太容易理解碳柱,我們還是先看圖:
從上圖我們可以看到, Kubernetes集群會(huì)無(wú)差別的將提供的計(jì)算機(jī)分成兩組:Master節(jié)點(diǎn)組和Worker節(jié)點(diǎn)組。Master節(jié)點(diǎn)組中的機(jī)器上熬芜,部署了和Kubernetes集群管理有關(guān)的組件莲镣,這些組件共同構(gòu)成了Kuberntes的管理大腦,負(fù)責(zé)控制整個(gè)集群的運(yùn)行和維護(hù)等工作涎拉;而對(duì)于開(kāi)發(fā)人員和運(yùn)維人員來(lái)說(shuō)瑞侮,我們通過(guò)kubectl -f xx.yaml部署的應(yīng)用程序,就運(yùn)行在Worker節(jié)點(diǎn)組的一臺(tái)或者多臺(tái)機(jī)器上曼库。
題外:熟悉Istio的同學(xué)應(yīng)該知道數(shù)據(jù)平面的概念区岗,并且很多文章中把Kubernetes的Worker節(jié)點(diǎn)也稱作是Data Node,但是由于Kubernetes平臺(tái)的核心是解決應(yīng)用的部署毁枯,運(yùn)維和資源調(diào)度等工作慈缔,因此筆者還是會(huì)沿用Worker節(jié)點(diǎn)的命名,但是當(dāng)你碰到Kubernetes的文章說(shuō)說(shuō)Data Node的時(shí)候种玛,知道說(shuō)的是Worker Node就行藐鹤,但是因?yàn)镮stio本身就是基于Kubernetes部署瓤檐,因此要特別注意上下文。
控制節(jié)點(diǎn)需要機(jī)器的數(shù)量一般是一臺(tái)或者三臺(tái)娱节,取決于我們對(duì)可靠性的需求挠蛉,具體來(lái)說(shuō),如果K8S集群是用來(lái)測(cè)試肄满,那么部署一臺(tái)機(jī)器就足夠了谴古,但是如果是生產(chǎn)環(huán)境,那就需要至少三臺(tái)機(jī)器稠歉。而Worker集群的節(jié)點(diǎn)數(shù)量掰担,取決于我們會(huì)部署多少應(yīng)用到集群上,因此可以按照自己項(xiàng)目的實(shí)際需求來(lái)規(guī)劃資源怒炸。
當(dāng)我們?cè)诙嗯_(tái)機(jī)器上部署了Kubernetes集群之后带饱,我們對(duì)這些機(jī)器的操作,就當(dāng)做一個(gè)整體來(lái)看待了阅羹,我們不用再像傳統(tǒng)的單機(jī)那樣對(duì)待每臺(tái)機(jī)器勺疼,特別是對(duì)于Worker節(jié)點(diǎn)組來(lái)說(shuō),無(wú)論有多少臺(tái)機(jī)器加入的工作節(jié)點(diǎn)組中捏鱼,Kubernetes會(huì)按一個(gè)統(tǒng)一的計(jì)算資源來(lái)對(duì)待执庐,如下圖所示:
說(shuō)有工作節(jié)點(diǎn)組成一個(gè)連續(xù)的空間供應(yīng)用程序部署這句話其實(shí)不是很?chē)?yán)謹(jǐn),因?yàn)槲覀兤鋵?shí)不能部署一個(gè)需要橫跨兩臺(tái)機(jī)器的應(yīng)用穷躁,Kubernetes并不支持一個(gè)應(yīng)用的實(shí)例橫跨兩臺(tái)機(jī)器的能力耕肩,因此我們的應(yīng)用實(shí)例必須足夠小,能夠最少被部署到一臺(tái)機(jī)器的資源上问潭。
Kubernetes在部署應(yīng)用程序的時(shí)候,會(huì)有一套完整的邏輯來(lái)完成“調(diào)度”工作婚被,調(diào)度在分布式系統(tǒng)里是個(gè)高頻出現(xiàn)的詞匯狡忙,簡(jiǎn)單理解就是將資源申請(qǐng),找到一個(gè)無(wú)論從資源的平衡性址芯,可用性灾茁,系統(tǒng)的穩(wěn)定性角度最佳的節(jié)點(diǎn),這個(gè)過(guò)程是整個(gè)Kubernetes的核心谷炸,我們后續(xù)會(huì)專門(mén)介紹北专。另外調(diào)度在大數(shù)據(jù)平臺(tái),分布式系統(tǒng)中有廣泛的應(yīng)用旬陡,比如在Hadoop中拓颓,就有專門(mén)的調(diào)度組件來(lái)將計(jì)算任務(wù)下推到具體的計(jì)算節(jié)點(diǎn)上,完成計(jì)算描孟。
K8S的調(diào)度組件目前并沒(méi)有標(biāo)準(zhǔn)化驶睦,標(biāo)準(zhǔn)化的意思是砰左,不像我們后邊會(huì)提到的CSI(通用存儲(chǔ)接口)),CNI(通用網(wǎng)絡(luò)接口)以及CRI(容器運(yùn)行接口),關(guān)于調(diào)度引擎场航,目前Kubernetes不提供定制化和擴(kuò)展缠导,這部分會(huì)是后續(xù)Kubernetes重點(diǎn)開(kāi)發(fā)的方向。
當(dāng)應(yīng)用部署到K8S集群上之后溉痢,其實(shí)用戶并不用太關(guān)心具體部署到哪個(gè)節(jié)點(diǎn)了僻造。但是這句話不能太絕對(duì),考慮到具體調(diào)度算法的差異孩饼,需要針對(duì)特殊場(chǎng)景來(lái)特殊處理髓削。比如筆者在之前在華南作為大促總負(fù)責(zé)人,在大促之前會(huì)做一個(gè)叫:聚合度的排查捣辆,也就是說(shuō)看看我的訂單中心的實(shí)例是否被比較均衡的調(diào)度到了多太機(jī)器上蔬螟,而不是都堆在一臺(tái)物理機(jī)器上,這種排查其實(shí)不應(yīng)該需要用戶關(guān)注汽畴,但是我們一定要清楚背后的邏輯旧巾,的確在特殊的場(chǎng)景下,會(huì)出現(xiàn)一臺(tái)機(jī)器上的資源很充足忍些,大部分實(shí)例都在一臺(tái)機(jī)器上鲁猩,那么這臺(tái)機(jī)器的網(wǎng)絡(luò)和磁盤(pán)IO等就會(huì)在并發(fā)量高的時(shí)候,出現(xiàn)問(wèn)題罢坝。
雖然筆者舉了個(gè)例子證明了我們有時(shí)候還是需要關(guān)注廓握,但是這里要強(qiáng)調(diào)的是:Kubernetes可能會(huì)移動(dòng)你的應(yīng)用程序,因此你不應(yīng)該特別關(guān)注應(yīng)用運(yùn)行的Node節(jié)點(diǎn)嘁酿。
其實(shí)筆者已經(jīng)基本介紹了整個(gè)Kubernetes集群的大致架構(gòu)隙券,但是上邊的介紹就想隔靴搔癢一般,并不是很痛快闹司,那么接下來(lái)娱仔,我們就把靴子脫了,看看K8S集群的完整架構(gòu)游桩。下圖是展示了更多細(xì)節(jié)的Kubernetes架構(gòu)圖牲迫,我們來(lái)一起看看:
從上邊的架構(gòu)圖可以看到,Kubernetes的核心就是兩個(gè)平面借卧,控制平面和工作節(jié)點(diǎn)平面盹憎,這兩個(gè)平面上運(yùn)行的不同Kubernetes組件,共同組成整個(gè)K8S集群铐刘,我們來(lái)分別介紹一下陪每。
【控制平面上的組件介紹 - Control Panel】
控制平面是整個(gè)集群的大腦,又多個(gè)運(yùn)行在Master節(jié)點(diǎn)上的組件組成,在高可用的環(huán)境中奶稠,Maser節(jié)點(diǎn)一般由多臺(tái)機(jī)器組成俯艰,來(lái)提供高可用能力,關(guān)于控制平面包含的組件锌订,如下圖所示:
基于上圖的描述竹握,管理平面包含的組件和簡(jiǎn)單的介紹如下:
- Kubernetes的API Server暴露了Restful風(fēng)格的操作接口,開(kāi)發(fā)和運(yùn)維人員可以通過(guò)這些接口來(lái)部署辆飘,更細(xì)和下線應(yīng)用程序啦辐,包括運(yùn)維和監(jiān)控等工作。
- ETCD是一個(gè)分布式的KV存儲(chǔ)引擎蜈项,我們通過(guò)API Server提供的API來(lái)部署應(yīng)用程序的時(shí)候芹关,應(yīng)用的描述信息(yaml文件)會(huì)被持久化到ETCD中,并且API Server是唯一可以對(duì)ETCD進(jìn)行CRUD操作的組件紧卒。
- 控制器負(fù)責(zé)將我們通過(guò)API Server部署到集群的應(yīng)用運(yùn)行起來(lái)侥衬,大部分控制器只是簡(jiǎn)單的創(chuàng)建對(duì)象,但是有些也需要和集群外部的服務(wù)組件進(jìn)行通信跑芳,比如集群中的PV不夠了轴总,當(dāng)我的YAML聲明了一個(gè)新的PVC,那么這個(gè)時(shí)候就需要外部的比如說(shuō)云平臺(tái)存儲(chǔ)提供接口來(lái)提供更多的存儲(chǔ)卷博个。關(guān)于PV和PVC怀樟,如果你不能理解,也沒(méi)有關(guān)系盆佣,后邊會(huì)有介紹往堡。
- 調(diào)度器,調(diào)度器就是筆者前邊說(shuō)的共耍,為新部署的應(yīng)用找合適的部署節(jié)點(diǎn)的組件虑灰,這個(gè)過(guò)程異常的復(fù)雜,目前你只需要理解到這個(gè)節(jié)點(diǎn)會(huì)基于應(yīng)用申請(qǐng)的資源和整個(gè)集群現(xiàn)在有的資源余量痹兜,來(lái)找到最佳匹配瘩缆,其實(shí)找到就是將應(yīng)用的Nodename設(shè)置一下,因?yàn)楣P者還沒(méi)有介紹容器佃蚜,POD的概念,因此先簡(jiǎn)單這么理解着绊。
以上就是整個(gè)管理平面的所有Kubernetes組件的介紹谐算。讀到這里,你可能會(huì)問(wèn)归露,說(shuō)了半天洲脂,我還是不知道我的應(yīng)用具體在哪里運(yùn)行啊,我們接著調(diào)度器的執(zhí)行結(jié)果來(lái)繼續(xù)討論,因?yàn)橥ㄟ^(guò)調(diào)度器已經(jīng)為應(yīng)用找到了合適的運(yùn)行節(jié)點(diǎn)恐锦,那么這個(gè)時(shí)候焦點(diǎn)就轉(zhuǎn)到了Wroker node往果,我們來(lái)看看工作節(jié)點(diǎn)上有哪些組件。
【工作節(jié)點(diǎn)上的組件介紹 - Worker Node plane】
工作節(jié)點(diǎn)比起來(lái)控制節(jié)點(diǎn)簡(jiǎn)單很多一铅,工作節(jié)點(diǎn)就是單純的運(yùn)行我們通過(guò)API Server部署到集群上應(yīng)用陕贮,除了運(yùn)行應(yīng)用,還包括監(jiān)控潘飘,提供應(yīng)用多個(gè)實(shí)際之間的聯(lián)通肮之,工作節(jié)點(diǎn)上的Kubernetes組件如下圖所示:
基于上圖的信息,我們可以看到Kubernetes工作節(jié)點(diǎn)上包含了如下一些組件:
- Kubelet組件卜录,這個(gè)組件非常重要戈擒,這個(gè)組件是形成集群的關(guān)鍵。Kubelet是運(yùn)行在工作節(jié)點(diǎn)上的代理插件, 負(fù)責(zé)和API Server通信艰毒,以及管理運(yùn)行在工作節(jié)點(diǎn)上應(yīng)用程序筐高。另外Kubelet也會(huì)將應(yīng)用運(yùn)行的狀態(tài)反饋給控制節(jié)點(diǎn)上的組件。
- 容器運(yùn)行時(shí)丑瞧,可以是Docker或者任何Kubernetes提供支持的容器組件柑土,容器運(yùn)行時(shí)的主要工作就是基于提供的接口,和Kublets配合將我們的應(yīng)用運(yùn)行起來(lái)嗦篱。
- Kube代理冰单,此代理負(fù)責(zé)將入口請(qǐng)求流量代理到應(yīng)用的多個(gè)實(shí)例上。
除了這些組件之外灸促,Kubernets中還包括DNS诫欠,網(wǎng)絡(luò)插件等,這些組件大部分情況下都是運(yùn)行在工作節(jié)點(diǎn)上的浴栽。
好了荒叼,今天的文章就這么多內(nèi)容了,筆者接下來(lái)會(huì)介紹如何在K8S行啟動(dòng)一個(gè)應(yīng)用程序典鸡,敬請(qǐng)期待被廓。