1. 程式人生 > >Kubernetes 入門之Kubernetes 的基本概念和術語

Kubernetes 入門之Kubernetes 的基本概念和術語

Kubernetes是什麼?    他是一個全新的基於容器技術分散式架構領先方案;    他也是一個開放的開發平臺;    他也是一個完備的分散式系統支撐平臺;   Kubernetes的基本慨念和術語
  • Master
      Kubernetes 裡的Master 指的是叢集控制節點,每個Kubernetes 叢集裡需要有一個 Master 節點負責整個叢集的管理和控制,基本上Kuberneter所有的控制命令都發給它,他來負責具體的執行過程,我們後面所執行的所有命令基本上都是在Master節點上執行的。Masteer通常會佔用一個獨立的伺服器(高可用部署建議用三臺伺服器);       Master節點上執行著一組關鍵程序 a). Kubernetes API Server(kube-apiserver):提供了HTTP Rest 介面的關鍵程序,是Kubernetes裡所有資源增、刪、改、查等操作的統一入口,也是叢集控制的入口程序。 b). Kubernetes Controller Manager(kub-controller-manager):Kubernetes 裡所有資源物件的自動化控制中心,可以理解為資源物件的“大總管”; c). Kubernetes Scheduer(kub-scheduler):負責資源排程(pod排程)的程序; d). Masternetes 節點上還需要啟動一個etcd服務,因為Kubernetes 上所有的資源物件全部儲存在etcd中的;
  • Node
      除了Mater節點外,Kubernetes叢集中其他機器的節點被稱為Node節點,在較早的版本中也被稱為Minion。與Master一樣,Node節點可以是一臺物理機,也可以是一臺虛擬機器。Node節點才是Kubernetes叢集中的工作負載節點,每個Node節點都會被Master分配一些工作負載(Docker容器),當某個Node宕機時,其上的工作負載會被Master節點自動轉移到其他節點上去的。      每個Node節點上都都執行著一組關鍵程序 a)kubelet:負責Pod 對應的容器的建立、啟停等任務,同時與Master 節點密切協作,實現叢集管理的基本功能。 b)kube-proxy:實現Kubernetes Server 的通訊與負載均衡機制的重要元件。 c)Docker Engine(docker):Docker 引擎,負責本機的容器建立和管理工作。      Node節點可以在執行期間動態的增加到Kubernetes叢集中,前提是這個節點上已經正確安裝、配置和啟動了上述關鍵程序,在預設的情況下kubelet會向Master註冊自己,這也是Kubernetes推薦的Node 管理方式。一旦Node 被納入叢集管理範圍,kubelet程序就會定時向Master節點彙報自身的情況,例如作業系統、Docker版本、機器的CPU和記憶體情況,以及當時有哪些Pod在執行等,這樣Master可以獲知每個Node 的資源使用情況,並實現高效均衡的資源排程策略。而某個Node 超過指定時間不上報資訊時,會被Master判定為”失聯“,Node的狀態被標記為不可用(Not Ready),隨後Master會觸發”工作負載大轉移“的自動流程。     我們可以通過執行以下命令檢視叢集中有多少個Node: # kubectl get nodes
然後通過kubectl describe node <node-name>檢視某個Node 節點的詳細資訊:
  • Pod
 Pod的基本組成:       每個Pod都有一個特殊地被稱為”根容器“的Pause的容器。Pause容器對應的映象屬於Kubernetes平臺的一部分,除了Pause容器,每個Pod還包含一個或多個緊密相關的使用者業務容器。 通過kubectl get pods檢視所有pod列表   為什麼Pod會設計出一個全新的Pod概念並且對Pod有這樣特殊的組成結構? 原因之一:在一組容器作為一個單元的情況下,我們難以對“整體”簡單地的進行判斷及有效地進行運動。比如,一個容器死亡了,此時算是整體死亡?是N/M的死亡率?引入業務無關且不易死亡的Pause容器作為Pod的根容器,以他的狀態代表整個容器組的狀態,就簡單、巧妙的解決了這個問題。 原因之二:Pod裡的uoge業務容器共享Pause容器的IP,共享Pause容器掛載的Volume,這樣既簡化了密切關聯的業務容器之間的通訊問題,也很好的解決了他們之間的檔案共享問題。   Kubernetes為每個Pod都分配了一個唯一的IP地址,稱為Pod IP,一個Pod裡的多個容器共享Pod IP地址。Kubernetes要求底層網路支援叢集內任意兩個Pod之間的TCP/IP直接通訊,這通常採用虛擬二層網路技術來實現,例如Flannel、Open vSwitch等。因此,我們需要牢記一點:在Kubernetes中,一個Pod裡的容器與另外主機上的Pod裡的容器可以直接通訊。 Pod其實有兩種型別:普通的Pod和靜態的Pod(Static Pod),後者比較特殊,他並不存放在Kubernetes的etcd儲存裡,而是存放在某個具體的Node上的一個具體的檔案中,並且只在該Node上啟動執行。而普通的Pod一旦被建立,就會被放入到etcd中儲存,隨後會被Kubernetes Master排程到某個具體的Node上進行繫結(Binding)。隨後該Pod被對應的Node上的kubelet程序例項化成一組相關的Docke容器並存儲起來。在預設情況下,當Pod裡的某個容器停止時,Kubernetes會自動檢測到這個問題並且重新啟動這個Pod(重啟Pod裡的所有容器),如果Pod所在的Node宕機,則會將這個Node節點上的所有Pod重新排程到其他Node節點上。 Pod、容器和Node的關係如下所示:  
  • Label
       Label是Kubernetes裡的另外一個核心概念。一個Label是一個key=value的鍵值對,其中key與value由使用者自己指定。Label可以附加到各種資源物件上,例如Node、Pod、Service、RC等,一個資源物件可以定義任意數量的label,同一個Label也可以被新增到任意數量的資源物件上去,Label通常在資源物件定義時被確定,也可以在物件建立後動態的新增或者刪除。         我們可以通過給指定的資源物件捆綁一個或多個不同的Label來實現多維度的資源分組管理功能,以便靈活、方便的進行資源分配、排程、配置、部署等管理工作。例如:部署不同的版本的應用到不同的環境中;或者監控和分析應用(日誌記錄、監控、告警)等。一些常用的Label標籤如下。       版本標籤:”release“:”stable“,”release“:“canary”....       環境標籤:”environment“:”dev“,”environment”:“qa”,“environment”:“producetion”       架構標籤:“tier”:“frontend”,“tier”:“backend”,“tier”:“middleware”       分割槽標籤:“partition”:“customerA”,“partition”:“customerB”....       質量管控標籤:“track”:“daily”,“track”:“weekly”               Label相當於我們熟悉的“標籤”,給某個資源物件定義一個Label,就相當於給他打了一個標籤,隨後可以通過Label Selector(標籤選擇器)查詢和篩選擁有某些Label的資源物件,Kubernetes通過這種方式實現了類似SQL的簡單又通用的物件查詢機制。        Label Selector 可以類比為SQL語句中的where查詢條件,例如,name=redis-slave這個Label Selector 作用於Pod時,可以類比為select * from pod where pod_name = 'redis-slave'這樣的語句。當前者有兩種不同的Label Selector 的表示式:基於等式的(Equality-based)和基於集合的(Set-based),前者採用“等式類”的表示式匹配標籤,下面是一些具體的例子。       name = redis-server:匹配所有具有標籤 nameredis-server的資源物件。       env != production:匹配所有不具有標籤 env=prouction 的資源物件。 而後者則使用集合操作的表示式匹配標籤,下面是一些具體的例子。       name in (redis-master,redis-slave):匹配所有具有標籤的nameredis-master或者nameredis-slave的資源物件。       name not in (php-frontend) :匹配所有不具有標籤namepho-frontend的資源物件。 可以通過多個Label Selector 表示式的組合實現複雜的條件選擇,多個表示式之間用“,”進行分割,幾個條件之間是“and”的關係,即同時滿足多個條件,比如下面的例子:      name = redis-server,env != production   Label Selector 在Kubernetes 中的重要使用場景有以下幾處。     a)kube-controller 程序通過資源物件RC上定義的Label Selector 來篩選要監控的Pod副本的數量,從而實現Pod副本的數量始終負荷預期設定的全自動流程控制。    b) kueb-proxy 程序通過Service 的 Label Selector 來選擇對應的Pod,自動建立起每個Service到對應Pod的請求轉發路由表,從而實現Servicce的智慧負載均衡機制。     c)通過對某些Node 定義特定的Label,並且在Pod定義檔案中使用NodeSelector這種標籤排程策略,kube-scheduler程序可以實現Pod定向排程的策略。   總結:使用Label 可以給物件建立更多組標籤,Label 和 Label Selector 共同構成了Kubernetes 系統中最核心的應用模型,使得被管理者物件能夠被精細地分組管理,同時實現了整個叢集的高可用性。
  • Replication Controller
     Replication Controller (簡稱RC),RC是Kubernetes的核心概念之一,簡單地說,他其實是定義了一個期望的場景,即聲明瞭某種Pod的副本的數量在任意時刻都符合某個預期值,所有RC的定義包括以下幾個部分:     a)Pod期待的副本數(replicas)     b)用於篩選目標Pod的Label Selector。     c)當Pod的副本數量小於預期值時,用於建立新Pod的Pod 模板(template)。        當我們定義了一個RC並提交到Kubernetes叢集中以後,Master節點上的Controller Manager元件就會收到通知,定期巡檢系統當中的當前存活的目標Pod,並確保目標Pod例項數量剛好等於此RC的期望值,如果有過多的Pod副本在執行,系統就會停掉一些Pod,否則系統就會再手動建立一些Pod。可以說,通過RC,Kubernetes實現了使用者應用叢集的高可用性,並且大大減少了系統管理員再傳統IT環境中需要手動完成的許多運維工作(如主機監控指令碼、應用監控指令碼、故障恢復指令碼等)。 ----通過RC,Kubernetes很容易就實現了這種高階實用的特性,被稱為“滾動升級”,具體的操作方法以後在做分析。 由於Replication Controller 與 Kubernetes程式碼中的模組Replication Controller同名,同時這個詞也無法準確表達他的本意,所以在Kubernetes v1.2時,他就升級成了另外一個概念-------Replica Set,官方解釋為“下一代的RC”,它與RC當前存在的唯一區別是:Replica Set支援基於集合的Label Selector(Set-based selector),而RC只支援基於等式的Label Selector(equality-based selector),這使得Replica Set的功能更強。     kubectl命令列使用與RC的絕大部分命令同樣也適用於Replica Set。此外,當前我們很少單獨使用Replica Set,它主要是被Deployment這個更高層級的資源物件所使用,從而形成一套完整的Pod建立、刪除、更新的編排機制。當我們使用Deplyment時,無須關心他說如何建立和維護Replica Set的,這一切都是自動發生的。     Replica Set和Deployment這兩個重要的資源物件逐步替換看之前的RC的作用,時Kubernetes v1.3裡的Pod自動擴容(伸縮)這個告警功能實現的基礎,也將繼續在Kubernetes未來的版本中發揮重要作用。     總結RC(Replica Set)的一些特性和作用。      a)在大多數情況下,我們通過定義一個RC實現Pod的傳教過程及副本數量的自動過程。      b)RC裡包含完整的Pod定義模板。      c)RC通過Label Selector機制實現對Pod副本的自動控制。      d)通過改變RC裡的Pod的副本數量,可以實現Pod的擴容與縮容功能。      e)通過改變RC裡Pod模板的映象版本,可以實現Pod的滾動升級功能。  
  • Deployment
     Deployment 是Kubernetes v1.2引入的概念,引入的目的是欸藍更好的解決Pod的編排問題。為此,Deployment 在內部使用了 Replica Set 來實現目的的,無論從Deployment 的作用與目的、它的YAML定義,還是從它的具體命令列操作來看,我們都可以把它看作RC的一次升級,兩者的相似度超過90%。        Deployment相對於RC的最大一個升級時我們可以隨時知道當前Pof“部署”的進度。實際上由於一個Po的建立、排程、繫結節點及在目標Node上啟動對應的的容器這一完整的過程需要一定的時間,所以我們期待系統啟動N個Pod副本的目標狀態,實際上是一個連續變化的“部署過程”導致的最終狀態。       Deployment典型使用場景有以下幾個:      a)建立一個Deployment物件來生成對應的Replica Set 並完成Pod副本的建立過程。      b)檢查Deployment的狀態來看部署動作是否完成(Pod副本的數量是達到預期的值)。      c)更新Deployment以建立新的Pod(比如映象升級)。      d)如果當前Deployment不穩定,則回滾到一個早先的Deployment版本。      e)暫停Deployment 以便一次性修改多個PodTemplateSpec 的配置項,之後再恢復Deployment,進行新的釋出。      f)擴充套件Deployment以應對高負載。      g)檢視 Deployment 的狀態,以此作為釋出是否成功的標誌。      h)清理不再需要的舊的 ReplicaSets。      執行下面命令可以檢視 Deployment 的資訊    kubectl  get deployments     Pod 的管理物件,除了RC和Deployment,還包括ReplicaSet、DaemonSet、StatefulSet、Job等,分別用於不同的業務場景,具體以後再分析。
  • Horizontal Pod Autoscaler
          以往我們通過手動執行kubectl scale 命令,我們可以實現Pod擴容和縮容。如果僅僅至此為止,顯然不符合谷歌對Kubernetes 的定位目標----自動化、智慧化。再谷歌看來,分散式系統要能夠根據當前負載的變化情況觸發水平擴充套件或縮容的行為,因為這一過程可能是頻繁發生的、不可預料的,所以手動控制的方式是不現實的。
  • StatefulSet
        在Kubernetes 中,Pod 的管理物件RC、Deployment、DaemonSet和job都是面向無狀態的服務。但是現實中有很多服務是由狀態的,特別是一些負載的中介軟體叢集,例如MYsQL叢集、MongoDB叢集、Akka叢集、Zookeeper叢集等,這些應用叢集都有以下一些特點。         a) 每個節點都有固定的省份ID,通過這個ID,叢集中的成員可以相互發現並通訊。      b) 叢集的規模是比較固定的,叢集規模不能隨意的變動。      c)  叢集裡的每個節點都是有狀態的,通常會持久化資料到永久儲存中。      d)  如果磁碟損壞,則叢集裡的某個節點無法正常執行,叢集功能受損。 如果用RC/Deployment控制Pod副本數的方式來實現上述有狀態的叢集,則我們會發現第一點是無法滿足的,因為Pod的名字是隨機產生的,Pod的ID地址也是在執行期才確定是否有變動的,我們事先無法為每個Pod確定一個唯一不便的ID,另外,為了能夠在其他節點上恢復這個失敗的節點,這中叢集中的Pod需要掛接某種共享儲存,為了解決這個問題,Kubernetes v1.4版本開始引入PetSet 這個新的資源物件,並且在 v1.5版本時更名為StatefulSet,StatefulSet從本質上來說,可以看著是Deployment/RC的一個特殊變種,它有如下的一些特性:       a)StatefulSet 裡的每一個Pod 都有穩定、唯一的網路標識,可以用來發現叢集內的其他成員。假設StatefulSet的名字叫kafka,那麼第一個Pod叫kafka-0,第二個叫kafka-1,以此類推。       b)StatefulSet 控制的Pod副本的啟停順序是受控的,操作第n個Pod時,前n-1 個Pod已經是執行且準備好的狀態。       c)StatefulSet 裡的Pod 採用穩定的持久化儲存卷,通過PV/PVC來實現,刪除Pod 時預設不會刪除與StatefulSet相關的儲存卷(為了保證資料的安全)。  
  • Service
         Kubernetes 裡的每個Servcice 其實就是我們經常提到的微服務架構中的一個“微服務”,之前我們所說的Pod、RC等資源物件其實都是為這節所說的“服務”-----Kubernetes Service作“嫁衣”的。 後面會單獨針對Service做講解,這裡首先知道有這麼一個物件存在就行。
  • Volume(儲存卷)
          Volume 是Pod 中能夠被多個容器訪問的共享目錄。Kubernetes 的 Volume 概念、用途和目的與Docker的Volume比較相似,但兩者不能等價。首先,Kubernetes中的Volume定義在Pod上,然後被一個Pod裡的多個容器掛載到具體的檔案目錄下;其次,Kubernetes中的Volume與Pod的生命週期相同,但是與容器的生命週期不相關,當容器終止或重啟時,Volume中的資料也不會丟失。最後,Kubernetes支援多種型別的Voume,例如 ClusterFS、Geph等先進的分散式檔案系統。            Kuberneter 提供了非常豐富的Volume 型別:                1.emptyDir                2.hosyPath                3.gcePersistentDisk                4.awsElasticBlockStore                5.NFS  
  • Persistent Volume
           前面我們說的Volume是定義在Pod上的,屬於“計算資源”的一部分,而實際上。“網路儲存”是相對獨立於“計算資源”而存在的一種實體資源。比如在使用虛擬機器的情況下,我們通常會先定義一個網路儲存,然後從中劃出一個“網盤”並接到虛擬機器上。Persistent Volume (簡稱 PV)和與之相關的 Persistent Volume Claim (簡稱 PVC)也起到了類似的作用。     PV可以理解成是 Kubernetes 叢集中的某個網路儲存中對應的一塊儲存,他與 Volume 很類似,但又以下區別:  a)PV只能是網路儲存,不屬於任何 Node,但可以在每個 Node 上訪問。  b)PV 並不是定義在 Pod 上的,而是獨立於 Pod 之外定義的。  c)PV 目前支援的型別有:gcePersistentDisk、awsElasticBlockStore、AzureFile、AzureDisk、FC(Fibre Channel)、Flocker、NFS、iSCSI....等等,這裡就不一一例舉了。       PV 是有狀態的物件,它有以下幾種狀態:      a)Available:空閒狀態。      b)Bound:已經繫結到某個 PVC 上。      c)Released:對應的PVC 已經刪除,但資源還沒被叢集回收。      d)Failed:PV 自動回收失敗。
  •  Namespace(名稱空間)
        Namespace(名稱空間)是Kubernetes 系統中一個非常重要的概念,Namespace在很多情況下用於實現多租戶的資源隔離。Namespace 通過將叢集內部的資源物件“分配”到不同的Namespace 中,形成邏輯上分組的不同專案、小組或使用者組,便於不同的分組在共享使用整個叢集的資源的同時還能被分別管理。        Kubernetes 叢集在啟動後,會建立一個名為“default”的Namespace,通過 kubectl可以查到:       kubectl get namespace:
  • Annotation
      Annotation於 Label 類似,也使用key/value 鍵值對的形式進行定義。不同的是Label 具有嚴格的命名規範,它的定義是 Kubernetes 物件的元資料(Metadata),並且用於 Label Selector。而 Annotation 則是任意定義的“附加”資訊,以便外部工具進行查詢,很多時候 Kubernetes 的模組自身會通過 Annotation 的方式標記資源物件的一些特殊資訊。通常來說,用Annotation 來記錄的資訊如下:     a)build資訊、release資訊、Docker映象資訊等,例如時間戳、release id 號、PR 好、映象 hash值、docker registry 地址等。     b)日誌庫、監控庫、分析庫等資源庫的地址資訊。     c)程式調式工具資訊,例如工具名稱、把本號等。     d)團隊的聯絡資訊,例如電話號碼、負責人名稱、網址等。   小結      上述這些元件是Kubernetes 系統的核心元件,他們共同組成了 Kubernetes 系統的框架和計算模型。除了上述所介紹的核心元件,在Kubernetes 中還有許多輔助配置的資源物件,例如LimitRange、ResourceQuota。另外,一些系統內部使用的物件 Binging、Event等參考Kubernetes的API文件。