K8S--架構及基本概念


一、K8S簡述

  K8S是Kubernetes的簡稱,其是基於谷歌的Borg系統開發的。

  K8S主要功能:

  K8s是用來對docker容器進行管理和編排的工具,其是一個基於docker構建的調度服務,提供資源調度、均衡容災、服務注冊、動態擴容等功能套件,其作用如下所示:

  (1)數據卷:pod中容器之間數據共享,可以使用數據卷

  (2)應用程序健康檢查:容器內服務可能發生異常導致服務不可用,可以使用健康檢查策略保證應用的健壯性。

  (3)復制應用程序實例:控制器維護着pod的副本數量,保證一個pod或者一組同類的pod數量始終可用。

  (4)彈性伸縮:根據設定的指標(CPU利用率等)動態的自動縮放pod數

  (5)負載均衡:一組pod副本分配一個私有的集群IP地址,負載均衡轉發請求到后端容器,在集群內布,其他pod可通過這個Cluster IP訪問集群。

  (6)滾動更新:更新服務不中斷,一次更新一個pod,而不是同時刪除整個服務

  (7)服務編排:通過文件描述部署服務,使的程序部署更高效。

  (8)資源監控:Node節點組件集成cAdvisor資源收集工具,可通過Heapster匯總整個集群節點資源數據,然后存儲到InfluxDB時序數據庫,再由Grafana展示

  (9)提供認證和授權:支持屬性訪問控制、角色訪問控制等認證授權策略。

  K8S的架構圖如下所示:

      

   從上圖可以看到,K8S提供了:

    web browsers提供可視化操作

    kubectl來接收Docker鏡像進行部署

    scheduler進行任務調度

    Controller進行請求控制

    API Server進行請求的統一網關處理

    etcd用於存儲集群中的網絡及狀態信息

    Kubelet來接收控制器的處理任務

    Container Registry用來存儲鏡像倉庫

二、K8S集群

(一)集群概述

  一個K8S集群包含一個master節點和一群node節點,Mater節點負責管理和控制,Node節點是工作負載節點,里面是具體的容器,容器中部署的是具體的服務。

  Mater節點包括API Server、Scheduler、Controller Manager、etcd。

    API Server:整個集群的對外接口,供客戶端和其他組件調用。

    Scheduler:負責集群內部資源調度

    Controller Manager:負責管理控制器。

    etcd:用於保存集群中所有網絡配置和對象狀態信息。

  node節點包括Docker、kubelet、kube-proxy、Fluentd、kube-dns(可選)、pod     

 (二)Mater節點

  上面已經提到,Mater節點包括API Server、Scheduler、Controller Manager、etcd。

  1、API Server

    API Server是整個集群的統一入口,各組件的協調者,以HTTP的形式對外提供服務,所有對象資源的增刪改查和監聽操作都交給API Server處理后再提交給etcd進行存儲。

  2、Scheduler

    Scheduler負責集群內部資源調度,其會根據調度算法為新創建的pod選擇一個node節點,Scheduler在整個集群中起到了承上啟下的重要功能,承上是指她負責接收Controller Manager創建的新的pod,為其安排一個node節點,啟下指的是當為pod選定node節點后,目標Node上的kubelet服務進程會接管該pod。

      

    這里就要提一下創建Pod的流程:

      (1)kubectl發送創建pod的請求,此時這個命令被apiserver攔截,把創建的pod存儲到etcd的podQueue

      (2)Scheduler發起調用請求,此時這個命令被apiserver攔截,獲取etcd中podQueue.NodeList,使用調度算法(調度算法:預選調度、優選策略)選擇一個合適的node節點

      (3)把選擇合適的pod、node存儲到etcd中

      (4)node節點上的Kubelet進程,發送請求獲取pod、node對應創建資源

      (5)此時node發現pod是本node需要創建的,kubelet就開始創建pod

  3、Controller Manager

    每個資源都對應一個控制器(Kubernets Controller),其用來處理集群中常規的后台任務,而Controller Manager是用來負責管理控制器的。

    K8S集群有以下控制器:

      (1)Replication Controller:保證Replication Controller中定義的副本數量與實際運行的pod數量一致。

      (2)Node Controller:管理維護Node,定期檢查Node節點的健康狀態,標識出失效和未失效的Node節點。

      (3)Namespace Controller:管理維護Namespace,定期清理無效的Namespace,包括Namespace下的API對象,例如pod和service等

      (4)Service Controller:管理維護Service,提供負載以及服務代理。

      (5)Endpoints Controller:管理維護Endpoints,即維護關聯service和pod的對應關系,其對應關系通過Label來進行關聯的

      (6)Service Account Controller:管理維護Service Account,為每個Namespace創建默認的Service Account,同時為Service Account創建Service Account Secret。

      (7)Persistent Volume Controller:持久化數據控制器,用來部署有狀態服務

      (8)Deamon Set Controller:讓每一個Node節點都運行相同的服務

      (9)Deployment Controller:無狀態服務部署控制器

      (10)Job Controller:管理維護Job,為Job創建一次性任務Pod,保證完成Job指定完成的任務數目。

      (11)Pod Autoscaler Controller:實現pod的自動伸縮,定時獲取監控數據,進行策略匹配,當滿足條件時執行pod的伸縮動作。

  4、etcd

    etcd是一個第三方服務,分布式鍵值對存儲系統,用於保存網絡配置、集群狀態等信息,例如service、pod等對象的信息。

    K8S中一共有兩個服務需要用到etcd來協調和存儲數據,分別是網絡插件flannel和K8S本身,其中flannel使用etcd存儲網絡配置信息,K8S本身使用etcd存儲各種對象的狀態和元信息配置。

(三)Node節點

  上面提到,node節點包括Docker、kubelet、kube-proxy、Fluentd、kube-dns(可選)、pod等信息。

      

  1、kubelet

    kubelet是Mater在Node節點上的代理,每個Node節點都會啟動一個kubelet進程,用來處理Mater節點下發到Node節點的任務,管理本機運行容器的生命周期,比如創建容器、Pod掛載數據卷、下載secret、獲取容器和節點的狀態等工作,kubelet將每個pod轉換成一組容器。

    kubelet默認監聽四個端口:10250、10255、10248、4194

    10250端口:kubelet API的端口,也就是kubelet server與api server的通訊端口,定期請求apiserver獲取自己所應當處理的任務,通過該端口可以訪問和獲取node資源及狀態。

    10248端口:健康檢查的端口,通過訪問該端口可以判斷kubelet是否正常工作,可以通過 kubelet 的啟動 參數 --healthz-port 和 --healthz-bind-address 來指定監聽的地址和端口

    4194端口:kubelet通過該端口可以獲取到該節點的環境信息以及node上運行的容器狀態等內容,訪問 http://localhost:4194 可以看到 cAdvisor 的管理界面,通過 kubelet 的啟動參 數 --cadvisor-port 可以指定啟動的端口。

    10255端口:提供了pod和node的信息,接口以只讀形式暴露出去,訪問該端口不需要認證和鑒權。

  2、kube-proxy

    在Node節點上實現Pod網絡代理,維護網絡規則和四層負載均衡工作,kube-proxy本質上類似於一個反向代理,我們可以把每個節點上運行的kube-proxy看作是service的透明代理兼LB。

    kube-proxy監聽apiserver中service與endpoints的信息,配置iptables規則,請求通過iptables直接轉發給pod。

    

   3、docker

    運行容器的引擎,pod內部運行的都是容器,這個容器是由Docker引擎創建的,Docker引擎是node節點的基礎服務。

  4、pod

    pod是最小的部署單元,一個pod由一個或多個容器組成,pod中共享存儲和網絡,在同一個Docker主機上運行。pod內部可以運行一個或多個容器,一般情況下,為了便於管理,一個pod下只運行一個容器。

(四)Pod

  pod就是一個容器,內部封裝了docker容器,同時擁有自己的ip地址,也有用自己的HostName,Pod就像一個物理機一樣,實際上Pod就是一個虛擬化的容器(進程),pod中運行的是一個或者多個容器。

      

   pod是一個大的容器,由K8S創建,pod內部的是docker容器,由Docker引擎創建。K8S不會直接管理容器,而是管理Pod。

  pod的作用是管理線上運行的應用程序,在通常情況下,在服務上線部署的時候,pod通常被用來部署一組相關的服務。而一個調用鏈上的服務就叫做一組相關的服務。但是實際生產上一般是一個Pod對應一個服務,不會在一個Pod上部署太多的服務。

  pod的具體結構如下圖所示,一個Node中有很多pause容器,這些pause容器和pod是一一對應的,每個Pod里面運行着一個特殊的被稱為Pause的容器,其他的容器則為業務容器,這些容器共享Pause容器的網絡和存儲,因此他們之間的通信更高效,在同一個pod里面的容器之間僅需要通過localhost就可以通信。

      

   K8S中的pause容器主要為每個業務容器提供以下功能,從而對各個Pod進行了隔離:

    PID命名空間隔離:pod中不同的應用程序可以看到其他應用程序的進程ID

    網絡命名空間隔離:Pod中多個容器能夠訪問同一個IP和端口范圍

    IPC命名空間隔離:Pod中多個容器能夠使用System VIPC或POSIX消息隊列進行通信

    UTS命名空間隔離:pod中多個容器共享一個主機名和掛在卷

    Pod中各個容器可以訪問在Pod級別定義的Volumes

  一個Pod創建的過程:首先kubelet會先創建一個pod,然后立馬會創建一個pause容器,pause容器是默認創建的,然后再創建內部其他的業務容器。

三、核心組件及原理

  1、RC控制器(ReplicationController)

    用來確保容器應用的副本數始終與用戶定義的副本數一致,如果有副本由於異常退出,Replication Pod會自動創建新的Pod來替代,而如果出現多余的pod,控制器也會自動將其回收。

    在新版的K8S中,建議使用ReplicaSet來取代Replication Controller

  2、RS控制器(ReplicaSet)

    ReplicaSet和Replication Contreoller並沒有本質上的區別,ReplicaSet支持集合式的選擇器。

    雖然ReplicaSet可以獨立使用,但一般情況下還是建議使用Deployment來自動管理ReplicaSet,這樣就無需擔心跟其他機制的不兼容問題。

    RC和RS的區別是RC只支持單個標簽選擇器,不支持復合標簽選擇器;而RS同時支持單個和復合選擇器。

  3、label(標簽)

    label用於區分對象,例如區分是service還是pod,以鍵值對的形式存在,每個對象可以有多個標簽,可以通過標簽關聯對象。

    label是replication Controller和Service運行的基礎,二者是通過label來進行關聯Node上運行的Pod。我們可以通過給指定的資源對象捆綁一個或多個不同的Label來實現多維度資源分配管理功能,一些常用的Label如下所示:

版本標簽:"release":"stable","release":"canary"......
環境標簽:"environment":"dev","environment":"qa","environment":"production" 架構標簽:"tier":"frontend","tier":"backend","tier":"middleware" 分區標簽:"partition":"customerA","partition":"customerB" 質量管控標簽:"track":"daily","track":"weekly"

    label就類似與標簽,給某個對象定義了一個label就相當於給對象定義了一個標簽。

    如果多個pod擁有相同的標簽,就說明這是一組pod。

  4、selector

    標簽選擇器是K8S非常重要的一環,其用來查詢和篩選某些擁有具體標簽的對象,K8S也是使用這種方式進行對象的查詢。

    Label Selector在K8S中的應用有以下幾個場景:

      Kube-Controller進程通過資源對象RC上定義的Label Selector來篩選要監控的Pod的副本數量,從而實現副本數量與用戶定義的副本數量保持一致。

      Kube-proxy進程通過Service的Label Selector來篩選對應的Pod,自動建立起每個Service到對應Pod的請求鏈路表,從而實現Service的負載均衡。

      Kube-Scheduler通過對某些Pod的自定義Label,並且在pod定義文件中使用Node Selector這種標簽的調度策略,從而實現了Pod定向調度的特性。

    例如上面Label的例子中,如果服務中既有環境Label又有版本Label,使用RC只能對同一個版本標簽或者同一個環境標簽的Pod進行選擇,不能同時對版本和環境兩個維度進行篩選,而RS可以對兩個維度同時進行篩選。

  5、Deployment

    RS雖然可以控制副本的數量,但是單獨的RS部署卻不能滾動更新。因此衍生了Deployment組件,其支持滾動更新,其會先創建新版本的pod容器,然后再刪除老舊版本的pod容器。

    滾動發布:滾動發布有金絲雀發布和灰度發布,該種發布一般是以25%的模式進行發布,也就是先刪除25%舊版本,在部署對應數量的新版本Pod,然后再刪除25%舊版本,這樣以此滾動更新。

    因此實際生產中一般都是用RS和Deployment的組合來進行發布服務。

    總體來說,Deployment是用來管理RS,RS來管理Pod,deployment支持動態更新,也就是在更新時動態的創建一個新的RS,然后由新RS創建新版本的Pod,然后將舊版本RS中的Pod進行刪除。如果發生回滾,就是一個逆向操作,產生一個舊版本的RS,用來生成舊版本的Pod。

    在滾動發布過程中,對於流量是轉發到新版本還是老版本的Pod中,是由商城的Service進行轉發的。

    Deployment為Pod和ReplicaSet提供了一個聲明式定義方法,典型的應用場景:

      定義Deployment來創建Pod和ReplicaSet

      滾動升級和回滾應用

      擴容和縮容

      暫停和繼續Deployment

      

   6、HPA(HorizontalPodAutoScale)

    HPA僅適用於Deployment和ReplicaSet,在V1.0版本中,僅支持根據pod的CPU利用率進行擴容縮容,在新版本中,支持根據內存和用戶自定義的metric進行擴容縮容。說的通俗一點,就是在流量突然增大,可以自動擴容,流量降下后,可以自動縮容。

  7、StatefullSet

    deployment和StatefullSet都是用來進行服務部署的,但是這兩個組件各自使用的場景不一樣,deployment是用來部署無狀態服務的,而StatefullSet是用來部署有狀態服務的。

    這里說明一下有狀態服務和無狀態服務,有狀態服務指的是需要進行實時的數據更新和存儲的服務,如果將某個服務抽離,再加入進來就沒辦法進行正常工作,例如mysql、redis等;無狀態服務指的是沒有對應數據進行更新和存儲的服務,如果將某個服務抽離,再加入進來依然可以提供服務,我們常用的業務服務一般都是無狀態服務,而docker業主要是為了無狀態服務提供部署的。

    StatefullSet應用場景包括:

      (1)穩定的持久化存儲,即pod重新調度后仍然可以訪問相同的持久化數據,基於PVC實現

      (2)穩定的網絡標志,即pod重新調度后,podName和HostName不變,基於Headless Service來實現

      (3)有序部署&有序擴展,即pod是有順序的,在部署或者擴展的時候要依據定義的順序依次進行,也就是說,從0到N-1,在下一個pod運行前,所有之前的pod都處於running和ready狀態。基於init contains實現。

      (4)有序收縮&有序刪除,即從N-1到0進行回收或刪除

    總體來說,Pod是可能隨時刪除或者新增的,一個pod也是有自己的網絡和存儲的,對於例如Mysql這類的Pod,可能不能發生網絡和存儲上的變化,StatefullSet就是為了解決這個問題而產生的。

  8、DaemonSet

    DaemonSet確保全部Node上運行一個Pod副本,當有Node加入集群時,也會為他們新增一個pod,當有Node從集群中被移除時,這些pod也會被回收,刪除DaemonSet將會刪除其創建的所有pod。最典型的場景就是每個Pod里面都有服務在運行,需要收集服務運行日志,但是Pod是由K8S自動創建或刪除的,因此需要使用DaemonSet來設定在每一個Pod中進行日志收集。

    DaemonSet的一些典型用法:

      (1)運行集群存儲Daemon,例如在每個Node上運行glustered、ceph

      (2)在每個Node上運行日志收集Daemon,例如fluentd、logstash

      (3)在每個Node上運行監控Daemon,例如Prometheus Node Exporter

    Job負責批處理任務,即僅執行一次的任務,他保證批處理任務的一個或多個pod成功結束。

  9、Volume

    數據卷,共享pod中容器使用的數據。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM