<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # Kubernetes的設計理念 這一章將介紹 Kubernetes 的設計理念及基本概念。 ### Kubernetes設計理念與分布式系統 分析和理解Kubernetes的設計理念可以使我們更深入地了解Kubernetes系統,更好地利用它管理分布式部署的云原生應用,另一方面也可以讓我們借鑒其在分布式系統設計方面的經驗。 ### 分層架構 Kubernetes設計理念和功能其實就是一個類似Linux的分層架構,如下圖所示 ![Kubernetes 分層架構示意圖](https://ws4.sinaimg.cn/large/006tNc79ly1fzniqvmi51j31gq0s0q5u.jpg) * 核心層:Kubernetes最核心的功能,對外提供API構建高層的應用,對內提供插件式應用執行環境 * 應用層:部署(無狀態應用、有狀態應用、批處理任務、集群應用等)和路由(服務發現、DNS解析等) * 管理層:系統度量(如基礎設施、容器和網絡的度量),自動化(如自動擴展、動態Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等) * 接口層:kubectl命令行工具、客戶端SDK以及集群聯邦 * 生態系統:在接口層之上的龐大容器集群管理調度的生態系統,可以劃分為兩個范疇 * Kubernetes外部:日志、監控、配置管理、CI、CD、Workflow、FaaS、OTS應用、ChatOps等 * Kubernetes內部:CRI、CNI、CVI、鏡像倉庫、Cloud Provider、集群自身的配置和管理等 ### API設計原則 對于云計算系統,系統API實際上處于系統設計的統領地位,正如本文前面所說,Kubernetes集群系統每支持一項新功能,引入一項新技術,一定會新引入對應的API對象,支持對該功能的管理操作,理解掌握的API,就好比抓住了Kubernetes系統的牛鼻子。Kubernetes系統API的設計有以下幾條原則: 1. **所有API應該是聲明式的**。正如前文所說,聲明式的操作,相對于命令式操作,對于重復操作的效果是穩定的,這對于容易出現數據丟失或重復的分布式環境來說是很重要的。另外,聲明式操作更容易被用戶使用,可以使系統向用戶隱藏實現的細節,隱藏實現的細節的同時,也就保留了系統未來持續優化的可能性。此外,聲明式的API,同時隱含了所有的API對象都是名詞性質的,例如Service、Volume這些API都是名詞,這些名詞描述了用戶所期望得到的一個目標分布式對象。 2. **API對象是彼此互補而且可組合的**。這里面實際是鼓勵API對象盡量實現面向對象設計時的要求,即“高內聚,松耦合”,對業務相關的概念有一個合適的分解,提高分解出來的對象的可重用性。事實上,Kubernetes這種分布式系統管理平臺,也是一種業務系統,只不過它的業務就是調度和管理容器服務。 3. **高層API以操作意圖為基礎設計**。如何能夠設計好API,跟如何能用面向對象的方法設計好應用系統有相通的地方,高層設計一定是從業務出發,而不是過早的從技術實現出發。因此,針對Kubernetes的高層API設計,一定是以Kubernetes的業務為基礎出發,也就是以系統調度管理容器的操作意圖為基礎設計。 4. **低層API根據高層API的控制需要設計**。設計實現低層API的目的,是為了被高層API使用,考慮減少冗余、提高重用性的目的,低層API的設計也要以需求為基礎,要盡量抵抗受技術實現影響的誘惑。 5. **盡量避免簡單封裝,不要有在外部API無法顯式知道的內部隱藏的機制**。簡單的封裝,實際沒有提供新的功能,反而增加了對所封裝API的依賴性。內部隱藏的機制也是非常不利于系統維護的設計方式,例如StatefulSet和ReplicaSet,本來就是兩種Pod集合,那么Kubernetes就用不同API對象來定義它們,而不會說只用同一個ReplicaSet,內部通過特殊的算法再來區分這個ReplicaSet是有狀態的還是無狀態。 6. **API操作復雜度與對象數量成正比**。這一條主要是從系統性能角度考慮,要保證整個系統隨著系統規模的擴大,性能不會迅速變慢到無法使用,那么最低的限定就是API的操作復雜度不能超過O\(N\),N是對象的數量,否則系統就不具備水平伸縮性了。 7. **API對象狀態不能依賴于網絡連接狀態**。由于眾所周知,在分布式環境下,網絡連接斷開是經常發生的事情,因此要保證API對象狀態能應對網絡的不穩定,API對象的狀態就不能依賴于網絡連接狀態。 8. **盡量避免讓操作機制依賴于全局狀態,因為在分布式系統中要保證全局狀態的同步是非常困難的**。 ### 控制機制設計原則 * **控制邏輯應該只依賴于當前狀態**。這是為了保證分布式系統的穩定可靠,對于經常出現局部錯誤的分布式系統,如果控制邏輯只依賴當前狀態,那么就非常容易將一個暫時出現故障的系統恢復到正常狀態,因為你只要將該系統重置到某個穩定狀態,就可以自信的知道系統的所有控制邏輯會開始按照正常方式運行。 * **假設任何錯誤的可能,并做容錯處理**。在一個分布式系統中出現局部和臨時錯誤是大概率事件。錯誤可能來自于物理系統故障,外部系統故障也可能來自于系統自身的代碼錯誤,依靠自己實現的代碼不會出錯來保證系統穩定其實也是難以實現的,因此要設計對任何可能錯誤的容錯處理。 * **盡量避免復雜狀態機,控制邏輯不要依賴無法監控的內部狀態**。因為分布式系統各個子系統都是不能嚴格通過程序內部保持同步的,所以如果兩個子系統的控制邏輯如果互相有影響,那么子系統就一定要能互相訪問到影響控制邏輯的狀態,否則,就等同于系統里存在不確定的控制邏輯。 * **假設任何操作都可能被任何操作對象拒絕,甚至被錯誤解析**。由于分布式系統的復雜性以及各子系統的相對獨立性,不同子系統經常來自不同的開發團隊,所以不能奢望任何操作被另一個子系統以正確的方式處理,要保證出現錯誤的時候,操作級別的錯誤不會影響到系統穩定性。 * **每個模塊都可以在出錯后自動恢復**。由于分布式系統中無法保證系統各個模塊是始終連接的,因此每個模塊要有自我修復的能力,保證不會因為連接不到其他模塊而自我崩潰。 * **每個模塊都可以在必要時優雅地降級服務**。所謂優雅地降級服務,是對系統魯棒性的要求,即要求在設計實現模塊時劃分清楚基本功能和高級功能,保證基本功能不會依賴高級功能,這樣同時就保證了不會因為高級功能出現故障而導致整個模塊崩潰。根據這種理念實現的系統,也更容易快速地增加新的高級功能,因為不必擔心引入高級功能影響原有的基本功能。 ## Kubernetes的核心技術概念和API對象 API對象是Kubernetes集群中的管理操作單元。Kubernetes集群系統每支持一項新功能,引入一項新技術,一定會新引入對應的API對象,支持對該功能的管理操作。例如副本集Replica Set對應的API對象是RS。 每個API對象都有3大類屬性:元數據metadata、規范spec和狀態status。元數據是用來標識API對象的,每個對象都至少有3個元數據:namespace,name和uid;除此以外還有各種各樣的標簽labels用來標識和匹配不同的對象,例如用戶可以用標簽env來標識區分不同的服務部署環境,分別用env=dev、env=testing、env=production來標識開發、測試、生產的不同服務。規范描述了用戶期望Kubernetes集群中的分布式系統達到的理想狀態(Desired State),例如用戶可以通過復制控制器Replication Controller設置期望的Pod副本數為3;status描述了系統實際當前達到的狀態(Status),例如系統當前實際的Pod副本數為2;那么復制控制器當前的程序邏輯就是自動啟動新的Pod,爭取達到副本數為3。 Kubernetes中所有的配置都是通過API對象的spec去設置的,也就是用戶通過配置系統的理想狀態來改變系統,這是Kubernetes重要設計理念之一,即所有的操作都是聲明式(Declarative)的而不是命令式(Imperative)的。聲明式操作在分布式系統中的好處是穩定,不怕丟操作或運行多次,例如設置副本數為3的操作運行多次也還是一個結果,而給副本數加1的操作就不是聲明式的,運行多次結果就錯了。 ### Pod Kubernetes有很多技術概念,同時對應很多API對象,最重要的也是最基礎的是Pod。Pod是在Kubernetes集群中運行部署應用或服務的最小單元,它是可以支持多容器的。Pod的設計理念是支持多個容器在一個Pod中共享網絡地址和文件系統,可以通過進程間通信和文件共享這種簡單高效的方式組合完成服務。Pod對多容器的支持是K8最基礎的設計理念。比如你運行一個操作系統發行版的軟件倉庫,一個Nginx容器用來發布軟件,另一個容器專門用來從源倉庫做同步,這兩個容器的鏡像不太可能是一個團隊開發的,但是他們一塊兒工作才能提供一個微服務;這種情況下,不同的團隊各自開發構建自己的容器鏡像,在部署的時候組合成一個微服務對外提供服務。 Pod是Kubernetes集群中所有業務類型的基礎,可以看作運行在Kubernetes集群中的小機器人,不同類型的業務就需要不同類型的小機器人去執行。目前Kubernetes中的業務主要可以分為長期伺服型(long-running)、批處理型(batch)、節點后臺支撐型(node-daemon)和有狀態應用型(stateful application);分別對應的小機器人控制器為Deployment、Job、DaemonSet和StatefulSet,本文后面會一一介紹。 ### 副本控制器(Replication Controller,RC) RC是Kubernetes集群中最早的保證Pod高可用的API對象。通過監控運行中的Pod來保證集群中運行指定數目的Pod副本。指定的數目可以是多個也可以是1個;少于指定數目,RC就會啟動運行新的Pod副本;多于指定數目,RC就會殺死多余的Pod副本。即使在指定數目為1的情況下,通過RC運行Pod也比直接運行Pod更明智,因為RC也可以發揮它高可用的能力,保證永遠有1個Pod在運行。RC是Kubernetes較早期的技術概念,只適用于長期伺服型的業務類型,比如控制小機器人提供高可用的Web服務。 ### 副本集(Replica Set,RS) RS是新一代RC,提供同樣的高可用能力,區別主要在于RS后來居上,能支持更多種類的匹配模式。副本集對象一般不單獨使用,而是作為Deployment的理想狀態參數使用。 ### 部署(Deployment) 部署表示用戶對Kubernetes集群的一次更新操作。部署是一個比RS應用模式更廣的API對象,可以是創建一個新的服務,更新一個新的服務,也可以是滾動升級一個服務。滾動升級一個服務,實際是創建一個新的RS,然后逐漸將新RS中副本數增加到理想狀態,將舊RS中的副本數減小到0的復合操作;這樣一個復合操作用一個RS是不太好描述的,所以用一個更通用的Deployment來描述。以Kubernetes的發展方向,未來對所有長期伺服型的的業務的管理,都會通過Deployment來管理。 ### 服務(Service) RC、RS和Deployment只是保證了支撐服務的微服務Pod的數量,但是沒有解決如何訪問這些服務的問題。一個Pod只是一個運行服務的實例,隨時可能在一個節點上停止,在另一個節點以一個新的IP啟動一個新的Pod,因此不能以確定的IP和端口號提供服務。要穩定地提供服務需要服務發現和負載均衡能力。服務發現完成的工作,是針對客戶端訪問的服務,找到對應的的后端服務實例。在K8集群中,客戶端需要訪問的服務就是Service對象。每個Service會對應一個集群內部有效的虛擬IP,集群內部通過虛擬IP訪問一個服務。在Kubernetes集群中微服務的負載均衡是由Kube-proxy實現的。Kube-proxy是Kubernetes集群內部的負載均衡器。它是一個分布式代理服務器,在Kubernetes的每個節點上都有一個;這一設計體現了它的伸縮性優勢,需要訪問服務的節點越多,提供負載均衡能力的Kube-proxy就越多,高可用節點也隨之增多。與之相比,我們平時在服務器端做個反向代理做負載均衡,還要進一步解決反向代理的負載均衡和高可用問題。 ### 任務(Job) Job是Kubernetes用來控制批處理型任務的API對象。批處理業務與長期伺服業務的主要區別是批處理業務的運行有頭有尾,而長期伺服業務在用戶不停止的情況下永遠運行。Job管理的Pod根據用戶的設置把任務成功完成就自動退出了。成功完成的標志根據不同的spec.completions策略而不同:單Pod型任務有一個Pod成功就標志完成;定數成功型任務保證有N個任務全部成功;工作隊列型任務根據應用確認的全局成功而標志成功。 ### 后臺支撐服務集(DaemonSet) 長期伺服型和批處理型服務的核心在業務應用,可能有些節點運行多個同類業務的Pod,有些節點上又沒有這類Pod運行;而后臺支撐型服務的核心關注點在Kubernetes集群中的節點(物理機或虛擬機),要保證每個節點上都有一個此類Pod運行。節點可能是所有集群節點也可能是通過nodeSelector選定的一些特定節點。典型的后臺支撐型服務包括,存儲,日志和監控等在每個節點上支持Kubernetes集群運行的服務。 ### 有狀態服務集(StatefulSet) Kubernetes在1.3版本里發布了Alpha版的PetSet功能,在1.5版本里將PetSet功能升級到了Beta版本,并重新命名為StatefulSet,最終在1.9版本里成為正式GA版本。在云原生應用的體系里,有下面兩組近義詞;第一組是無狀態(stateless)、牲畜(cattle)、無名(nameless)、可丟棄(disposable);第二組是有狀態(stateful)、寵物(pet)、有名(having name)、不可丟棄(non-disposable)。RC和RS主要是控制提供無狀態服務的,其所控制的Pod的名字是隨機設置的,一個Pod出故障了就被丟棄掉,在另一個地方重啟一個新的Pod,名字變了。名字和啟動在哪兒都不重要,重要的只是Pod總數;而StatefulSet是用來控制有狀態服務,StatefulSet中的每個Pod的名字都是事先確定的,不能更改。StatefulSet中Pod的名字的作用,并不是《千與千尋》的人性原因,而是關聯與該Pod對應的狀態。 對于RC和RS中的Pod,一般不掛載存儲或者掛載共享存儲,保存的是所有Pod共享的狀態,Pod像牲畜一樣沒有分別(這似乎也確實意味著失去了人性特征);對于StatefulSet中的Pod,每個Pod掛載自己獨立的存儲,如果一個Pod出現故障,從其他節點啟動一個同樣名字的Pod,要掛載上原來Pod的存儲繼續以它的狀態提供服務。 適合于StatefulSet的業務包括數據庫服務MySQL和PostgreSQL,集群化管理服務ZooKeeper、etcd等有狀態服務。StatefulSet的另一種典型應用場景是作為一種比普通容器更穩定可靠的模擬虛擬機的機制。傳統的虛擬機正是一種有狀態的寵物,運維人員需要不斷地維護它,容器剛開始流行時,我們用容器來模擬虛擬機使用,所有狀態都保存在容器里,而這已被證明是非常不安全、不可靠的。使用StatefulSet,Pod仍然可以通過漂移到不同節點提供高可用,而存儲也可以通過外掛的存儲來提供高可靠性,StatefulSet做的只是將確定的Pod與確定的存儲關聯起來保證狀態的連續性。 ### 集群聯邦(Federation) Kubernetes在1.3版本里發布了beta版的Federation功能。在云計算環境中,服務的作用距離范圍從近到遠一般可以有:同主機(Host,Node)、跨主機同可用區(Available Zone)、跨可用區同地區(Region)、跨地區同服務商(Cloud Service Provider)、跨云平臺。Kubernetes的設計定位是單一集群在同一個地域內,因為同一個地區的網絡性能才能滿足Kubernetes的調度和計算存儲連接要求。而聯合集群服務就是為提供跨Region跨服務商Kubernetes集群服務而設計的。 每個Kubernetes Federation有自己的分布式存儲、API Server和Controller Manager。用戶可以通過Federation的API Server注冊該Federation的成員Kubernetes Cluster。當用戶通過Federation的API Server創建、更改API對象時,Federation API Server會在自己所有注冊的子Kubernetes Cluster都創建一份對應的API對象。在提供業務請求服務時,Kubernetes Federation會先在自己的各個子Cluster之間做負載均衡,而對于發送到某個具體Kubernetes Cluster的業務請求,會依照這個Kubernetes Cluster獨立提供服務時一樣的調度模式去做Kubernetes Cluster內部的負載均衡。而Cluster之間的負載均衡是通過域名服務的負載均衡來實現的。 Federation V1的設計是盡量不影響Kubernetes Cluster現有的工作機制,這樣對于每個子Kubernetes集群來說,并不需要更外層的有一個Kubernetes Federation,也就是意味著所有現有的Kubernetes代碼和機制不需要因為Federation功能有任何變化。 目前正在開發的Federation V2,在保留現有Kubernetes API的同時,會開發新的Federation專用的API接口,詳細內容可以在[這里](https://github.com/kubernetes/community/tree/master/sig-multicluster)找到。 ### 存儲卷(Volume) Kubernetes集群中的存儲卷跟Docker的存儲卷有些類似,只不過Docker的存儲卷作用范圍為一個容器,而Kubernetes的存儲卷的生命周期和作用范圍是一個Pod。每個Pod中聲明的存儲卷由Pod中的所有容器共享。Kubernetes支持非常多的存儲卷類型,特別的,支持多種公有云平臺的存儲,包括AWS,Google和Azure云;支持多種分布式存儲包括GlusterFS和Ceph;也支持較容易使用的主機本地目錄emptyDir, hostPath和NFS。Kubernetes還支持使用Persistent Volume Claim即PVC這種邏輯存儲,使用這種存儲,使得存儲的使用者可以忽略后臺的實際存儲技術(例如AWS,Google或GlusterFS和Ceph),而將有關存儲實際技術的配置交給存儲管理員通過Persistent Volume來配置。 ### 持久存儲卷(Persistent Volume,PV)和持久存儲卷聲明(Persistent Volume Claim,PVC) PV和PVC使得Kubernetes集群具備了存儲的邏輯抽象能力,使得在配置Pod的邏輯里可以忽略對實際后臺存儲技術的配置,而把這項配置的工作交給PV的配置者,即集群的管理者。存儲的PV和PVC的這種關系,跟計算的Node和Pod的關系是非常類似的;PV和Node是資源的提供者,根據集群的基礎設施變化而變化,由Kubernetes集群管理員配置;而PVC和Pod是資源的使用者,根據業務服務的需求變化而變化,有Kubernetes集群的使用者即服務的管理員來配置。 ### 節點(Node) Kubernetes集群中的計算能力由Node提供,最初Node稱為服務節點Minion,后來改名為Node。Kubernetes集群中的Node也就等同于Mesos集群中的Slave節點,是所有Pod運行所在的工作主機,可以是物理機也可以是虛擬機。不論是物理機還是虛擬機,工作主機的統一特征是上面要運行kubelet管理節點上運行的容器。 ### 密鑰對象(Secret) Secret是用來保存和傳遞密碼、密鑰、認證憑證這些敏感信息的對象。使用Secret的好處是可以避免把敏感信息明文寫在配置文件里。在Kubernetes集群中配置和使用服務不可避免的要用到各種敏感信息實現登錄、認證等功能,例如訪問AWS存儲的用戶名密碼。為了避免將類似的敏感信息明文寫在所有需要使用的配置文件中,可以將這些信息存入一個Secret對象,而在配置文件中通過Secret對象引用這些敏感信息。這種方式的好處包括:意圖明確,避免重復,減少暴漏機會。 ### 用戶帳戶(User Account)和服務帳戶(Service Account) 顧名思義,用戶帳戶為人提供賬戶標識,而服務賬戶為計算機進程和Kubernetes集群中運行的Pod提供賬戶標識。用戶帳戶和服務帳戶的一個區別是作用范圍;用戶帳戶對應的是人的身份,人的身份與服務的namespace無關,所以用戶賬戶是跨namespace的;而服務帳戶對應的是一個運行中程序的身份,與特定namespace是相關的。 ### 命名空間(Namespace) 命名空間為Kubernetes集群提供虛擬的隔離作用,Kubernetes集群初始有兩個命名空間,分別是默認命名空間default和系統命名空間kube-system,除此以外,管理員可以可以創建新的命名空間滿足需要。 ### RBAC訪問授權 Kubernetes在1.3版本中發布了alpha版的基于角色的訪問控制(Role-based Access Control,RBAC)的授權模式。相對于基于屬性的訪問控制(Attribute-based Access Control,ABAC),RBAC主要是引入了角色(Role)和角色綁定(RoleBinding)的抽象概念。在ABAC中,Kubernetes集群中的訪問策略只能跟用戶直接關聯;而在RBAC中,訪問策略可以跟某個角色關聯,具體的用戶在跟一個或多個角色相關聯。顯然,RBAC像其他新功能一樣,每次引入新功能,都會引入新的API對象,從而引入新的概念抽象,而這一新的概念抽象一定會使集群服務管理和使用更容易擴展和重用。 ## 總結 從Kubernetes的系統架構、技術概念和設計理念,我們可以看到Kubernetes系統最核心的兩個設計理念:一個是**容錯性**,一個是**易擴展性**。容錯性實際是保證Kubernetes系統穩定性和安全性的基礎,易擴展性是保證Kubernetes對變更友好,可以快速迭代增加新功能的基礎。 按照分布式系統一致性算法Paxos發明人計算機科學家[Leslie Lamport](http://research.microsoft.com/users/lamport/pubs/pubs.html)的理念,一個分布式系統有兩類特性:安全性Safety和活性Liveness。安全性保證系統的穩定,保證系統不會崩潰,不會出現業務錯誤,不會做壞事,是嚴格約束的;活性使得系統可以提供功能,提高性能,增加易用性,讓系統可以在用戶“看到的時間內”做些好事,是盡力而為的。Kubernetes系統的設計理念正好與Lamport安全性與活性的理念不謀而合,也正是因為Kubernetes在引入功能和技術的時候,非常好地劃分了安全性和活性,才可以讓Kubernetes能有這么快版本迭代,快速引入像RBAC、Federation和PetSet這種新功能。 原文地址:[《Kubernetes與云原生應用》系列之Kubernetes的系統架構與設計理念](http://www.infoq.com/cn/articles/kubernetes-and-cloud-native-applications-part01)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看