1.K8S歷史
K8S是谷歌的項目惫确,它的前身是Borg
Borg是Google用來管理公司內(nèi)部所有作業(yè)的這樣一個作業(yè)管理平臺。過去的一段時間里面诸狭,對于作業(yè)管理或者對于云管理产上,那主要其實是兩條路隘马,第一條路就是以O(shè)penstack這類虛擬化技術(shù)為主的這種云管平臺,就相當于說我把很多物理機在這個基礎(chǔ)之上裝上Hypervisor另患,然后在上面在啟一些虛擬機盏袄,那么再把這些虛擬機組成一個大的云平臺。這是以O(shè)penstack為例的葱她,它主要的云平臺交付的最核心的產(chǎn)品或者是它最終的交付形態(tài)就是一個個的操作系統(tǒng)撩扒,在這個操作系統(tǒng)之上我們需要部署自己的應(yīng)用,后續(xù)應(yīng)用的升級吨些,應(yīng)用的管理跟底層的基礎(chǔ)云平臺它是相對有比較明確的界限搓谆。所以在以前的云平臺里面,都會有比較清晰的像這種基礎(chǔ)架構(gòu)的Inrasturcture as a Service.平臺的Platform as a Service.Saas Software as a Service,就會有這樣明確的界限锤灿。
那么另外一類就是以Google的Borg系統(tǒng)為主的挽拔,它沒有虛擬化技術(shù),它的主要的一個實現(xiàn)方式就是用輕量級的作業(yè)調(diào)度但校,在做kubernetes之前螃诅,IBM有幾年其實是做這種傳統(tǒng)High Performance Computing平臺的(高性能運算),其核心就是作業(yè)調(diào)度状囱,調(diào)度的是一個個的進程术裸。所以Borg就是一個這樣的平臺,Borg本身利用了一些容器技術(shù),比如說Cgroup技術(shù)亭枷,就是Google開源給Linux袭艺。
1.1 Borg簡介
1.2 基本概念
1.3 Borg架構(gòu)
1.4 應(yīng)用高可用
1.5 Borg系統(tǒng)自身高可用
1.6 資源利用率
1.7 Borg調(diào)度原理
1.8隔離性
2.什么是K8S
2.1命令式VS聲明式
2.2聲明式系統(tǒng)規(guī)范
2.3 K8S:聲明式系統(tǒng)
pod是描述一個個作業(yè)的,它是基本的一個調(diào)度單元叨粘,用戶可以在pod里面定義要運行哪個容器鏡像猾编。
Kubernetes里面允許用戶去定義一個Service對象瘤睹,Service這個對象一旦被創(chuàng)建出來,Kubernetes就會完成負載均衡的配置以及域名配置答倡,就類似于剛才Borg的Naming Service
2.4 K8S采用與Borg類似的架構(gòu)
集群里面會分為管理節(jié)點和Worker節(jié)點(作業(yè)節(jié)點)
2.4.1 API Server
管理節(jié)點會運行API Server轰传,API Server其實就是一個簡單的restServer,它接受Web請求瘪撇,所有Web請求無論是通過命令行還是瀏覽器也好都會轉(zhuǎn)換成一個REST的調(diào)用获茬,發(fā)到API Server里面。API Server本身邏輯簡單倔既,沒有太多的業(yè)務(wù)邏輯恕曲,它會把這個請求直接存到自己的數(shù)據(jù)庫里面(etcd,作為整個集群的一個分布式鍵值存儲體系)。etcd有一個watcher模式渤涌,也就是說當我們?nèi)et一個對象的時候佩谣,我們可以加一個watch的參數(shù),那么加了watch參數(shù)以后歼捏,那么你客戶端的這次get請求首先會完成稿存,第二這次連接不會斷掉的話,你客戶端就會跟服務(wù)器端保持一個長連接瞳秽,如果所請求完了之后的對象發(fā)生后續(xù)的變化瓣履,etcd會主動把這個變化以事件的形式推給客戶端。所以一旦etcd那里發(fā)生了變化练俐,也會通知到API Server袖迎,API Server也可以把這個變化給推送出去。
2.4.2 scheduler
scheduler:用戶創(chuàng)建一個pod(作業(yè))的時候腺晾,那么這個請求會被API Server接收到燕锥,API Server就會告訴調(diào)度器說有這樣一個Pod的調(diào)度需求,那么scheduler就會去做調(diào)度悯蝉,scheduler主要看這個pod需要多少資源归形,另外也要看當前集群里面的資源利用狀況,這些利用狀況都是從worker節(jié)點的kubelet上得到的鼻由。kublet會把節(jié)點的狀況報告給API Server,API Server會把這些信息存儲到etcd暇榴,同時scheduler就能接收到這些變化的請求。然后scheduler可以把pod和節(jié)點做一個綁定蕉世,并告訴API Server蔼紧。API Server相當于把Pod的信息里面的NameNode屬性更新到etcd里面去。接下來每個節(jié)點上運行的kubelet就會看跟我這個節(jié)點相關(guān)的pod有哪些狠轻,如果這個新的pod跟我這個節(jié)點相關(guān)奸例,那我就去啟動進程。
2.4.3 Controllers
K8S不僅僅只有Pod向楼,還有其他抽象對象查吊,每個抽象對象都一些特定的職責谐区,比如說剛才用戶要建立的Service,那么K8S要幫它去配域名的對吧菩貌,要配負載均衡的卢佣。每個worker節(jié)點上有個kube-proxy去配置負載均衡
那controller里面就有一些更加高級的功能重荠,是面向K8S的不同對象去做整個集群的自動化配置的箭阶。
2.5 主要組件
API Server,注冊了一些對象Handler戈鲁,當你這個對象要操作任何對象的時候仇参,它實際上轉(zhuǎn)化成了一個REST的調(diào)用,由API Server來接收婆殿,API Server其實就是整個集群控制面的API網(wǎng)關(guān)诈乒。
Controller manager管理了一堆的控制器。比如Deployment控制器婆芦,ReplicaSet控制器怕磨,NodeLifeCycle的控制器,分別用來管理不同的對象消约。它相當于一個大腦肠鲫。API Server收到請求之后只是存儲起來,具體該怎么做或粮,是由這個controller manager去做的导饲。
kublet:上傳節(jié)點的而健康裝填,維護當前節(jié)點的所有Pod的生命周期
kube-proxy:當你去定義一個Service的時候氯材,要發(fā)布一個服務(wù)的時候渣锦,需要為這個服務(wù)配置負載均衡,這個是由Proxy去做的氢哮。
Pod:每一個Pod里面袋毙,都是通過container的RuntimeService去啟的應(yīng)用。
cAdvisor:用于收集容器進程的一些健康狀況冗尤。包括資源容量听盖,比如說你用了CPU多少memory。以此做到一個監(jiān)控生闲。
2.6 K8S的主節(jié)點
其實controller和Scheduler沒有什么本質(zhì)區(qū)別媳溺,只不過controller是專職做調(diào)度的
2.7 etcd
選主是很重要的事情,所有的寫操作都由leader去做碍讯。另外master需要把寫操作指令下發(fā)到其他節(jié)點上面去悬蔽,保證這些節(jié)點跟leader同步
我們直接可以進到etcd的pod里面查看數(shù)據(jù)。關(guān)鍵的是etcd是有狀態(tài)的
2.8 API Server
這個是無狀態(tài)的捉兴。Mutating是什么意思呢蝎困,當API Server收到請求后录语,可能想在這個請求里面加一些屬性操作,這個就是Mutating禾乘。
APIServer本身是一個RestServer澎埠,RestServer它就要去注冊自己的每一個不同對象的Handler。所以它有個APIHandler的注冊的過程始藕,然后接下來會去做認證蒲稳,認證可以用自帶的認證,也可以用戶自定義一些認證伍派,通過掛鉤的方式弄進來
在接下來就是限流--審計--鑒權(quán)
2.9 Controller Manager
Controller Manager監(jiān)控了整個APIServer江耀,里面有很多的控制器,不同的控制器會負責不通的職責诉植。那么其有些控制器祥国,其實所有的控制器遵循同樣的規(guī)范,就是先去讀用戶的這個抽象對象晾腔,那么這個抽象對象里面有用戶的期望狀態(tài)(Desired State)舌稀。當讀到這個狀態(tài)之后,接下來就要開始干活了灼擂,也就是去做真實的配置壁查,它要確保這個系統(tǒng)的真實狀態(tài)跟用戶的期望狀態(tài)保持一致。如果這次配置出現(xiàn)了錯誤缤至,它就要自動重試潮罪。
比如說你要創(chuàng)建一個Pod,這個Pod需要4個CPU领斥,但是當前的集群已經(jīng)沒有任何的節(jié)點嫉到,能夠滿足你的4個CPU的需求,這個時候你的Pod就會處于一個Pending的狀態(tài)月洛,它就不會被調(diào)成功何恶。然后需要不斷的重試去滿足要求。
2.10 控制器的工作流程
針對任何對象嚼黔,K8S其實它有一些輔助的一些工具叫CodeGenerator细层,會幫忙生成這個對象的一些代碼框架,這個代碼框架其實主要就是它的Controller Interface.
這個Intereface氛圍Listener和Informer唬涧。K8S中任何的對象是允許去做監(jiān)聽的疫赎,這個Informer相當于是去監(jiān)聽某個對象,對象發(fā)生了任何變化后碎节,把這個對象放到隊列里面捧搞,然后后續(xù)由worker從隊列里面獲取這些事件。
Listener:它提供了一些接口,讓用戶從client-cache里面獲取對象胎撇,而不需要去訪問API Server了介粘。
2.11 Informer的機制
List&Watch。List會把當前的所有對象List返回回來晚树,第二作為一個長連接姻采,它會關(guān)注后續(xù)的變化。
Reflector:按照給定的這個對象的類型爵憎,把API Server里面的一些JSON和Protobuf類型的對象按照反射的方式轉(zhuǎn)換成對象慨亲。
轉(zhuǎn)換好后的對象就會存到一個Thread safe Store里面來。這里面的對象凡是被list到還是watch到纲堵,都會通過Informer發(fā)送到handler巡雨,來處理這些事件。
2.12 控制器的協(xié)同工作原理
當我們創(chuàng)建一個Deployment(包含一個Nginx鏡像的Pod)席函,我們會發(fā)起一條命令給API Server。發(fā)起的時候冈涧,客戶端會去讀取confile file文件(在/root/.kube/config目錄下面)茂附,這個文件是kubctl默認讀取的一個配置,這個配置里面有API Server的地址督弓,以及客戶身份的一些認證信息营曼。
API Server收到請求以后,就會把這個請求存到etcd里面去愚隧,存好以后蒂阱,這個時候控制器就開始工作了,控制器里面有一對的Controller狂塘,Deployment這個Controller就會去解析用戶傳遞過來的Deployment對象录煤,然后根據(jù)里面的模板創(chuàng)建ReplicaSet(副本集對象)。
當這個副本集創(chuàng)建好了以后荞胡,它又一樣經(jīng)過認證妈踊、鑒權(quán)等存到etcd里面,這個時候ReplicaSet Controller會Watch API Server泪漂,它發(fā)現(xiàn)有個replicaSet對象被創(chuàng)建了廊营,那么它就要去解析了,看其中的pod模板是咋樣的萝勤,接下來就會創(chuàng)建一個Pod露筒。這個Pod創(chuàng)建請求就會被提交到APIServer。
這個Pod被創(chuàng)建的時候敌卓,沒有經(jīng)過調(diào)度慎式,沒有和任何節(jié)點產(chǎn)生綁定關(guān)系。那么這個時候調(diào)度器就要開始工作了,它去監(jiān)聽這個Pod瞬捕,發(fā)現(xiàn)這個Pod沒有跟節(jié)點產(chǎn)生過綁定關(guān)系鞍历,那么它就去找現(xiàn)有集群里面的所有可用節(jié)點,并匹配一個適合這個Pod的節(jié)點肪虎。這個時候Pod的Nodename就會被賦予一個值劣砍。
這個時候節(jié)點的kubelet會嘗試去加載這個Pod,通過Container Runtime Interface先把這個容器進程拉起來扇救,通過Container Network Interface把網(wǎng)絡(luò)配置好刑枝,通過Container Storage Interface幫它把這個存儲掛上去。這樣就完成了整個Pod應(yīng)用的加載
2.13 Scheduler
2.14 kubelet
2.15 kube-proxy
當我們把一個Service發(fā)布出來以后迅腔,kube-proxy去配負載均衡装畅。為服務(wù)發(fā)布做出努力的這樣一個組件。