Kubernetes(k8s)讀記(一)

                                                  Kubernetes

內容主要來源於:https://www.kubernetes.org.cn/docs

      概述:Kubernetes是一個開源的,用於管理雲平臺中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單並且高效,它提供了應用部署,規劃,更新,維護的一種機制。它的一個核心的特點就是能夠自主的管理容器來保證雲平臺中的容器按照用戶的期望狀態運行着,比如用戶想讓apache一直運行,用戶不需要關心怎麼去做,Kubernetes會自動去監控,然後去重啓,新建,總之讓apache一直提供服務。在K8s中,所有的容器均在Pod中運行,一個Pod可以承載一個或者多個相關的容器,同一個Pod中的容器會部署在同一個物理機器上並且能夠共享資源。一個Pod也可以包含0個或者多個磁盤卷組, 這些卷組將會以目錄的形式提供給一個容器,或者被所有Pod中的容器共享,對於用戶創建的每個Pod,系統會自動選擇那個健康並且有足夠容量的機器,然後創建類似容器的容器,當容器創建失敗的時候,容器會被node agent自動的重啓,這個node agent叫kubelet,但是,如果是Pod失敗它不會自動的轉移並且啓動,除非用戶定義了 replication controller。

        優點及特點:通過Kubernetes,你可以快速有效地響應用戶需求:1)快速而有預期地部署你的應用;2)極速地擴展你的應用;3)無縫對接新的應用功能;4)節省資源,優化硬件資源的使用。特點: 1)可移植: 支持公有云,私有云,混合雲,多重雲(multi-cloud);2)可擴展: 模塊化, 插件化, 可掛載, 可組合;3)自愈: 自動佈置,自動重啓,自動複製,自動擴展。

         起源Kubernetes起源於希臘語, 是“舵手”或者“領航員”的意思,是“管理者”和“控制論”的根源。 K8s是把用8代替8個字符“ubernete”而成的縮寫。一句話K8s是一個用於容器集羣的自動化部署、擴容以及運維的開源平臺。關於使用容器自然是其所具有的優勢帶來其快速發展,傳統的應用部署方式是通過操作系統的包管理器來安裝應用。但它把應用的運行,配置,庫和生存週期和機器的操作系統糾纏在一起。當然可以通過創建虛機鏡像的方式來獲得可以預期的前滾和回滾操作,然而虛擬機太重量級並且不可移植。容器方式是通過部署基於操作系統級別虛擬化的容器進行虛擬化而非通過硬件來進行虛擬化。這些容器之間相互隔離:它們有自己的文件系統,然而它們也無法看到彼此之間的進程,並且它們之間的計算資源也是有界限的。相較於虛擬機容器也更容易部署,並且因爲它們是和底層設施和機器文件系統解耦的,它們可以在雲和不同版本的操作系統間進行遷移。因此從開發、部署、資源佔用利用率、安全等方面都有其優勢。那麼就需要類似一個可以安排物理機或者虛擬機上運行的應用容器的使用工具。當然k8s不只可以做這些。爲了充分發揮它的潛能,你需要剪斷物理機虛擬機的束縛。然而一旦特定的容器不再侷限於特定的主機,主機爲中心的基礎設施便不再適用了:組管理,負載均衡,自動擴展等。你需要的是以容器爲中心的基礎設施。而這正是K8s所提供的。K8s可以滿足很多運行環境中應用的通用的需求,比如:1)進程協同,利用複合應用保證應用和容器一對一的模型。2)存儲系統掛載;3)分發密鑰;4)應用健康檢測;5)應用實例複製;6)水平自動擴展;7)命名和發現;8)負載均衡;9)滾動更新;10)資源監控;11)日誌訪問;12)自檢和調試;13)識別和認證。這些爲PaaS提供了IaaS層的便利,提供了基礎設施提供者間的可移植性。

       非NOT:但K8s不是一個傳統的,包羅一切的PaaS系統。保留用戶的選擇,這一點非常重要,還有其他不是的特點是:1)K8s不限制支持應用的種類。它不限制應用框架,或者支持的運行時語言,也不去區分 “apps” 或者“services”。 K8s致力於支持不同負載應用,包括有狀態、無狀態、數據處理類型的應用。只要這個應用可以在容器裏運行,那麼它就可以在Kubernetes上很多地運行。2)K8s不提供中間件(如message buses),數據處理框架(如Spark),數據庫(如Mysql),或者集羣存儲系統(如Ceph)。但這些應用都可以運行於K8s。3)K8s沒有一個點擊即可用的應用市場。4)K8s不部署源碼不編譯應用。持續集成的 (CI)工作流方面,不同的用戶有不同的需求和偏好,因此,我們提供分層的 CI工作流,但並不定義它應該怎麼做。5)K8s允許用戶選擇自己的日誌、監控和報警系統。6)K8s不提供可理解的應用配置語言(e.g., jsonnet). 7)K8s不提供或者任何綜合的機器配置,維護,管理或者自愈系統。

     架構:Kubernetes集羣包含有節點代理kubelet和Master組件(APIs, scheduler, etc),一切都基於分佈式的存儲系統。下面這張圖是Kubernetes的架構圖。

 

K8s節點服務分爲運行在工作節點上的服務和組成集羣級別控制板的服務。K8s節點有運行應用容器必備的服務,而這些都是受Master的控制。如下圖Master節點:與工作節點

       

        每個節點上當然都要運行Docker。Docker來負責所有具體的映像下載和容器運行。K8s主要由以下幾個核心組件組成:1)etcd保存了整個集羣的狀態,所有master的持續狀態都存在etcd的一個實例中。這可以很好地存儲配置數據。因爲有watch(觀察者)的支持,各部件協調中的改變可以很快被察覺;2)apiserver提供了資源操作的唯一入口,並提供認證、授權、訪問控制、API註冊和發現等機制;3)controller manager負責維護集羣的狀態,比如故障檢測、自動擴展、滾動更新等;4)scheduler負責資源的調度,按照預定的調度策略將Pod調度到相應的機器上;5)kubelet負責維護容器的生命週期,同時也負責Volume(CVI)和網絡(CNI)的管理;6)Container runtime負責鏡像管理以及Pod和容器的真正運行(CRI);7)kube-proxy負責爲Service提供cluster內部的服務發現和負載均衡。

       除了核心組件,還有一些推薦的Add-ons:如:1)kube-dns負責爲整個集羣提供DNS服務;2)Ingress Controller爲服務提供外網入口;2)Heapster提供資源監控;3)Dashboard提供GUI;4)Federation提供跨可用區的集羣;5)Fluentd-elasticsearch提供集羣日誌採集、存儲與查詢。 K8s還提供了控制面板,K8s控制面板可以分爲多個部分。目前它們都運行在一個master節點,然而爲了達到高可用性需要改變。不同部分一起協作提供一個統一的關於集羣的視圖。

分層結構:Kubernetes設計理念和功能其實就是一個類似Linux的分層架構,如下圖所示

 

核心層:Kubernetes最核心的功能,對外提供API構建高層的應用,對內提供插件式應用執行環境;應用層:部署(無狀態應用、有狀態應用、批處理任務、集羣應用等)和路由(服務發現、DNS解析等);管理層:系統度量(如基礎設施、容器和網絡的度量),自動化(如自動擴展、動態Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等);接口層:kubectl命令行工具、客戶端SDK以及集羣聯邦;生態系統:在接口層之上的龐大容器集羣管理調度的生態系統,可以劃分爲兩個範疇:1)K8s外部:日誌、監控、配置管理、CI、CD、Workflow、FaaS、OTS應用、ChatOps等;2)K8s內部:CRI、CNI、CVI、鏡像倉庫、Cloud Provider、集羣自身的配置和管理等。

       設計理念:對於雲計算系統,系統API實際上處於系統設計的統領地位,K8s集羣系統每支持一項新功能,引入一項新技術,一定會新引入對應的API對象,支持對該功能的管理操作。因此API設計及控制設計都應遵循一些原則。每個API對象都有3大類屬性:元數據metadata、規範spec和狀態status。元數據是用來標識API對象的,每個對象都至少有3個元數據:namespace,name和uid;除此以外還有各種各樣的標籤labels用來標識和匹配不同的對象,例如用戶可以用標籤env來標識區分不同的服務部署環境,分別用env=dev、env=testing、env=production來標識開發、測試、生產的不同服務。規範描述了用戶期望K8s集羣中的分佈式系統達到的理想狀態(Desired State),例如用戶可以通過複製控制器Replication Controller設置期望的Pod副本數爲3;status描述了系統實際當前達到的狀態(Status),例如系統當前實際的Pod副本數爲2;那麼複製控制器當前的程序邏輯就是自動啓動新的Pod,爭取達到副本數爲3。

       K8s中所有的配置都是通過API對象的spec去設置的,也就是用戶通過配置系統的理想狀態來改變系統,這是k8s重要設計理念之一,即所有的操作都是聲明式(Declarative)的而不是命令式(Imperative)的。聲明式操作在分佈式系統中的好處是穩定,不怕丟操作或運行多次,例如設置副本數爲3的操作運行多次也還是一個結果,而給副本數加1的操作就不是聲明式的,運行多次結果就錯了。最基礎微服務Pod:Pod是在K8s集羣中運行部署應用或服務的最小單元,它是可以支持多容器的。Pod的設計理念是支持多個容器在一個Pod中共享網絡地址和文件系統,可以通過進程間通信和文件共享這種簡單高效的方式組合完成服務。Pod對多容器的支持是K8s最基礎的設計理念。Pod可以看作運行在K8s集羣中的小機器人,不同類型的業務就需要不同類型的小機器人去執行。目前K8s中的業務主要可以分爲長期伺服型(long-running)、批處理型(batch)、節點後臺支撐型(node-daemon)和有狀態應用型(stateful application);分別對應的小機器人控制器爲Deployment、Job、DaemonSet和PetSet。

      複製控制器(Replication Controller,RC):RC是K8s集羣中最早的保證Pod高可用的API對象。通過監控運行中的Pod來保證集羣中運行指定數目的Pod副本。指定的數目可以是多個也可以是1個;少於指定數目,RC就會啓動運行新的Pod副本;多於指定數目,RC就會殺死多餘的Pod副本。RC是K8s較早期的技術概念,只適用於長期伺服型的業務類型,比如控制小機器人提供高可用的Web服務。

      副本集(Replica Set,RS):RS是新一代RC,提供同樣的高可用能力,區別主要在於RS後來居上,能支持更多種類的匹配模式。副本集對象一般不單獨使用,而是作爲Deployment的理想狀態參數使用。

      部署(Deployment):部署表示用戶對K8s集羣的一次更新操作。部署是一個比RS應用模式更廣的API對象,可以是創建一個新的服務,更新一個新的服務,也可以是滾動升級一個服務。滾動升級一個服務,實際是創建一個新的RS,然後逐漸將新RS中副本數增加到理想狀態,將舊RS中的副本數減小到0的複合操作;這樣一個複合操作用一個RS是不太好描述的,所以用一個更通用的Deployment來描述。以K8s的發展方向,未來對所有長期伺服型的的業務的管理,都會通過Deployment來管理。

       服務(Service):RC、RS和Deployment只是保證了支撐服務的微服務Pod的數量,但是沒有解決如何訪問這些服務的問題。一個Pod只是一個運行服務的實例,隨時可能在一個節點上停止,在另一個節點以一個新的IP啓動一個新的Pod,因此不能以確定的IP和端口號提供服務。要穩定地提供服務需要服務發現和負載均衡能力。服務發現完成的工作,是針對客戶端訪問的服務,找到對應的的後端服務實例。在K8s集羣中,客戶端需要訪問的服務就是Service對象。每個Service會對應一個集羣內部有效的虛擬IP,集羣內部通過虛擬IP訪問一個服務。在K8s集羣中微服務的負載均衡是由Kube-proxy實現的。Kube-proxy是K8s集羣內部的負載均衡器。它是一個分佈式代理服務器,在K8s的每個節點上都有一個;這一設計體現了它的伸縮性優勢,需要訪問服務的節點越多,提供負載均衡能力的Kube-proxy就越多,高可用節點也隨之增多。與之相比,我們平時在服務器端做個反向代理做負載均衡,還要進一步解決反向代理的負載均衡和高可用問題。

      任務(Job):Job是K8s用來控制批處理型任務的API對象。批處理業務與長期伺服業務的主要區別是批處理業務的運行有頭有尾,而長期伺服業務在用戶不停止的情況下永遠運行。Job管理的Pod根據用戶的設置把任務成功完成就自動退出了。成功完成的標誌根據不同的spec.completions策略而不同:單Pod型任務有一個Pod成功就標誌完成;定數成功型任務保證有N個任務全部成功;工作隊列型任務根據應用確認的全局成功而標誌成功。

       後臺支撐服務集(DaemonSet):長期伺服型和批處理型服務的核心在業務應用,可能有些節點運行多個同類業務的Pod,有些節點上又沒有這類Pod運行;而後臺支撐型服務的核心關注點在K8s集羣中的節點(物理機或虛擬機),要保證每個節點上都有一個此類Pod運行。節點可能是所有集羣節點也可能是通過nodeSelector選定的一些特定節點。典型的後臺支撐型服務包括,存儲,日誌和監控等在每個節點上支持K8s集羣運行的服務。

    有狀態服務集(PetSet):K8s在1.3版本里發佈了Alpha版的PetSet功能。在雲原生應用的體系裏,有下面兩組近義詞;第一組是無狀態(stateless)、牲畜(cattle)、無名(nameless)、可丟棄(disposable);第二組是有狀態(stateful)、寵物(pet)、有名(having name)、不可丟棄(non-disposable)。RC和RS主要是控制提供無狀態服務的,其所控制的Pod的名字是隨機設置的,一個Pod出故障了就被丟棄掉,在另一個地方重啓一個新的Pod,名字變了、名字和啓動在哪兒都不重要,重要的只是Pod總數;而PetSet是用來控制有狀態服務,PetSet中的每個Pod的名字都是事先確定的,不能更改。對於RC和RS中的Pod,一般不掛載存儲或者掛載共享存儲,保存的是所有Pod共享的狀態,Pod像牲畜一樣沒有分別(這似乎也確實意味着失去了人性特徵);對於PetSet中的Pod,每個Pod掛載自己獨立的存儲,如果一個Pod出現故障,從其他節點啓動一個同樣名字的Pod,要掛載上原來Pod的存儲繼續以它的狀態提供服務。適合於PetSet的業務包括數據庫服務MySQL和PostgreSQL,集羣化管理服務Zookeeper、etcd等有狀態服務。PetSet的另一種典型應用場景是作爲一種比普通容器更穩定可靠的模擬虛擬機的機制。傳統的虛擬機正是一種有狀態的寵物,運維人員需要不斷地維護它,容器剛開始流行時,我們用容器來模擬虛擬機使用,所有狀態都保存在容器裏,而這已被證明是非常不安全、不可靠的。使用PetSet,Pod仍然可以通過漂移到不同節點提供高可用,而存儲也可以通過外掛的存儲來提供高可靠性,PetSet做的只是將確定的Pod與確定的存儲關聯起來保證狀態的連續性。PetSet還只在Alpha階段,後面的設計如何演變,我們還要繼續觀察。

      集羣聯邦(Federation):K8s在1.3版本里發佈了beta版的Federation功能。在雲計算環境中,服務的作用距離範圍從近到遠一般可以有:同主機(Host,Node)、跨主機同可用區(Available Zone)、跨可用區同地區(Region)、跨地區同服務商(Cloud Service Provider)、跨雲平臺。K8s的設計定位是單一集羣在同一個地域內,因爲同一個地區的網絡性能才能滿足K8s的調度和計算存儲連接要求。而聯合集羣服務就是爲提供跨Region跨服務商K8s集羣服務而設計的。每個K8s Federation有自己的分佈式存儲、API Server和Controller Manager。用戶可以通過Federation的API Server註冊該Federation的成員K8s Cluster。當用戶通過Federation的API Server創建、更改API對象時,Federation API Server會在自己所有註冊的子K8s Cluster都創建一份對應的API對象。在提供業務請求服務時,K8s Federation會先在自己的各個子Cluster之間做負載均衡,而對於發送到某個具體K8s Cluster的業務請求,會依照這個K8s Cluster獨立提供服務時一樣的調度模式去做K8s Cluster內部的負載均衡。而Cluster之間的負載均衡是通過域名服務的負載均衡來實現的。所有的設計都儘量不影響K8s Cluster現有的工作機制,這樣對於每個子K8s集羣來說,並不需要更外層的有一個K8s Federation,也就是意味着所有現有的K8s代碼和機制不需要因爲Federation功能有任何變化。

      存儲卷(Volume):K8s集羣中的存儲卷跟Docker的存儲卷有些類似,只不過Docker的存儲卷作用範圍爲一個容器,而K8s的存儲卷的生命週期和作用範圍是一個Pod。每個Pod中聲明的存儲卷由Pod中的所有容器共享。K8s支持非常多的存儲卷類型,特別的,支持多種公有云平臺的存儲,包括AWS,Google和Azure雲;支持多種分佈式存儲包括GlusterFS和Ceph;也支持較容易使用的主機本地目錄hostPath和NFS。K8s還支持使用Persistent Volume Claim即PVC這種邏輯存儲,使用這種存儲,使得存儲的使用者可以忽略後臺的實際存儲技術(例如AWS,Google或GlusterFS和Ceph),而將有關存儲實際技術的配置交給存儲管理員通過Persistent Volume來配置。

持久存儲卷(Persistent Volume,PV)和持久存儲卷聲明(Persistent Volume Claim,PVC):PV和PVC使得K8s集羣具備了存儲的邏輯抽象能力,使得在配置Pod的邏輯裏可以忽略對實際後臺存儲技術的配置,而把這項配置的工作交給PV的配置者,即集羣的管理者。存儲的PV和PVC的這種關係,跟計算的Node和Pod的關係是非常類似的;PV和Node是資源的提供者,根據集羣的基礎設施變化而變化,由K8s集羣管理員配置;而PVC和Pod是資源的使用者,根據業務服務的需求變化而變化,有K8s集羣的使用者即服務的管理員來配置。

    節點(Node):K8s集羣中的計算能力由Node提供,最初Node稱爲服務節點Minion,後來改名爲Node。K8s集羣中的Node也就等同於Mesos集羣中的Slave節點,是所有Pod運行所在的工作主機,可以是物理機也可以是虛擬機。不論是物理機還是虛擬機,工作主機的統一特徵是上面要運行kubelet管理節點上運行的容器。

      密鑰對象(Secret):Secret是用來保存和傳遞密碼、密鑰、認證憑證這些敏感信息的對象。使用Secret的好處是可以避免把敏感信息明文寫在配置文件裏。在K8s集羣中配置和使用服務不可避免的要用到各種敏感信息實現登錄、認證等功能,例如訪問AWS存儲的用戶名密碼。爲了避免將類似的敏感信息明文寫在所有需要使用的配置文件中,可以將這些信息存入一個Secret對象,而在配置文件中通過Secret對象引用這些敏感信息。這種方式的好處包括:意圖明確,避免重複,減少暴漏機會。

       用戶帳戶(User Account)和服務帳戶(Service Account):顧名思義,用戶帳戶爲人提供賬戶標識,而服務賬戶爲計算機進程和K8s集羣中運行的Pod提供賬戶標識。用戶帳戶和服務帳戶的一個區別是作用範圍;用戶帳戶對應的是人的身份,人的身份與服務的namespace無關,所以用戶賬戶是跨namespace的;而服務帳戶對應的是一個運行中程序的身份,與特定namespace是相關的。

      名字空間(Namespace):名字空間爲K8s集羣提供虛擬的隔離作用,K8s集羣初始有兩個名字空間,分別是默認名字空間default和系統名字空間kube-system,除此以外,管理員可以可以創建新的名字空間滿足需要。

      RBAC訪問授權:K8s在1.3版本中發佈了alpha版的基於角色的訪問控制(Role-based Access Control,RBAC)的授權模式。相對於基於屬性的訪問控制(Attribute-based Access Control,ABAC),RBAC主要是引入了角色(Role)和角色綁定(RoleBinding)的抽象概念。在ABAC中,K8s集羣中的訪問策略只能跟用戶直接關聯;而在RBAC中,訪問策略可以跟某個角色關聯,具體的用戶在跟一個或多個角色相關聯。顯然,RBAC像其他新功能一樣,每次引入新功能,都會引入新的API對象,從而引入新的概念抽象,而這一新的概念抽象一定會使集羣服務管理和使用更容易擴展和重用。

      總結:從K8s的系統架構、技術概念和設計理念,我們可以看到K8s系統最核心的兩個設計理念:一個是容錯性,一個是易擴展性。容錯性實際是保證K8s系統穩定性和安全性的基礎,易擴展性是保證K8s對變更友好,可以快速迭代增加新功能的基礎。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章