天天看點

kubernetes 基本概念

  kubernetes中的Node、Pod、Replication Controller、Service等都可以看作為資源對象,幾乎所有的資源對象都可以通過kubectl工具執行增删改查并将其儲存在etcd中持久化存儲。 kubernetes通過對資源進行監控,并對比etcd庫中儲存的資源期望狀态與目前環境中資源實際狀态的差異來實作對容器群的自動控制與自動糾錯。

1. Master

  Master和Node都屬于實體主機或虛拟機. Master是叢集的控制節點, 負責叢集的管理和控制, 接收并執行kubernetes的控制指令. 

  Master之上運作如下關鍵程序:

    ● Kubernetes API Server(kube-apiserver): 提供标準的Http Rest 接口,是kubernetes資源增删改查的唯一入口, 也是叢集控制的入口程序;

    ● Kubernetes Controller Manager (kube-controller-manager): kubernetes中所有資源對象的自動化控制中心, 是資源對象的大總管;

    ● Kubernetes Scheduler(kube-scheduler): 負責資源排程(pod排程)的程序;

    ● etcd: Master節點上需要啟動etcd服務, kubernetes所有的資源對象的資料都會儲存在etcd中.

2. Node

       除了Master, kubernetes叢集中其他所有機器稱之為Node節點. Node節點可以在運作期間動态的增加到kubernetes叢集中, 當Node被納入叢集中, kubelet會自動向Master注冊自己進而被Master所管理, Master會配置設定給Node任務, 當Node當機時, 其工作負載會被Master自動轉移到其他Node上. 

       Node會定時向Master發送自身的資訊, 包括作業系統, Docker版本, 機器CPU和記憶體使用情況, 以及目前有哪些pod在運作等. Master根據這些資訊獲知每個Node的資源使用情況, 進而實作高效均衡的資源排程政策. 當某個Node超過指定時間沒有上報資訊時, 會被Master判斷為"失聯", 該Node狀态被标記為"不可用"(Not Ready), 随後Master會觸發"工作負載轉移"的自動流程.

  Node上運作的關鍵程序如下:

          ● kubelet: 負責Pod對應容器的建立、啟停等任務,同時與Master節點密切協作,實作叢集管理的基本功能;

       ● kube-proxy: 實作kubernetes Service的通信與負載均衡機制的主要元件;

    ● Docker Engine(docker): Docker引擎,負責本機容器建立以及管理工作, 管理容器的.

3. Pod

kubernetes 基本概念

  pod運作在Node之上, 一個Node可運作多個pod; 容器運作在pod中, 一個pod可對應多個容器. 

  pod類别: 

    ● 靜态pod(Static Pod): 不存放在etcd存儲中, 而是存放在某個具體Node上的一個具體檔案中, 并且隻在該Node上啟動運作;

    ● 普通pod: 普通pod一旦被建立, 會被立即放入etcd中存儲, 随後會被kubernetes Master排程到某個具體的Node上并運作綁定(Binding), 随後該pod被對應的Node上的kubelet程序執行個體化成一組相關的docker容器并啟動起來.

  容器類别:

    ● Pause容器: 根容器, 其IP和挂載的Volume被業務容器所共享;

    ● 業務容器: 使用者自定義的容器.

  在預設情況下, pod裡的某個容器停止運作時, kubernetes會自動檢測到這個問題并且重新啟動這個pod(重新開機pod裡的所有容器), 如果pod所在的node當機, 則會将這個node上的所有pod重新排程到其他節點.

4. Label

  Label是使用者指定的鍵值對. 可附加到各種資源對象上, 例如Node, Pod, Service, RC等. 一個資源對象可定義多個Label, 同一個Label可應用到多個資源對象中.  Label可在資源對象定義時指定, 也能在運作過程中動态添加和删除.

  通過Label Selector(标簽選擇器)可以篩選擁有某些标簽的資源對象, 相當于SQL中的WHERE條件, 例如name=redis-server的Label Selector作用于pod時, 相當于條件WHERE name=redis-server. 我們可以通過為指定的資源對象添加多個Label實作多元度的資源分組管理.

5. Replication Controller

  RC用于定義期望值, 例如聲明某種pod的副本數量在任意時刻都符合某個預期值, 是以其定義包括如下幾個部分:

    ● Pod期待的副本數;

    ● 用于篩選目标Pod的Label Selector;

    ● 當Pod的副本數小于預期數量的時候,用于建立新Pod的Pod模闆。

  當RC被定義并送出到kubernetes叢集中, Master節點的Controller Manage元件就會得到通知, 進而依據RC的定義, 定期巡檢系統中存活的目标pod, 確定目标pod執行個體的數量剛好等于此RC的期望值, 如果有過多pod副本在運作, 系統就會停掉一些pod, 否則自動建立pod. 通過RC, kubernetes實作了使用者應用叢集的高可用性.

  在運作時, 能夠通過動态更改RC的副本數量, 來實作pod的動态縮放. 

  删除RC時, 不會影響通過該RC已建立好的pod, 如果想要删除其建立的pod, 可以通過設定其副本數量為0實作. 另外, kubectl提供了stop和delete指令來一次性删除RC及其控制的全部pod.

  此外, RC可以實作滾動更新, 藍綠部署.

  總結RC特性及作用:

    ● 在大多數情況下,我們通過定義一個RC實作Pod的建立過程以及副本數量的自動控制;

    ● RC裡包括完整的Pod定義模闆;

    ● RC通過Label Selector 機制實作對Pod副本的自動控制;

    ● 通過改變RC的Pod副本數量,可以實作Pod的擴容和縮容功能;

    ● 通過改變RC裡Pod模闆中的鏡像版本,可以實作Pod的滾動更新功能.

6. Replica Set

  由于Replication Controller與kubernetes中的子產品Replication Controller同名,是以在kubernetes 1.2 ,它更新為Replica Set ,與之前的RC的唯一差別是支援基于集合的Label selector ,而RC隻支援基于等式的Label Selector 這使得Replica Set的功能更強。

  我們很少直接使用Replica Set, 它主要被Deployment這個更高層的對象使用, 進而形成一整套的pod建立, 删除, 更新的編排機制. 當我們使用Deployment時, 無需關心它是如何建立和維護Replica Set對象的.

  Replica Set和Deployment這兩個資源對象逐漸替代了之前的RC的作用, 是v1.3 pod自動擴容(伸縮)這個告警功能實作的基礎.

7. Deployment

  Deployment為了更好地解決pod的編排問題, 為此, Department在内部使用了Replica Set對象 , Department可以認為是RC的一次更新, 兩者相似度超過90%.

相對于RC, Department可以随時知道目前pod部署的進度, 一個pod的建立, 排程, 綁定節點以及在目标Node啟動對應的容器這一完整過程需要一定的時間, 就是一個連續變化的部署過程.

  典型适用場景:

    ● 建立一個Deployment對象來生成對應的Replica Set并完成Pod副本的建立過程;

    ● 檢查Deployment的狀态來看部署動作是否完成(Pod副本的數量是否達到預期的值);

    ● 更新Deployment以建立新的Pod(比如鏡像更新);

    ● 如果目前的Depoyment不穩定,則復原到一個早先的Deployment版本;

    ● 擴充Department以應對高負載;

    ● 檢視Department狀态, 以此作為釋出是否成功的名額.

    ● 清理不需要的舊版Replica Set.

8. Horizontal Pod Autoscaler (HPA)

  Pod橫向自動擴容,通過追蹤分析RC控制的所有目标Pod的負載變化情況,來确定是否需要針對性的調整目标Pod的副本數. 

  HPA有以下兩種方式來作為HPA的負載名額:

    ● CPUUtilizationPercentage  是指Cpu使用率的平均值, 通常是過去1min内的平均值;

    ● 應用程式自定義的度量标準,比如服務在每秒内的響應的請求數(TPS或QPS)

  如果某一名額到達臨界點, 例如CPUUtilizationPercentage達到80%, 可以認為是目前pod副本數很可能不足以支撐接下來更多的請求, 此時會觸發動态擴容, 當請求高峰期過去後, pod的CPUUtilizationPercentage又會降下來, 此時對應的pod數就會自動減少到一個合理的水準.

9. StatefulSet

  在kubernetes中, pod的管理對象RC, Deployment, DaemonSet和Job都是面向無狀态的服務, 但是現實中很多服務需要狀态, 例如Mysql, Zookeeper等. 這些應用的叢集有以下共同點:

    ● 每個節點都有固定的身份ID, 通過這個ID, 叢集中的成員可以互相發現并且通信;

    ● 叢集的規模是比較固定的, 叢集規模不能随意改動;

    ● 叢集中每個節點都是有狀态的, 通常會持久化資料到永久存儲中;

    ● 如果磁盤損壞, 則叢集中某個節點無法正常運作, 叢集功能受損.

  如果用RC / Deployment控制pod副本數方式來實作有狀态的叢集, 會發現第一點無法滿足, 因為pod名字是随機産生的, 無法為每個pod确定唯一不變的ID. 另外, 為了能夠在其他節點上恢複某個失敗的節點, 這種叢集中的pod需要挂載某種共享的存儲. 為了解決這個問題, kubernetes在v1.4引入了PetSet, 并在v1.5更名為StatefulSet.

  StatefulSet可以看為Deployment / RC的變種, 有如下特性:

    ● StatefulSet裡的每個pod都有穩定唯一的網絡辨別, 可以用來發現叢集中其他成員. 假設StatefulSet名字為kafka, 那麼第一個pod叫kafka-0, 第二個為kafka-1, 以此類推;

    ● StatefulSet控制的pod副本的啟停順序是受控的, 操作第n個pod時, 前n-1個pod已經是運作且準備好的狀态;

    ● StatefulSet裡的pod采用穩定的持久化存儲卷, 通過PV / PVC來實作, 删除pod時, 預設不會删除與StatefulSet相關的存儲卷.

10. Service

  kubernetes中的Service對應的是微服務架構中的一個微服務, 之前的pod, RC等資源對象都是為Service服務的. 

kubernetes 基本概念

  Service定義了一個服務的通路入口位址, 前端應用通過這個入口位址通路其背後的一組由pod副本組成的叢集執行個體. Service與其後端pod副本叢集之間則是通過Label Selector來實作對接. 而RC的作用實際上是保證Service的服務能力和服務品質始終保持在預期的标準. 

  因為pod的IP位址會随着pod的銷毀和重新建立而變化,是以通路端不能以寫死IP的方式去通路pod提供的服務。而service作為pod路由代理抽象,通路端隻需要知道service的位址,由service來提供代理,保證了pod的動态變化對通路端透明。

  每個Node上運作的kube-proxy是一個智能的軟體負載均衡器,負責将用戶端發送到Service的請求依據負載均衡算法轉發到後端的某個pod執行個體上.

  Service一旦被建立, kubernetes會為它配置設定一個可用的Cluster IP, 在Service整個生命周期内都不會發生變化. 于是服務發現的問題被解決了: 使用Service的Name與Cluster IP做一個DNS映射即可.

  由此知道, 用戶端通路Service位址, 然後Service将請求轉發給pod. 

  Service位址如何得到?

  首先看一下Cluster IP特點:

    ● Cluster IP僅僅作用于Kubernetes Service這個對象,并由kubernetes管理和配置設定IP位址(來源于Cluster IP位址池);

    ● Cluster IP無法被ping,因為沒有一個實體網絡對象來響應;

    ● Cluster IP隻能結合Service Port組成一個具體的通信端口,單獨的Cluster IP 不具備TCP/IP通信的基礎,并且它們隻屬于Kubernetes叢集這樣一個封閉的空間,叢集之外的節點要通路這個通信端口,則要做一些額外的工作;

    ● 在Kubernetes叢集之内,Node IP網、Pod IP網與Cluster IP網之間的通信,采用的是Kubernetes自己設計的一種程式設計方式的特殊的路由規則,與我們熟知的IP路由有很大的不同。

  也就是說外網不能直接通路Cluster IP, 那麼如何通路Service? 通過NodePort來通路的。在Service定義中指定NodePort, 例如10000, 那麼通過NodeIP + NodePort即可通路到Service.

  NodePort的實作方式是在kubernetes叢集裡的每個Node上為需要外部通路的Service開放一個對應的監聽端口, 外部系統隻要用任意一個Node的IP位址+具體的NodePort端口号即可通路此服務. 

11. Volume

  Volume是pod中能被多個容器通路的共享目錄. 除了可以讓多個容器共享檔案, 讓容器資料寫到主控端的磁盤上或網絡存儲外, 還能通過ConfigMap做容器配置檔案集中化定義與管理.

  Volume類型:

    ● emptyDir: pod被配置設定到Node時建立的, 初始内容為空, 無需指定主控端上對應的目錄檔案, 因為這是kubernetes自動配置設定的一個目錄;

    ● hostPath: pod挂載在主控端上的檔案和目錄;

    ● NFS: NFS可通過網絡将遠端NFS伺服器分享的目錄挂載到本地,使得不同的機器或作業系統共享檔案. 使用NFS網絡檔案系統提供的共享目錄存儲資料時, 需要在系統中部署一個NFS Server.

12. Persistent Volume

  PV是叢集中的一塊網絡存儲,是Kubernetes叢集的一種資源。 

  Pod的Volume與PV的差別:

    Volume從屬于pod, 生命周期和Pod相同,Pod被删除時,Volume和儲存在Volume中的資料就被删除了;Volume和使用它的Pod之間是一種靜态綁定關系,在定義Pod檔案時也定義了它使用的Volume。Volume是Pod的附屬品,我們無法單獨建立一個Volume,因為它不是一個獨立的資源對象;

    PV是一個獨立的資源對象,是以我們可以單獨建立一個PV。它不和Pod直接發生關系,而是通過PVC來實作動态綁定。Pod定義裡指定的PVC,然後PVC根據Pod的要求自動綁定合适的PV。PV是獨立的,即使挂載PV的Pod被删除了,PV和PV上的資料仍然存在。

  PV通路模式範圍如下:

    ● ReadWriteOnce:該卷能夠以讀寫模式被加載到一個節點上。

    ● ReadOnlyMany:該卷能夠以隻讀模式加載到多個節點上。

    ● ReadWriteMany:該卷能夠以讀寫模式被多個節點同時加載。

  PV的狀态:

    ● Available:可用資源,尚未被綁定到 PVC 上;

    ● Bound:已經綁定到某個PVC上;

    ● Released:對應的PVC 已經被删除,但該資源尚未被叢集回收;

    ● Failed:該卷的自動回收過程失敗。

13、Namespace 

  Namespace在很多情況下用于實作多租戶的資源隔離,Namespace通過将叢集内部的資源對象配置設定到不同的namespace中,形成邏輯上分組的不同項目、小組和使用者組, 便于不同的分組在共享叢集的資源時還能被分别管理.

kubernetes叢集在啟動後, 預設建立一個名為default的Namespace, 如果不特别指明Namespace, 使用者建立的pod, RC, Service都将被系統建立到為default的NameSpace中.

  一旦建立了namespace, 在建立資源對象時就可以指定哪些資源屬于哪個namespace. 

  結合kubernetes的資源配額管理, 能夠限定不同租戶能占用的資源, 例如CPU / 記憶體使用量等.

14. Annotation

  Annotation與Label類似, 同樣使用鍵值對定義. 但Label定義的是對象的中繼資料, 可用于Label Selector. 而Annotation是使用者任意定義的附加資訊, 以便于外部工具查找, 很多時候, kubernetes的子產品自身會通過Annotation方式标記資源對象的一些特殊資訊.

  注: 本文基于Kubernete權威指南進行總結.