Kubernetes學習之路(二十)之K8S組件運行原理詳解總結

1、看圖說K8S

先從一張大圖來觀看一下K8S是如何運做的,再具體去細化K8S的概念、組件以及網絡模型。node

從上圖,咱們能夠看到K8S組件和邏輯及其複雜,可是這並不可怕,咱們從宏觀上先了解K8S是怎麼用的,再進行庖丁解牛。從上圖咱們能夠看出:linux

  • Kubernetes集羣主要由Master和Node兩類節點組成
  • Master的組件包括:apiserver、controller-manager、scheduler和etcd等幾個組件,其中apiserver是整個集羣的網關。
  • Node主要由kubelet、kube-proxy、docker引擎等組件組成。kubelet是K8S集羣的工做與節點上的代理組件。
  • 一個完整的K8S集羣,還包括CoreDNS、Prometheus(或HeapSter)、Dashboard、Ingress Controller等幾個附加組件。其中cAdivsor組件做用於各個節點(master和node節點)之上,用於收集及收集容器及節點的CPU、內存以及磁盤資源的利用率指標數據,這些統計數據由Heapster聚合後,能夠經過apiserver訪問。

要了解K8S的全部組件,沒去走一遍,永遠不知道它是怎麼跑起來的,那麼下面就帶着幾個新手疑問來看K8Sredis

  • 一、K8S是如何對容器編排?

在K8S集羣中,容器並不是最小的單位,K8S集羣中最小的調度單位是Pod,容器則被封裝在Pod之中。由此可知,一個容器或多個容器能夠同屬於在一個Pod之中。docker

  • 二、Pod是怎麼建立出來的?

Pod並非平白無故跑出來的,它是一個抽象的l邏輯概念,那麼Pod是如何建立的呢?Pod是由Pod控制器進行管理控制,其表明性的Pod控制器有Deployment、StatefulSet等。這裏咱們先有這樣的一個概念,後面再詳細解刨。後端

  • 三、Pod資源組成的應用如何提供外部訪問的?

Pod組成的應用是經過Service這類抽象資源提供內部和外部訪問的,可是service的外部訪問須要端口的映射,帶來的是端口映射的麻煩和操做的繁瑣。爲此還有一種提供外部訪問的資源叫作Ingress。api

  • 四、Service又是怎麼關聯到Pod呢?

在上面說的Pod是由Pod控制器進行管理控制,對Pod資源對象的指望狀態進行自動管理。而在Pod控制器是經過一個YAML的文件進行定義Pod資源對象的。在該文件中,還會對Pod資源對象進行打標籤,用於Pod的辨識,而Servcie就是經過標籤選擇器,關聯至同一標籤類型的Pod資源對象。這樣就實現了從service-->pod-->container的一個過程。緩存

  • 五、Pod的怎麼建立邏輯流程是怎樣的?
  • (1)客戶端提交建立請求,能夠經過API Server的Restful API,也可使用kubectl命令行工具。支持的數據類型包括JSON和YAML。
  • (2)API Server處理用戶請求,存儲Pod數據到etcd。
  • (3)調度器經過API Server查看未綁定的Pod。嘗試爲Pod分配主機。
  • (4)過濾主機 (調度預選):調度器用一組規則過濾掉不符合要求的主機。好比Pod指定了所須要的資源量,那麼可用資源比Pod須要的資源量少的主機會被過濾掉。
  • (5)主機打分(調度優選):對第一步篩選出的符合要求的主機進行打分,在主機打分階段,調度器會考慮一些總體優化策略,好比把容一個Replication Controller的副本分佈到不一樣的主機上,使用最低負載的主機等。
  • (6)選擇主機:選擇打分最高的主機,進行binding操做,結果存儲到etcd中。
  • (7)kubelet根據調度結果執行Pod建立操做: 綁定成功後,scheduler會調用APIServer的API在etcd中建立一個boundpod對象,描述在一個工做節點上綁定運行的全部pod信息。運行在每一個工做節點上的kubelet也會按期與etcd同步boundpod信息,一旦發現應該在該工做節點上運行的boundpod對象沒有更新,則調用Docker API建立並啓動pod內的容器。

從上面的幾個疑問,大體瞭解了K8S怎麼工做的,那麼如今再從三個面去了解Kubernetes,分別是Kubernetes概念和術語、集羣組件、網絡模型。服務器

2、K8S的概念和術語

​ Kubernetes是利用共享網絡將多個物理機或者虛擬機組成一個集羣,在各個服務器之間進行通訊,該集羣是配置Kubernetes的全部租金啊啊、功能和負載的物理平臺。網絡

​ 一個Kubernetes集羣由master和node組成。以下圖:

  • Master:是集羣的網關和中樞樞紐,主要做用:暴露API接口,跟蹤其餘服務器的健康狀態、以最優方式調度負載,以及編排其餘組件之間的通訊。單個的Master節點能夠完成全部的功能,可是考慮單點故障的痛點,生產環境中一般要部署多個Master節點,組成Cluster。
  • Node:是Kubernetes的工做節點,負責接收來自Master的工做指令,並根據指令相應地建立和銷燬Pod對象,以及調整網絡規則進行合理路由和流量轉發。生產環境中,Node節點能夠有N個。

img

Kubernetes從宏觀上看分爲2個角色:Master和Node,可是在Master節點和Node節點上都存在着多個組件來支持內部的業務邏輯,其包括:運行應用、應用編排、服務暴露、應用恢復等等,在Kubernetes中這些概念被抽象爲Pod、Service、Controller等資源類型。先來了解一下這些經常使用概念和術語:

  • (1)Pod

    從上圖,咱們能夠看到K8S並不直接地運行容器,而是被一個抽象的資源對象--Pod所封裝,它是K8S最小的調度單位。這裏要注意的是,Pod能夠封裝一個活多個容器!同一個Pod中共享網絡名稱空間和存儲資源,而容器之間能夠經過本地迴環接口:lo 直接通訊,可是彼此之間又在Mount、User和Pid等名稱空間上保持了隔離。

  • (2)資源標籤(Label)

    標籤(Label)是將資源進行分類的標識符,就好像超市的商品分類通常。資源標籤具體化的就是一個鍵值型(key/values)數據,相信瞭解redis的友友應該知道什麼是鍵值數據。使用標籤是爲了對指定對象進行辨識,好比Pod對象。標籤能夠在對象建立時進行附加,也能夠建立後進行添加或修改。要知道的是一個對象能夠有多個標籤,一個標籤頁能夠附加到多個對象。如圖:

  • (3)標籤選擇器(Selector)

    有標籤,固然就有標籤選擇器,它是根據Label進行過濾符合條件的資源對象的一種 機制。好比將含有標籤role: backend的全部Pod對象挑選出來歸併爲一組。一般在使用過程當中,會經過標籤對資源對象進行分類,而後再經過標籤選擇器進行篩選,最多見的應用就是講一組這樣的Pod資源對象建立爲某個Service的端點。如圖:

  • (4)Pod控制器(Controller)

    雖然Pod是K8S的最小調度單位,可是K8S並不會直接地部署和管理Pod對象,而是要藉助於另一個抽象資源--Controller進行管理。其實一種管理Pod生命週期的資源抽象,而且它是一類對象,並不是單個的資源對象,其中包括:ReplicationController、ReplicaSet、Deployment、StatefulSet、Job等。

    以Deployment爲例,它負責確保定義的Pod對象的副本數量符合預期的設置,這樣用戶只須要聲明應用的指望狀態,控制器就會自動地對其進行管理。如圖:

  • (5)服務資源(Service)

Service是創建在一組Pod對象之上的資源對象,在前面提過,它是經過標籤選擇器選擇一組Pod對象,併爲這組Pod對象定義一個統一的固定訪問入口(一般是一個IP地址),若是K8S存在DNS附件(如coredns)它就會在Service建立時爲它自動配置一個DNS名稱,用於客戶端進行服務發現。

一般咱們直接請求Service IP,該請求就會被負載均衡到後端的端點,即各個Pod對象,從這點上,是否是有點像負載均衡器呢,所以Service本質上是一個4層的代理服務,另外Service還能夠將集羣外部流量引入至集羣,這就須要節點對Service的端口進行映射了。

  • (6)存儲卷(Volume)

在使用容器時,咱們知道,當數據存放於容器之中,容器銷燬後,數據也會隨之丟失。這就是須要一個外部存儲,以保證數據的持久化存儲。而存儲卷就是這樣的一個東西。

存儲卷(Volume)是獨立於容器文件系統以外的存儲空間,經常使用於擴展容器的存儲空間併爲其提供持久存儲能力。存儲卷在K8S中的分類爲:臨時卷、本地卷和網絡卷。臨時卷和本地卷都位於Node本地,一旦Pod被調度至其餘Node節點,此類型的存儲卷將沒法被訪問,由於臨時卷和本地卷一般用於數據緩存,持久化的數據一般放置於持久卷(persistent volume)之中。

  • (7)Name和Namespace

名稱(Name)是K8S集羣中資源對象的標識符,一般做用於名稱空間(Namespace),所以名稱空間是名稱的額外的限定機制。在同一個名稱空間中,同一類型資源對象的名稱必須具備惟一性。

名稱空間一般用於實現租戶或項目的資源隔離,從而造成邏輯分組。關於此概念能夠參考:https://www.jb51.net/article/136411.htm

如圖:建立的Pod和Service等資源對象都屬於名稱空間級別,未指定時,都屬於默認的名稱空間default

  • (8)註解(Annotation)

Annotation是另外一種附加在對象上的一種鍵值類型的數據,經常使用於將各類非標識型元數據(metadata)附加到對象上,但它並不能用於標識和選擇對象。其做用是方便工具或用戶閱讀及查找。

  • (9)Ingress

K8S將Pod對象和外部的網絡環境進行了隔離,Pod和Service等對象之間的通訊須要經過內部的專用地址進行,若是須要將某些Pod對象提供給外部用戶訪問,則須要給這些Pod對象打開一個端口進行引入外部流量,除了Service之外,Ingress也是實現提供外部訪問的一種方式。

3、K8S集羣組件

一、Master組件

  • 一、API Server

K8S對外的惟一接口,提供HTTP/HTTPS RESTful API,即kubernetes API。全部的請求都須要通過這個接口進行通訊。主要負責接收、校驗並響應全部的REST請求,結果狀態被持久存儲在etcd當中,全部資源增刪改查的惟一入口。

  • 二、etcd

負責保存k8s 集羣的配置信息和各類資源的狀態信息,當數據發生變化時,etcd會快速地通知k8s相關組件。etcd是一個獨立的服務組件,並不隸屬於K8S集羣。生產環境當中etcd應該以集羣方式運行,以確保服務的可用性。

etcd不只僅用於提供鍵值數據存儲,並且還爲其提供了監聽(watch)機制,用於監聽和推送變動。在K8S集羣系統中,etcd的鍵值發生變化會通知倒API Server,並由其經過watch API向客戶端輸出。

  • 三、Controller Manager

負責管理集羣各類資源,保證資源處於預期的狀態。Controller Manager由多種controller組成,包括replication controller、endpoints controller、namespace controller、serviceaccounts controller等 。由控制器完成的主要功能主要包括生命週期功能和API業務邏輯,具體以下:

  • 生命週期功能:包括Namespace建立和生命週期、Event垃圾回收、Pod終止相關的垃圾回收、級聯垃圾回收及Node垃圾回收等。
  • API業務邏輯:例如,由ReplicaSet執行的Pod擴展等。
  • 四、調度器(Schedule)

資源調度,負責決定將Pod放到哪一個Node上運行。Scheduler在調度時會對集羣的結構進行分析,當前各個節點的負載,以及應用對高可用、性能等方面的需求。

二、Node組件

Node主要負責提供容器的各類依賴環境,並接受Master管理。每一個Node有如下幾個組件構成。

  • 一、Kubelet

kubelet是node的agent,當Scheduler肯定在某個Node上運行Pod後,會將Pod的具體配置信息(image、volume等)發送給該節點的kubelet,kubelet會根據這些信息建立和運行容器,並向master報告運行狀態。

  • 二、Container Runtime

每一個Node都須要提供一個容器運行時(Container Runtime)環境,它負責下載鏡像並運行容器。目前K8S支持的容器運行環境至少包括Docker、RKT、cri-o、Fraki等。

  • 三、Kube-proxy

service在邏輯上表明瞭後端的多個Pod,外借經過service訪問Pod。service接收到請求就須要kube-proxy完成轉發到Pod的。每一個Node都會運行kube-proxy服務,負責將訪問的service的TCP/UDP數據流轉發到後端的容器,若是有多個副本,kube-proxy會實現負載均衡,有2種方式:LVS或者Iptables

三、核心附件

K8S集羣還依賴一組附件組件,一般是由第三方提供的特定應用程序。以下圖:

  • 一、KubeDNS

在K8S集羣中調度並運行提供DNS服務的Pod,同一集羣內的其餘Pod可使用該DNS服務來解決主機名。K8S自1.11版本開始默認使用CoreDNS項目來爲集羣提供服務註冊和服務發現的動態名稱解析服務。

  • 二、Dashboard

K8S集羣的所有功能都要基於Web的UI,來管理集羣中的應用和集羣自身。

  • 三、Heapster

容器和節點的性能監控與分析系統,它收集並解析多種指標數據,如資源利用率、生命週期時間,在最新的版本當中,其主要功能逐漸由Prometheus結合其餘的組件進行代替。

  • 四、Ingress Controller

Service是一種工做於4層的負載均衡器,而Ingress是在應用層實現的HTTP(S)的負載均衡。不過,Ingress資源自身並不能進行流量的穿透,,它僅僅是一組路由規則的集合,這些規則須要經過Ingress控制器(Ingress Controller)發揮做用。目前該功能項目大概有:Nginx-ingress、Traefik、Envoy和HAproxy等。以下圖就是Nginx-ingress的應用,具體能夠查看博文:http://www.javashuo.com/article/p-ertaxvss-eo.html

img

4、K8S的網絡模型

K8S的網絡中主要存在4種類型的通訊:

  • ①同一Pod內的容器間通訊
  • ②各個Pod彼此間的通訊
  • ③Pod和Service間的通訊
  • ④集羣外部流量和Service之間的通訊

K8S爲Pod和Service資源對象分別使用了各自的專有網絡,Pod網絡由K8S的網絡插件配置實現,而Service網絡則由K8S集羣進行指定。以下圖:

K8S使用的網絡插件須要爲每一個Pod配置至少一個特定的地址,即Pod IP。Pod IP地址實際存在於某個網卡(能夠是虛擬機設備)上。

而Service的地址倒是一個虛擬IP地址,沒有任何網絡接口配置在此地址上,它由Kube-proxy藉助iptables規則或ipvs規則重定向到本地端口,再將其調度到後端的Pod對象。Service的IP地址是集羣提供服務的接口,也稱爲Cluster IP。

Pod網絡和IP由K8S的網絡插件負責配置和管理,具體使用的網絡地址能夠在管理配置網絡插件時進行指定,如10.244.0.0/16網絡。而Cluster網絡和IP是由K8S集羣負責配置和管理,如10.96.0.0/12網絡。

從上圖進行總結起來,一個K8S集羣包含是三個網絡。

  • (1)節點網絡:各主機(Master、Node、ETCD等)自身所屬的網絡,地址配置在主機的網絡接口,用於各主機之間的通訊,又稱爲節點網絡。
  • (2)Pod網絡:專用於Pod資源對象的網絡,它是一個虛擬網絡,用於爲各Pod對象設定IP地址等網絡參數,其地址配置在Pod中容器的網絡接口上。Pod網絡須要藉助kubenet插件或CNI插件實現。
  • (3)Service網絡:專用於Service資源對象的網絡,它也是一個虛擬網絡,用於爲K8S集羣之中的Service配置IP地址,可是該地址不會配置在任何主機或容器的網絡接口上,而是經過Node上的kube-proxy配置爲iptables或ipvs規則,從而將發往該地址的全部流量調度到後端的各Pod對象之上。

5、Kubernetes的核心對象詳解

一、Pod資源對象

​ Pod資源對象是一種集合了一個或多個應用容器、存儲資源、專用ip、以及支撐運行的其餘選項的邏輯組件。以下圖:Pod其實就是一個應用程序運行的單一實例,它一般由共享資源且關係緊密的一個或2多個應用容器組成。

​ Kubernetes的網絡模型要求每一個Pod的IP地址同一IP網段,各個Pod之間可使用IP地址進行通訊,不管這些Pod運行在集羣內的哪一個節點上,這些Pod對象都相似於運行在同一個局域網內的虛擬機通常。

​ 咱們能夠將每個Pod對象類比爲一個物理主機或者是虛擬機,那麼運行在同一個Pod對象中的多個進程,也就相似於跑在物理主機上的獨立進程,而不一樣的是Pod對象中的各個進程都運行在彼此隔離的容器當中,而各個容器之間共享兩種關鍵性資源:網絡和存儲卷。

  • 網絡:每個Pod對象都會分配到一個Pod IP地址,同一個Pod內部的全部容器共享Pod對象的Network和UTS名稱空間,其中包括主機名、IP地址和端口等。所以,這些容器能夠經過本地的迴環接口lo進行通訊,而在Pod以外的其餘組件的通訊,則須要使用Service資源對象的Cluster IP+端口完成。
  • 存儲卷:用戶能夠給Pod對象配置一組存儲卷資源,這些資源能夠共享給同一個Pod中的全部容器使用,從而完成容器間的數據共享。存儲卷還能夠確保在容器終止後被重啓,或者是被刪除後也能確保數據的持久化存儲。

​ 一個Pod表明着某個應用程序的特定實例,若是咱們須要去擴展這個應用程序,那麼就意味着須要爲該應用程序同時建立多個Pod實例,每一個實例都表明着應用程序的一個運行副本。而這些副本化的Pod對象的建立和管理,都是由一組稱爲Controller的對象實現,好比Deployment控制器對象。

​ 當建立Pod時,咱們還可使用Pod Preset對象爲Pod注入特定的信息,好比Configmap、Secret、存儲卷、卷掛載、環境變量等。有了Pod Preset對象,Pod模板的建立就不須要爲每一個模板顯示提供全部信息。

​ 基於預約的指望狀態和各個節點的資源可用性,Master會把Pod對象調度至選定的工做節點上運行,工做節點從指向的鏡像倉庫進行下載鏡像,並在本地的容器運行時環境中啓動容器。Master會將整個集羣的狀態保存在etcd中,並經過API Server共享給集羣的各個組件和客戶端。

二、Controller

​ 在K8S的集羣設計中,Pod是一個有生命週期的對象。那麼用戶經過手工建立或者經過Controller直接建立的Pod對象會被調度器(Scheduler)調度到集羣中的某個工做節點上運行,等到容器應用進程運行結束以後正常終止,隨後就會被刪除。而須要注意的是,當節點的資源耗盡或者故障,也會致使Pod對象的回收。

​ 而K8S在這一設計上,使用了控制器實現對一次性的Pod對象進行管理操做。好比,要確保部署的應用程序的Pod副本數達到用戶預期的數目,以及基於Pod模板來重建Pod對象等,從而實現Pod對象的擴容、縮容、滾動更新和自愈能力。例如,在某個節點故障,相關的控制器會將運行在該節點上的Pod對象從新調度到其餘節點上進行重建。

​ 控制器自己也是一種資源類型,其中包括Replication、Controller、Deployment、StatefulSet、DaemonSet、Jobs等等,它們都統稱爲Pod控制器。以下圖的Deployment就是這類控制器的表明實現,是目前用於管理無狀態應用的Pod控制器。

​ Pod控制器的定義一般由指望的副本數量、Pod模板、標籤選擇器組成。Pod控制器會根據標籤選擇器來對Pod對象的標籤進行匹配篩選,全部知足選擇條件的Pod對象都會被當前控制器進行管理並計入副本總數,確保數目可以達到預期的狀態副本數。

​ 須要注意的是,在實際的應用場景中,在接收到的請求流量負載低於或接近當前已有Pod副本的承載能力時,須要咱們手動修改Pod控制器中的指望副本數量以實現應用規模的擴容和縮容。而在集羣中部署了HeapSet或者Prometheus的這一類資源監控組件時,用戶還能夠經過HPA(HorizontalPodAutoscaler)來計算出合適的Pod副本數量,並自動地修改Pod控制器中指望的副本數,從而實現應用規模的動態伸縮,提升集羣資源的利用率。

​ K8S集羣中的每一個節點上都運行着cAdvisor,用於收集容器和節點的CPU、內存以及磁盤資源的利用率直播數據,這些統計數據由Heapster聚合以後能夠經過API server訪問。而HorizontalPodAutoscaler基於這些統計數據監控容器的健康狀態並做出擴展決策。

三、Service

​ 咱們知道Pod對象有Pod IP地址,可是該地址沒法確保Pod對象重啓或者重建以後保持不變,這會帶來集羣中Pod應用間依賴關係維護的麻煩。好比前段Pod應用沒法基於固定的IP地址跟中後端的Pod應用。

​ 而Service資源就是在被訪問的Pod對象中添加一個有着固定IP地址的中間層,客戶端向該地址發起訪問請求後,由相關的Service資源進行調度並代理到後端的Pod對象。

​ Service並非一個具體的組件,而是一個經過規則定義出由多個Pod對象組成而成的邏輯集合,並附帶着訪問這組Pod對象的策略。Service對象挑選和關聯Pod對象的方式和Pod控制器是同樣的,都是經過標籤選擇器進行定義。以下圖:

​ Service IP是一種虛擬IP,也稱爲Cluster IP,專用於集羣內通訊,一般使用專有的地址段,如:10.96.0.0/12網絡,各Service對象的IP地址在該範圍內由系統動態分配。

​ 集羣內的Pod對象可直接請求這類Cluster IP,好比上圖中來自Pod client的訪問請求,能夠經過Service的Cluster IP做爲目標地址進行訪問,可是在集羣網絡中是屬於私有的網絡地址,僅僅能夠在集羣內部訪問。

​ 而須要將集羣外部的訪問引入集羣內部的經常使用方法是經過節點網絡進行,其實現方法以下:

  • 經過工做節點的IP地址+端口(Node Port)接入請求。
  • 將該請求代理到相應的Service對象的Cluster IP的服務端口上,通俗地說:就是工做節點上的端口映射了Service的端口。
  • 由Service對象將該請求轉發到後端的Pod對象的Pod IP和 應用程序的監聽端口。

​ 所以,相似於上圖來自Exxternal Client的集羣外部客戶端,是沒法直接請求該Service的Cluster IP,而是須要實現通過某一工做節點(如 Node Y)的IP地址,着了請求須要2次轉發才能到目標Pod對象。這一類訪問的缺點就是在通訊效率上有必定的延時。

相關文章
相關標籤/搜索