《K8s与云原生应用》之K8s的系统架构与设计理念
《Kubernetes與云原生應(yīng)用》專欄是InfoQ向輕元科技首席架構(gòu)師王昕約稿的系列文章。本專欄包含8篇內(nèi)容,將會從介紹和分析Kubernetes系統(tǒng)以及云原生應(yīng)用入手,逐步推出基于Kubernetes的容器設(shè)計模式實踐案例,希望對計劃應(yīng)用Kubernetes的朋友有所幫助。本文是該專欄的第一篇。
Kubernetes系統(tǒng)架構(gòu)與設(shè)計理念
云原生應(yīng)用的設(shè)計理念與挑戰(zhàn)
Kubernetes與云原生應(yīng)用的容器設(shè)計模式
Kubernetes容器設(shè)計模式實踐案例-單節(jié)點多容器模式
Kubernetes容器設(shè)計模式實踐案例-多節(jié)點選舉模式
Kubernetes容器設(shè)計模式實踐案例-工作隊列模式
Kubernetes容器設(shè)計模式實踐案例-分散收集模式
云原生應(yīng)用的容器設(shè)計模式綜述與展望
Kubernetes與云原生應(yīng)用簡介
隨著Docker技術(shù)的發(fā)展和廣泛流行,云原生應(yīng)用和容器調(diào)度管理系統(tǒng)也成為IT領(lǐng)域大熱的詞匯。事實上,云原生應(yīng)用的思想,在Docker技術(shù)火爆之前,已經(jīng)由云計算技術(shù)的領(lǐng)導(dǎo)者和分布式系統(tǒng)架構(gòu)的推廣者廣泛傳播,例如云原生應(yīng)用的12要素早在2011年就由Heroku的工程師提出了;只不過以虛擬機技術(shù)作為云原生應(yīng)用的基礎(chǔ)實施,由于虛擬機鏡像大、鏡像標(biāo)準(zhǔn)不統(tǒng)一以及打包流程和工具不統(tǒng)一,無法業(yè)界廣泛接受的云原生應(yīng)用標(biāo)準(zhǔn),限制了云原生應(yīng)用的流行。而Docker的出現(xiàn)正好解決了這些限制云原生應(yīng)用構(gòu)建、交付和運行的瓶頸,使得構(gòu)建云原生應(yīng)用成為了使用Docker的開發(fā)者自然而然的選擇。
單機的Docker引擎和單一的容器鏡像只能解決單一服務(wù)的打包和測試問題。而要運行生產(chǎn)級的企業(yè)級應(yīng)用,就需要容器調(diào)度管理系統(tǒng)。在這里面,Docker技術(shù)就仿佛運送系統(tǒng)零件的集裝箱,把云原生應(yīng)用的各個標(biāo)準(zhǔn)化零件交付到各個企業(yè)的不同碼頭,而容器調(diào)度管理系統(tǒng)就是企業(yè)應(yīng)用的運行車間,把不同的零件組裝、運行、維護起來。
Kubernetes是為生產(chǎn)環(huán)境而設(shè)計的容器調(diào)度管理系統(tǒng),對于負(fù)載均衡、服務(wù)發(fā)現(xiàn)、高可用、滾動升級、自動伸縮等容器云平臺的功能要求有原生支持。由于Kubernetes在K和s間有8個字母,因此常簡稱K8s。事實上,隨著對K8s系統(tǒng)架構(gòu)與設(shè)計理念的了解深入,我們會發(fā)現(xiàn)K8s系統(tǒng)正是處處為運行云原生應(yīng)用而設(shè)計考慮;同時,隨著對K8s系統(tǒng)使用的加深和加廣,也會有越來越多有關(guān)云原生應(yīng)用的設(shè)計模式產(chǎn)生出來,使得基于K8s系統(tǒng)設(shè)計和開發(fā)生產(chǎn)級的復(fù)雜云原生應(yīng)用變得像啟動一個單機版容器服務(wù)那樣簡單易用。
本系列文章將會從介紹和分析K8s系統(tǒng)以及云原生應(yīng)用入手,逐步推出基于K8s的容器設(shè)計模式實踐案例,希望對計劃應(yīng)用K8s的朋友有所幫助。
Kubernetes的最新進展
K8s于2016年7月發(fā)布了1.3的正式版,帶來了3個實驗性的新功能:基于角色的權(quán)限控制RBAC,跨地區(qū)跨云的聯(lián)合集群服務(wù)Federation和有狀態(tài)應(yīng)用微服務(wù)集合PetSet,讓大家可以對K8s集群本身的技術(shù)發(fā)展趨勢窺豹一斑。本文的系統(tǒng)架構(gòu)和核心技術(shù)解析部分會包含這幾項功能的詳細(xì)介紹。
Kubernetes與容器設(shè)計模式
K8s在2016年6月的云計算大會上發(fā)表了有關(guān)容器設(shè)計模式的論文《Design patterns for container-based distributed systems》,介紹了基于K8s設(shè)計云原生應(yīng)用的容器設(shè)計模式,為基于K8s的云原生應(yīng)用的設(shè)計模式劃定了藍(lán)圖。在K8s與云原生應(yīng)用系列文章中我們會結(jié)合具體應(yīng)用案例解析這些設(shè)計模式。
Kubernetes的系統(tǒng)架構(gòu)
Kubernetes的系統(tǒng)架構(gòu)
一個K8s集群是由分布式存儲(etcd)、服務(wù)節(jié)點(Minion,etcd現(xiàn)在稱為Node)和控制節(jié)點(Master)構(gòu)成的。所有的集群狀態(tài)都保存在etcd中,Master節(jié)點上則運行集群的管理控制模塊。Node節(jié)點是真正運行應(yīng)用容器的主機節(jié)點,在每個Minion節(jié)點上都會運行一個Kubelet代理,控制該節(jié)點上的容器、鏡像和存儲卷等。
Kubernetes的架構(gòu)實現(xiàn)理念
K8s在實現(xiàn)上述架構(gòu)時要基于以下架構(gòu)理念:
-
只有API Server與存儲通信,其他模塊通過API Server訪問集群狀態(tài)。這樣第一,是為了保證集群狀態(tài)訪問的安全。第二,是為了隔離集群狀態(tài)訪問的方式和后端存儲實現(xiàn)的方式:API Server是狀態(tài)訪問的方式,不會因為后端存儲技術(shù)etcd的改變而改變。加入以后將etcd更換成其他的存儲方式,并不會影響依賴依賴API Server的其他K8s系統(tǒng)模塊。
-
一個工作節(jié)點被攻破不能導(dǎo)致整個K8s集群被攻破。這是所有分布式系統(tǒng)架構(gòu)設(shè)計中都應(yīng)該考慮的問題。
-
考慮網(wǎng)絡(luò)隨時可能斷開的情況,沒有新配置聲明時各模塊按照之前的配置聲明繼續(xù)工作。在K8s集群中,所有的配置管理操作都聲明式而非命令式的,因為聲明式操作對于網(wǎng)絡(luò)故障等分布式系統(tǒng)常見的故障情況更加穩(wěn)定。
-
各個模塊在內(nèi)存中緩存自己的相關(guān)狀態(tài)以提高系統(tǒng)性能。
-
需要監(jiān)控某個系統(tǒng)狀態(tài)來做下一步動作的時候,優(yōu)先考慮觀察通知模式,其次再考慮輪詢模式,這也是為了提高系統(tǒng)的響應(yīng)速度。
K8s的核心技術(shù)概念和API對象
API對象是K8s集群中的管理操作單元。K8s集群系統(tǒng)每支持一項新功能,引入一項新技術(shù),一定會新引入對應(yīng)的API對象,支持對該功能的管理操作。例如副本集Replica Set對應(yīng)的API對象是RS。
每個API對象都有3大類屬性:元數(shù)據(jù)metadata、規(guī)范spec和狀態(tài)status。元數(shù)據(jù)是用來標(biāo)識API對象的,每個對象都至少有3個元數(shù)據(jù):namespace,name和uid;除此以外還有各種各樣的標(biāo)簽labels用來標(biāo)識和匹配不同的對象,例如用戶可以用標(biāo)簽env來標(biāo)識區(qū)分不同的服務(wù)部署環(huán)境,分別用env=dev、env=testing、env=production來標(biāo)識開發(fā)、測試、生產(chǎn)的不同服務(wù)。規(guī)范描述了用戶期望K8s集群中的分布式系統(tǒng)達(dá)到的理想狀態(tài)(Desired State),例如用戶可以通過復(fù)制控制器Replication Controller設(shè)置期望的Pod副本數(shù)為3;status描述了系統(tǒng)實際當(dāng)前達(dá)到的狀態(tài)(Status),例如系統(tǒng)當(dāng)前實際的Pod副本數(shù)為2;那么復(fù)制控制器當(dāng)前的程序邏輯就是自動啟動新的Pod,爭取達(dá)到副本數(shù)為3。
K8s中所有的配置都是通過API對象的spec去設(shè)置的,也就是用戶通過配置系統(tǒng)的理想狀態(tài)來改變系統(tǒng),這是k8s重要設(shè)計理念之一,即所有的操作都是聲明式(Declarative)的而不是命令式(Imperative)的。聲明式操作在分布式系統(tǒng)中的好處是穩(wěn)定,不怕丟操作或運行多次,例如設(shè)置副本數(shù)為3的操作運行多次也還是一個結(jié)果,而給副本數(shù)加1的操作就不是聲明式的,運行多次結(jié)果就錯了。
微服務(wù)豆莢(Pod)
K8s有很多技術(shù)概念,同時對應(yīng)很多API對象,最重要的也是最基礎(chǔ)的是微服務(wù)豆莢Pod。Pod是在K8s集群中運行部署應(yīng)用或服務(wù)的最小單元,它是可以支持多容器的。Pod的設(shè)計理念是支持多個容器在一個Pod中共享網(wǎng)絡(luò)地址和文件系統(tǒng),可以通過進程間通信和文件共享這種簡單高效的方式組合完成服務(wù)。Pod對多容器的支持是K8最基礎(chǔ)的設(shè)計理念。比如你運行一個操作系統(tǒng)發(fā)行版的軟件倉庫,一個Nginx容器用來發(fā)布軟件,另一個容器專門用來從源倉庫做同步,這兩個容器的鏡像不太可能是一個團隊開發(fā)的,但是他們一塊兒工作才能提供一個微服務(wù);這種情況下,不同的團隊各自開發(fā)構(gòu)建自己的容器鏡像,在部署的時候組合成一個微服務(wù)對外提供服務(wù)。
Pod是K8s集群中所有業(yè)務(wù)類型的基礎(chǔ),可以看作運行在K8集群中的小機器人,不同類型的業(yè)務(wù)就需要不同類型的小機器人去執(zhí)行。目前K8s中的業(yè)務(wù)主要可以分為長期伺服型(long-running)、批處理型(batch)、節(jié)點后臺支撐型(node-daemon)和有狀態(tài)應(yīng)用型(stateful application);分別對應(yīng)的小機器人控制器為Deployment、Job、DaemonSet和PetSet,本文后面會一一介紹。
復(fù)制控制器(Replication Controller,RC)
RC是K8s集群中最早的保證Pod高可用的API對象。通過監(jiān)控運行中的Pod來保證集群中運行指定數(shù)目的Pod副本。指定的數(shù)目可以是多個也可以是1個;少于指定數(shù)目,RC就會啟動運行新的Pod副本;多于指定數(shù)目,RC就會殺死多余的Pod副本。即使在指定數(shù)目為1的情況下,通過RC運行Pod也比直接運行Pod更明智,因為RC也可以發(fā)揮它高可用的能力,保證永遠(yuǎn)有1個Pod在運行。RC是K8s較早期的技術(shù)概念,只適用于長期伺服型的業(yè)務(wù)類型,比如控制小機器人提供高可用的Web服務(wù)。
副本集(Replica Set,RS)
RS是新一代RC,提供同樣的高可用能力,區(qū)別主要在于RS后來居上,能支持更多中的匹配模式。副本集對象一般不單獨使用,而是作為部署的理想狀態(tài)參數(shù)使用。
部署(Deployment)
部署表示用戶對K8s集群的一次更新操作。部署是一個比RS應(yīng)用模式更廣的API對象,可以是創(chuàng)建一個新的服務(wù),更新一個新的服務(wù),也可以是滾動升級一個服務(wù)。滾動升級一個服務(wù),實際是創(chuàng)建一個新的RS,然后逐漸將新RS中副本數(shù)增加到理想狀態(tài),將舊RS中的副本數(shù)減小到0的復(fù)合操作;這樣一個復(fù)合操作用一個RS是不太好描述的,所以用一個更通用的Deployment來描述。以K8s的發(fā)展方向,未來對所有長期伺服型的的業(yè)務(wù)的管理,都會通過Deployment來管理。
服務(wù)(Service)
RC、RS和Deployment只是保證了支撐服務(wù)的微服務(wù)豆莢的數(shù)量,但是沒有解決如何訪問這些服務(wù)的問題。一個Pod只是一個運行服務(wù)的實例,隨時可能在一個節(jié)點上停止,在另一個節(jié)點以一個新的IP啟動一個新的Pod,因此不能以確定的IP和端口號提供服務(wù)。要穩(wěn)定地提供服務(wù)需要服務(wù)發(fā)現(xiàn)和負(fù)載均衡能力。服務(wù)發(fā)現(xiàn)完成的工作,是針對客戶端訪問的服務(wù),找到對應(yīng)的的后端服務(wù)實例。在K8集群中,客戶端需要訪問的服務(wù)就是Service對象。每個Service會對應(yīng)一個集群內(nèi)部有效的虛擬IP,集群內(nèi)部通過虛擬IP訪問一個服務(wù)。在K8s集群中微服務(wù)的負(fù)載均衡是由Kube-proxy實現(xiàn)的。Kube-proxy是K8s集群內(nèi)部的負(fù)載均衡器。它是一個分布式代理服務(wù)器,在K8s的每個節(jié)點上都有一個;這一設(shè)計體現(xiàn)了它的伸縮性優(yōu)勢,需要訪問服務(wù)的節(jié)點越多,提供負(fù)載均衡能力的Kube-proxy就越多,高可用節(jié)點也隨之增多。與之相比,我們平時在服務(wù)器端做個反向代理做負(fù)載均衡,還要進一步解決反向代理的負(fù)載均衡和高可用問題。
任務(wù)(Job)
Job是K8s用來控制批處理型任務(wù)的API對象。批處理業(yè)務(wù)與長期伺服業(yè)務(wù)的主要區(qū)別是批處理業(yè)務(wù)的運行有頭有尾,而長期伺服業(yè)務(wù)在用戶不停止的情況下永遠(yuǎn)運行。Job管理的Pod根據(jù)用戶的設(shè)置把任務(wù)成功完成就自動退出了。成功完成的標(biāo)志根據(jù)不同的spec.completions策略而不同:單Pod型任務(wù)有一個Pod成功就標(biāo)志完成;定數(shù)成功型任務(wù)保證有N個任務(wù)全部成功;工作隊列型任務(wù)根據(jù)應(yīng)用確認(rèn)的全局成功而標(biāo)志成功。
后臺支撐服務(wù)集(DaemonSet)
長期伺服型和批處理型服務(wù)的核心在業(yè)務(wù)應(yīng)用,可能有些節(jié)點運行多個同類業(yè)務(wù)的Pod,有些節(jié)點上又沒有這類Pod運行;而后臺支撐型服務(wù)的核心關(guān)注點在K8s集群中的節(jié)點(物理機或虛擬機),要保證每個節(jié)點上都有一個此類Pod運行。節(jié)點可能是所有集群節(jié)點也可能是通過nodeSelector選定的一些特定節(jié)點。典型的后臺支撐型服務(wù)包括,存儲,日志和監(jiān)控等在每個節(jié)點上支持K8s集群運行的服務(wù)。
有狀態(tài)服務(wù)集(PetSet)
K8s在1.3版本里發(fā)布了Alpha版的PetSet功能。在云原生應(yīng)用的體系里,有下面兩組近義詞;第一組是無狀態(tài)(stateless)、牲畜(cattle)、無名(nameless)、可丟棄(disposable);第二組是有狀態(tài)(stateful)、寵物(pet)、有名(having name)、不可丟棄(non-disposable)。RC和RS主要是控制提供無狀態(tài)服務(wù)的,其所控制的Pod的名字是隨機設(shè)置的,一個Pod出故障了就被丟棄掉,在另一個地方重啟一個新的Pod,名字變了、名字和啟動在哪兒都不重要,重要的只是Pod總數(shù);而PetSet是用來控制有狀態(tài)服務(wù),PetSet中的每個Pod的名字都是事先確定的,不能更改。PetSet中Pod的名字的作用,并不是《千與千尋》的人性原因,而是關(guān)聯(lián)與該Pod對應(yīng)的狀態(tài)。
對于RC和RS中的Pod,一般不掛載存儲或者掛載共享存儲,保存的是所有Pod共享的狀態(tài),Pod像牲畜一樣沒有分別(這似乎也確實意味著失去了人性特征);對于PetSet中的Pod,每個Pod掛載自己獨立的存儲,如果一個Pod出現(xiàn)故障,從其他節(jié)點啟動一個同樣名字的Pod,要掛在上原來Pod的存儲繼續(xù)以它的狀態(tài)提供服務(wù)。
適合于PetSet的業(yè)務(wù)包括數(shù)據(jù)庫服務(wù)MySQL和PostgreSQL,集群化管理服務(wù)Zookeeper、etcd等有狀態(tài)服務(wù)。PetSet的另一種典型應(yīng)用場景是作為一種比普通容器更穩(wěn)定可靠的模擬虛擬機的機制。傳統(tǒng)的虛擬機正是一種有狀態(tài)的寵物,運維人員需要不斷地維護它,容器剛開始流行時,我們用容器來模擬虛擬機使用,所有狀態(tài)都保存在容器里,而這已被證明是非常不安全、不可靠的。使用PetSet,Pod仍然可以通過漂移到不同節(jié)點提供高可用,而存儲也可以通過外掛的存儲來提供高可靠性,PetSet做的只是將確定的Pod與確定的存儲關(guān)聯(lián)起來保證狀態(tài)的連續(xù)性。PetSet還只在Alpha階段,后面的設(shè)計如何演變,我們還要繼續(xù)觀察。
聯(lián)合集群服務(wù)(Federation)
K8s在1.3版本里發(fā)布了beta版的Federation功能。在云計算環(huán)境中,服務(wù)的作用距離范圍從近到遠(yuǎn)一般可以有:同主機(Host,Node)、跨主機同可用區(qū)(Available Zone)、跨可用區(qū)同地區(qū)(Region)、跨地區(qū)同服務(wù)商(Cloud Service Provider)、跨云平臺。K8s的設(shè)計定位是單一集群在同一個地域內(nèi),因為同一個地區(qū)的網(wǎng)絡(luò)性能才能滿足K8s的調(diào)度和計算存儲連接要求。而聯(lián)合集群服務(wù)就是為提供跨Region跨服務(wù)商K8s集群服務(wù)而設(shè)計的。
每個K8s Federation有自己的分布式存儲、API Server和Controller Manager。用戶可以通過Federation的API Server注冊該Federation的成員K8s Cluster。當(dāng)用戶通過Federation的API Server創(chuàng)建、更改API對象時,Federation API Server會在自己所有注冊的子K8s Cluster都創(chuàng)建一份對應(yīng)的API對象。在提供業(yè)務(wù)請求服務(wù)時,K8s Federation會先在自己的各個子Cluster之間做負(fù)載均衡,而對于發(fā)送到某個具體K8s Cluster的業(yè)務(wù)請求,會依照這個K8s Cluster獨立提供服務(wù)時一樣的調(diào)度模式去做K8s Cluster內(nèi)部的負(fù)載均衡。而Cluster之間的負(fù)載均衡是通過域名服務(wù)的負(fù)載均衡來實現(xiàn)的。
所有的設(shè)計都盡量不影響K8s Cluster現(xiàn)有的工作機制,這樣對于每個子K8s集群來說,并不需要更外層的有一個K8s Federation,也就是意味著所有現(xiàn)有的K8s代碼和機制不需要因為Federation功能有任何變化。
存儲卷(Volumn)
K8s集群中的存儲卷跟Docker的存儲卷有些類似,只不過Docker的存儲卷作用范圍為一個容器,而K8s的存儲卷的生命周期和作用范圍是一個Pod。每個Pod中聲明的存儲卷由Pod中的所有容器共享。K8s支持非常多的存儲卷類型,特別的,支持多種公有云平臺的存儲,包括AWS,Google和Azure云;支持多種分布式存儲包括GlusterFS和Ceph;也支持較容易使用的主機本地目錄hostPath和NFS。K8s還支持使用Persistent Volumn Claim即PVC這種邏輯存儲,使用這種存儲,使得存儲的使用者可以忽略后臺的實際存儲技術(shù)(例如AWS,Google或GlusterFS和Ceph),而將有關(guān)存儲實際技術(shù)的配置交給存儲管理員通過Persistent Volumn來配置。
持久存儲卷(Persistent Volumn,PV)和持久存儲卷聲明(Persistent Volumn Claim,PVC)
PV和PVC使得K8s集群具備了存儲的邏輯抽象能力,使得在配置Pod的邏輯里可以忽略對實際后臺存儲技術(shù)的配置,而把這項配置的工作交給PV的配置者,即集群的管理者。存儲的PV和PVC的這種關(guān)系,跟計算的Node和Pod的關(guān)系是非常類似的;PV和Node是資源的提供者,根據(jù)集群的基礎(chǔ)設(shè)施變化而變化,由K8s集群管理員配置;而PVC和Pod是資源的使用者,根據(jù)業(yè)務(wù)服務(wù)的需求變化而變化,有K8s集群的使用者即服務(wù)的管理員來配置。
節(jié)點(Node)
K8s集群中的計算能力由Node提供,最初Node稱為服務(wù)節(jié)點Minion,后來改名為Node。K8s集群中的Node也就等同于Mesos集群中的Slave節(jié)點,是所有Pod運行所在的工作主機,可以是物理機也可以是虛擬機。不論是物理機還是虛擬機,工作主機的統(tǒng)一特征是上面要運行kubelet管理節(jié)點上運行的容器。
K8s集群中與安全相關(guān)的技術(shù)概念
秘盒對象(Secret)
Secret是用來保存和傳遞密碼、密鑰、認(rèn)證憑證這些敏感信息的對象。使用Secret的好處是可以避免把敏感信息明文寫在配置文件里。在K8s集群中配置和使用服務(wù)不可避免的要用到各種敏感信息實現(xiàn)登錄、認(rèn)證等功能,例如訪問AWS存儲的用戶名密碼。為了避免將類似的敏感信息明文寫在所有需要使用的配置文件中,可以將這些信息存入一個Secret對象,而在配置文件中通過Secret對象引用這些敏感信息。這種方式的好處包括:意圖明確,避免重復(fù),減少暴漏機會。
用戶帳戶(User Account)和服務(wù)帳戶(Service Account)
顧名思義,用戶帳戶為人提供賬戶標(biāo)識,而服務(wù)賬戶為計算機進程和K8s集群中運行的Pod提供賬戶標(biāo)識。用戶帳戶和服務(wù)帳戶的一個區(qū)別是作用范圍;用戶帳戶對應(yīng)的是人的身份,人的身份與服務(wù)的namespace無關(guān),所以用戶賬戶是跨namespace的;而服務(wù)帳戶對應(yīng)的是一個運行中程序的身份,與特定namespace是相關(guān)的。
名字空間(Namespace)
名字空間為K8s集群提供虛擬的隔離作用,K8s集群初始有兩個名字空間,分別是默認(rèn)名字空間default和系統(tǒng)名字空間kube-system,除此以外,管理員可以可以創(chuàng)建新的名字空間滿足需要。
RBAC模式授權(quán)和ABAC模式授權(quán)
K8s在1.3版本中發(fā)布了alpha版的基于角色的訪問控制(Role-based Access Control,RBAC)的授權(quán)模式。相對于基于屬性的訪問控制(Attribute-based Access Control,ABAC),RBAC主要是引入了角色(Role)和角色綁定(RoleBinding)的抽象概念。在ABAC中,K8s集群中的訪問策略只能跟用戶直接關(guān)聯(lián);而在RBAC中,訪問策略可以跟某個角色關(guān)聯(lián),具體的用戶在跟一個或多個角色相關(guān)聯(lián)。顯然,RBAC像其他新功能一樣,每次引入新功能,都會引入新的API對象,從而引入新的概念抽象,而這一新的概念抽象一定會使集群服務(wù)管理和使用更容易擴展和重用。
Kubernetes的設(shè)計理念
Kubernetes設(shè)計理念與分布式系統(tǒng)
分析和理解K8s的設(shè)計理念對設(shè)計和實現(xiàn)分布式系統(tǒng)有兩方面的益處。一方面,可以使我們更深入地了解K8s系統(tǒng),更好地利用它管理分布式部署的云原生應(yīng)用;另一方面,K8s集群管理平臺本身也是個分布式系統(tǒng),分析和理解它可以讓我們借鑒其在分布式系統(tǒng)設(shè)計方面的經(jīng)驗。
Kubernetes系統(tǒng)API的設(shè)計原則
對于云計算系統(tǒng),系統(tǒng)API實際上處于系統(tǒng)設(shè)計的統(tǒng)領(lǐng)地位,正如本文前面所說,K8s集群系統(tǒng)每支持一項新功能,引入一項新技術(shù),一定會新引入對應(yīng)的API對象,支持對該功能的管理操作,理解掌握的API,就好比抓住了K8s系統(tǒng)的牛鼻子。K8s系統(tǒng)API的設(shè)計有以下幾條原則:
所有API應(yīng)該是聲明式的。正如前文所說,聲明式的操作,相對于命令式操作,對于重復(fù)操作的效果是穩(wěn)定的,這對于容易出現(xiàn)數(shù)據(jù)丟失或重復(fù)的分布式環(huán)境來說是很重要的。另外,聲明式操作更容易被用戶使用,可以使系統(tǒng)向用戶隱藏實現(xiàn)的細(xì)節(jié),隱藏實現(xiàn)的細(xì)節(jié)的同時,也就保留了系統(tǒng)未來持續(xù)優(yōu)化的可能性。此外,聲明式的API,同時隱含了所有的API對象都是名詞性質(zhì)的,例如Service、Volumn這些API都是名詞,這些名詞描述了用戶所期望得到的一個目標(biāo)分布式對象。
API對象是彼此互補而且可組合的。這里面實際是鼓勵A(yù)PI對象盡量實現(xiàn)面向?qū)ο笤O(shè)計時的要求,即“高內(nèi)聚,松耦合”,對業(yè)務(wù)相關(guān)的概念有一個合適的分解,提高分解出來的對象的可重用性。事實上,K8s這種分布式系統(tǒng)管理平臺,也是一種業(yè)務(wù)系統(tǒng),只不過它的業(yè)務(wù)就是調(diào)度和管理容器服務(wù)。
高層API以操作意圖為基礎(chǔ)設(shè)計。如何能夠設(shè)計好API,跟如何能用面向?qū)ο蟮姆椒ㄔO(shè)計好應(yīng)用系統(tǒng)有相通的地方,高層設(shè)計一定是從業(yè)務(wù)出發(fā),而不是過早的從技術(shù)實現(xiàn)出發(fā)。因此,針對K8s的高層API設(shè)計,一定是以K8s的業(yè)務(wù)為基礎(chǔ)出發(fā),也就是以系統(tǒng)調(diào)度管理容器的操作意圖為基礎(chǔ)設(shè)計。
低層API根據(jù)高層API的控制需要設(shè)計。設(shè)計實現(xiàn)低層API的目的,是為了被高層API使用,考慮減少冗余、提高重用性的目的,低層API的設(shè)計也要以需求為基礎(chǔ),要盡量抵抗受技術(shù)實現(xiàn)影響的誘惑。
盡量避免簡單封裝,不要有在外部API無法顯式知道的內(nèi)部隱藏的機制。簡單的封裝,實際沒有提供新的功能,反而增加了對所封裝API的依賴性。內(nèi)部隱藏的機制也是非常不利于系統(tǒng)維護的設(shè)計方式,例如PetSet和ReplicaSet,本來就是兩種Pod集合,那么K8s就用不同API對象來定義它們,而不會說只用同一個ReplicaSet,內(nèi)部通過特殊的算法再來區(qū)分這個ReplicaSet是有狀態(tài)的還是無狀態(tài)。
API操作復(fù)雜度與對象數(shù)量成正比。這一條主要是從系統(tǒng)性能角度考慮,要保證整個系統(tǒng)隨著系統(tǒng)規(guī)模的擴大,性能不會迅速變慢到無法使用,那么最低的限定就是API的操作復(fù)雜度不能超過O(N),N是對象的數(shù)量,否則系統(tǒng)就不具備水平伸縮性了。
API對象狀態(tài)不能依賴于網(wǎng)絡(luò)連接狀態(tài)。由于眾所周知,在分布式環(huán)境下,網(wǎng)絡(luò)連接斷開是經(jīng)常發(fā)生的事情,因此要保證API對象狀態(tài)能應(yīng)對網(wǎng)絡(luò)的不穩(wěn)定,API對象的狀態(tài)就不能依賴于網(wǎng)絡(luò)連接狀態(tài)。
盡量避免讓操作機制依賴于全局狀態(tài),因為在分布式系統(tǒng)中要保證全局狀態(tài)的同步是非常困難的。
Kubernetes系統(tǒng)的控制機制的設(shè)計原則
-
控制邏輯應(yīng)該只依賴于當(dāng)前狀態(tài)。這是為了保證分布式系統(tǒng)的穩(wěn)定可靠,對于經(jīng)常出現(xiàn)局部錯誤的分布式系統(tǒng),如果控制邏輯只依賴當(dāng)前狀態(tài),那么就非常容易將一個暫時出現(xiàn)故障的系統(tǒng)恢復(fù)到正常狀態(tài),因為你只要將該系統(tǒng)重置到某個穩(wěn)定狀態(tài),就可以自信的知道系統(tǒng)的所有控制邏輯會開始按照正常方式運行。
-
假設(shè)任何錯誤的可能,并做容錯處理。在一個分布式系統(tǒng)中出現(xiàn)局部和臨時錯誤是大概率事件。錯誤可能來自于物理系統(tǒng)故障,外部系統(tǒng)故障也可能來自于系統(tǒng)自身的代碼錯誤,依靠自己實現(xiàn)的代碼不會出錯來保證系統(tǒng)穩(wěn)定其實也是難以實現(xiàn)的,因此要設(shè)計對任何可能錯誤的容錯處理。
-
盡量避免復(fù)雜狀態(tài)機,控制邏輯不要依賴無法監(jiān)控的內(nèi)部狀態(tài)。因為分布式系統(tǒng)各個子系統(tǒng)都是不能嚴(yán)格通過程序內(nèi)部保持同步的,所以如果兩個子系統(tǒng)的控制邏輯如果互相有影響,那么子系統(tǒng)就一定要能互相訪問到影響控制邏輯的狀態(tài),否則,就等同于系統(tǒng)里存在不確定的控制邏輯。
-
假設(shè)任何操作都可能被任何操作對象拒絕,甚至被錯誤解析。由于分布式系統(tǒng)的復(fù)雜性以及各子系統(tǒng)的相對獨立性,不同子系統(tǒng)經(jīng)常來自不同的開發(fā)團隊,所以不能奢望任何操作被另一個子系統(tǒng)以正確的方式處理,要保證出現(xiàn)錯誤的時候,操作級別的錯誤不會影響到系統(tǒng)穩(wěn)定性。
-
每個模塊都可以在出錯后自動恢復(fù)。由于分布式系統(tǒng)中無法保證系統(tǒng)各個模塊是始終連接的,因此每個模塊要有自我修復(fù)的能力,保證不會因為連接不到其他模塊而自我崩潰。
-
每個模塊都可以在必要時優(yōu)雅地降級服務(wù)。所謂優(yōu)雅地降級服務(wù),是對系統(tǒng)魯棒性的要求,即要求在設(shè)計實現(xiàn)模塊時劃分清楚基本功能和高級功能,保證基本功能不會依賴高級功能,這樣同時就保證了不會因為高級功能出現(xiàn)故障而導(dǎo)致整個模塊崩潰。根據(jù)這種理念實現(xiàn)的系統(tǒng),也更容易快速地增加新的高級功能,以為不必?fù)?dān)心引入高級功能影響原有的基本功能。
Kubernetes系統(tǒng)核心理念總結(jié)
從K8s的系統(tǒng)架構(gòu)、技術(shù)概念和設(shè)計理念,我們可以看到K8s系統(tǒng)最核心的兩個設(shè)計理念:一個是容錯性,一個是易擴展性。容錯性實際是保證K8s系統(tǒng)穩(wěn)定性和安全性的基礎(chǔ),易擴展性是保證K8s對變更友好,可以快速迭代增加新功能的基礎(chǔ)。
按照分布式系統(tǒng)一致性算法Paxos發(fā)明人計算機科學(xué)家Leslie Lamport的理念,一個分布式系統(tǒng)有兩類特性:安全性Safety和活性Liveness。安全性保證系統(tǒng)的穩(wěn)定,保證系統(tǒng)不會崩潰,不會出現(xiàn)業(yè)務(wù)錯誤,不會做壞事,是嚴(yán)格約束的;活性使得系統(tǒng)可以提供功能,提高性能,增加易用性,讓系統(tǒng)可以在用戶“看到的時間內(nèi)”做些好事,是盡力而為的。K8s系統(tǒng)的設(shè)計理念正好與Lamport安全性與活性的理念不謀而合,也正是因為K8s在引入功能和技術(shù)的時候,非常好地劃分了安全性和活性,才可以讓K8s能有這么快版本迭代,快速引入像RBAC、Federation和PetSet這種新功能。
總結(jié)
以上是生活随笔為你收集整理的《K8s与云原生应用》之K8s的系统架构与设计理念的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Crosswalk环境搭建
- 下一篇: XMind8安装