本文已參與好文召集令活動,點擊查看:後端、大前端雙賽道投稿,2萬元獎池等你挑戰!前端
在開始使用以前,應當先了解一下關於Kubernetes
的相關概念術語,對後續的學習、使用將有很大的幫助。(Kubernetes
的概念比較多,建議增強理解,並清楚各類所處位置及關聯!)node
Kubernetes
中的大部分概念,如:Node
、Pod
、Replication Controller
、Service
等均可以看做是一種資源對象,幾乎全部資源對象均可以經過Kubernetes
提供的kubectl
工具(或者API接口)執行增、刪、改、查等操做並將其保存在etcd
中持久化存儲。linux
從這個角度來看,Kubernetes
實際上是一個高度自動化的資源控制系統,它經過跟蹤對比etcd
庫裏保存的「資源指望狀態」與當前環境中的「實際資源狀態」的差別來實現自動控制和自動糾錯的高級功能。redis
本文將介紹Kubernetes
中重要的資源對象,即:Kubernetes
的基本概念和術語。docker
Master
是指Kubernetes
集羣中的控制節點(Master Node),在每一個Kubernetes
集羣裏都須要有一個Master
來負責整個集羣的管理和控制,基本全部的控制命令都發給它,它負責具體的執行過程,後續執行的全部命令基本都是在Master
上運行。後端
Master
提供集羣的獨特視角,而且擁有一系列組件,好比Kubernetes API Server
。API Server
提供能夠用來和集羣交互的REST端點。能夠經過命令行或圖形化界面來維護pod、副本和服務。api
在Master上包括如下組件:安全
etcd: 分佈式key-value存儲,保存集羣的狀態數據、資源對象數據。服務器
API Server(kube-api-server
): Kubernetes提供的HTTP Rest接口,是全部資源的增、刪、改、查等操做的惟一入口,也是集羣控制的入口進程。markdown
Controllers(kube-controller-manager
): Kubernetes裏全部資源對象的自動化控制中心。
Scheduler(kube-scheduler
): 負責資源調度(Pod調度)的進程,至關於公交公司的"調度室"。
除了Master,Kubernetes集羣中的其餘集羣被稱爲Node
,即:Worker Node(工做節點)。與Master同樣,Node能夠是一臺物理主機,也能夠是一臺虛擬機。
Node
是Kubernetes集羣中的工做負載節點,每一個Node都會被Master分配一些工做負載,當某個Node宕機時,其上的工做負載會被Master自動轉移到其餘節點上。
每一個Node上都運行着如下關鍵組件:
kubelet
: 負責Pod對應的容器建立、啓停等任務,同時與Master密切協做,實現集羣管理的基本功能。kube-proxy
: 實現Kubernetes Service的通訊與負載均衡機制的重要組件。Node
能夠再運行期間動態增長調整到Kubernetes集羣中,默認狀況下kubelet會向Master註冊本身。一旦Node被歸入集羣管理範圍,kubelet進程就會定時向Master上報本身的信息,如操做系統、Docker版本、機器CPU和內存、以及當前有哪些Pod在運行等,這樣Master就能夠獲知每一個Node的資源使用狀況,並實現高效均衡的資源調度策略。而某個Node在超過指定時間不上報信息時,會被Master斷定爲「失聯」狀態,標記爲不可用(Not Ready),隨後Master會觸發「工做負載大轉移」的自動流程。
執行命令kubectl get nodes
能夠查看在集羣中有多少個Node:
[xcbeyond@localhost ~]$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready master 17d v1.19.0
複製代碼
而後經過kubectl describe node <node_name>
查看某個Node的詳細信息:
[xcbeyond@localhost ~]$ kubectl describe node minikube
Name: minikube
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=minikube
kubernetes.io/os=linux
……
複製代碼
Pod
是Kubernetes中的原子對象,是基本構建單元。
Pod
表示集羣上一組正在運行的容器。一般建立Pod是爲了運行單個主容器。Pod 還能夠運行可選的sidecar容器,以實現諸如日誌記錄之類的補充特性。(如:在Service Mesh中,和應用一塊兒存在的istio-proxy
、istio-init
容器)
一般用Deployment來管理Pod。
一個Pod
中能夠包含多個容器(其餘容器做爲功能補充),負責處理容器的數據卷、祕鑰、配置。
以下圖所示是Pod
的組成示意圖,咱們能夠看到每一個Pod
都有一個特殊的被稱爲「根容器」的Pause容器。Pause容器對應的鏡像屬於Kubernetes平臺的一部分,除了Pause容器,每一個Pod還包含一個或多個緊密相關的用戶業務容器。
爲何Kubernetes會設計出一個全新的Pod概念,而且Pod要有這樣特殊的組成結構?
在一組容器做爲一個單元總體的狀況下,咱們難以對「總體」簡單地進行判斷及有效地進行控制。好比,一個容器死亡了,此時算是總體死亡麼?引入業務無關而且不易死亡的Pause容器做爲Pod的根容器,以它的狀態表明總體容器組的狀態,就簡單、巧妙地解決了這個難題。
Pod裏的多個業務容器共享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進程實例化成一組相關的Docker容器而且啓動起來。
在默認狀況下,當Pod裏的某個容器中止時,Kubernetes會自動檢測到這個問題而且從新啓動這個Pod(重啓Pod裏的全部容器),若是Pod所在的Node宕機,則會將這個Node上的全部Pod從新調度到其餘節點上。Pod、容器與Node的關係圖以下圖所示。
Pod 的生命週期是不肯定的,可能很是短暫,但 Pod 具備很強的再生能力,在死後能夠自動從新啓動(重啓機制)。Pod生命週期整個過程當中,一般可能處於如下五個階段之一:
Pending
: Pod定義正確,提交到Master,但其所包含的容器鏡像還未徹底建立。一般,Master對Pod進行調度須要一些時間,Node進行容器鏡像的下載也須要一些時間,啓動容器也須要必定時間。
Running
: Pod已經被分配到某個Node上,而且全部的容器都被建立完畢,至少有一個容器正在運行中,或者有容器正在啓動或重啓中。
Succeeded
: Pod中全部的容器都成功運行結束,而且不會被重啓。這是Pod的一種最終狀態。
Failed
: Pod中全部的容器都運行結束了,其中至少有一個容器是非正常結束的(exit code不是0)。這也是Pod的一種最終狀態。
Unknown
: 沒法得到Pod的狀態,一般是因爲沒法和Pod所在的Node進行通訊。
Label
(標籤)是Kubernetes中另一個核心概念。一個Label是一個key=value的鍵值對,其中key與value由用戶本身指定。Label能夠被附加到各類資源對象上,例如Node、Pod、Service、RC等,一個資源對象能夠定義任意數量的Label,同一個Label也能夠被添加到任意數量的資源對象上。Label一般在資源對象定義時肯定,也能夠在對象建立後動態添加或刪除。
通常來講,咱們會給指定的資源對象定義多個label,來實現多維度的資源分組管理,以便靈活、方便地進行資源分配、調度、配置、部署等管理工做。例如:部署不一樣版本的應用到不一樣的環境中,或者監控和分析應用(日誌記錄,監控,報警等)。一些經常使用的Label示例以下:
release:stable
、release: canary
environment: dev
、environemnt: qa
、environment: production
tier: frontend
、tier: backend
、tier: middleware
某個資源對象定義了Label後,能夠經過Label Selector(標籤選擇器)查詢和篩選Label的資源對象,Kubernetes經過這種方式實現了相似SQL的對象查詢機制。
一般咱們經過描述文件中的spec.selector
字段來指定Label,從而Kubernetes尋找到全部包含你指定Label的對象,進行管理。
Kubernetes目前支持兩種類型的Label Selector:
使用Label
能夠給對象建立一組或多組標籤,Label
和Label Selector
共同構成了Kubernetes系統中最核心的應用模型,使得對象可以精細分組、管理,同時實現了集羣的高可用性。
Replication Controller
,簡稱RC,是Kubernetes中核心概念之一,定義了一個指望的場景,即:聲明某種Pod的副本數量在任意時刻都符合某個預期值。
RC的定義包括如下幾個部分:
下面以有3個Node的集羣爲例進行,說明Kubernetes如何經過RC來實現Pod副本數量自動控制的機制。
假如在咱們的RC裏定義redis-slave這個Pod須要保持2個副本,系統將可能在其中的兩個Node建立Pod,以下圖所示:
假如Node 2上的Pod意外終止,則根據RC定義的replicas數量2,Kubernetes將自動建立並啓動一個新的Pod,以保證整個集羣中始終有兩個redis-slave運行。以下圖所示,Kubernetes可能選擇Node 3或者Node 1來建立一個新的Pod。
此外,在運行時,咱們能夠經過修改RC的副本數量,來實現Pod的動態縮放(Scaling),可經過執行kubectl scale rc redis-slave --replicas=3
命令一鍵完成。執行結果示意以下圖所示:
注意:刪除RC並不會影響經過該RC建立好的Pod。 刪除全部Pod,能夠設置replicas的值爲0,而後更新該RC。另外,kubectl也提供了stop和delete命令來一次性刪除RC和RC控制的所有Pod。
最後,總結一下RC的特性和做用:
Deployment
是Kubernetes在1.2版本中引入的新概念,用於更好地解決Pod的編排問題。爲此,Deployment
在內部使用了Replica Set來實現,不管從Deployment的做用、YAML定義,仍是從它的具體命令行操做來看,咱們均可以把它看做是RC的一次升級。
Deployment
相對於RC的一個最大升級是咱們能夠隨時知道當前Pod部署的進度。
典型使用場景:
在Kubernetes中,Pod的管理對象RC、Deployment、DaemonSet和Job都是面向無狀態的服務。但現實中有不少服務是有狀態的,特別是一些複雜的中間件集羣,例如MySQL集羣、MongoDB集羣、Kafka集羣、Zookeeper集羣等,這些應用集羣有如下一些共同點。
若是用RC或Deployment控制Pod副本數的方式來實現上述有狀態的集羣,則咱們會發現第一點是沒法知足的,由於Pod的名字是隨機產生的,Pod的IP地址也是在運行期才肯定且可能有變更的,咱們事先沒法爲每一個Pod肯定惟一不變的ID,爲了可以在其餘節點上恢復某個失敗的節點,這種集羣中的Pod須要掛接某種共享存儲,爲了解決這個問題,Kubernetes從v1.4版本開始引入了PetSet這個新的資源對象,而且在v1.5版本時改名爲StatefulSet
,StatefulSet
從本質上來講,能夠看做Deployment/RC的一個特殊變種,它有以下一些特性。
StatefulSet
除了要與PV卷捆綁使用以存儲Pod的狀態數據,還要與Headless Service配合使用,即在每一個StatefulSet
的定義中要聲明它屬於哪一個Headless Service。Headless Service與普通Service的關鍵區別在於,它沒有Cluster IP,若是解析Headless Service的DNS域名,則返回的是該Service對應的所有Pod的Endpoint列表。StatefulSet在Headless Service的基礎上又爲StatefulSet控制的每一個Pod實例建立了一個DNS域名,這個域名的格式爲:
$(podname).$(headless service name)
好比一個3節點的Kafka的StatefulSet集羣,對應的Headless Service的名字爲kafka,StatefulSet的名字爲kafka,則StatefulSet裏面的3個Pod的DNS名稱分別爲kafka-0.kafka、kafka-1.kafka、kafka-3.kafka,這些DNS名稱能夠直接在集羣的配置文件中固定下來。
Service
也是Kubernetes裏的最核心的資源對象之一,Kubernetes裏的每一個Service其實就是咱們常常提起的微服務架構中的一個「微服務」,上面咱們所說的Pod、RC等資源對象其實都是爲講解Kubernetes Service作鋪墊的。下圖顯示了Pod、RC與Service的邏輯關係。
從圖中咱們看到,Kubernetes的Service定義了一個服務的訪問入口地址,前端的應用(Pod)經過這個入口地址訪問其背後的一組由Pod副本組成的集羣實例,Service與其後端Pod副本集羣之間則是經過Label Selector來實現「無縫對接」的。而RC的做用其實是保證Service的服務能力和服務質量始終處於預期的標準。
Job
(批處理任務)經過並行或串行啓動多個進程去處理一批工做,在處理完成後,整個批處理任務結束。從Kubernetes 1.2版本開始,支持批處理類型的應用,能夠經過Kubernetes Job這種新的資源對象定義並啓動一個批處理任務Job。與RC、Deployment、ReplicaSet相似,Job也是用來控制一組Pod容器。
Job
負責批量處理短暫的一次性任務 ,即僅執行一次的任務,它保證批處理任務的一個或多個Pod成功結束。
Volume
(存儲卷)是Pod中可以被多個容器訪問的共享目錄。Kubernetes的Volume概念、用途和目的與Docker的Volume比較相似,但二者不能等價。首先,Kubernetes中的Volume定義在Pod上,而後被一個Pod裏的多個容器掛載到具體的文件目錄下;其次,Kubernetes中的Volume中的數據也不會丟失。最後,Kubernetes支持多種類型的Volume,例如Gluster、Ceph等先進的分佈式文件系統。
Namespace
(命名空間)是Kubernetes系統中的另外一個很是重要的概念,Namespace在不少狀況下用於實現多租戶的資源隔離。Nameaspace經過將集羣內部的資源對象「分配」到不一樣的Namespace中,造成邏輯上分組的不一樣項目、小組或用戶組,便於不一樣的分組在共享使用整個集羣的資源的同時還能被分別管理。
Kubernetes集羣默認會建立一個名爲default的Namespace,經過kubectl
能夠查看:
[xcbeyond@bogon ~]$ kubectl get namespaces
NAME STATUS AGE
default Active 23d
istio-system Active 22d
kube-node-lease Active 23d
kube-public Active 23d
kube-system Active 23d
kubernetes-dashboard Active 23d
複製代碼
若是不特別指定Namespace,則用戶建立的Pod、RC、Service等都將建立到默認的default的Namespace中。
Annotation
(註解)與Label相似,也使用key/value鍵值對的形式進行定義。不一樣的是Label具備嚴格的命名規則,它定義的是Kubernetes對象的元數據(Metadata),而且用於Label Selector。而Annotation
則是用戶任意定義的「附加」信息,以便於外部工具進行查找,不少時候,Kubernetes的模塊自身會經過Annotation的方式標記資源對象的特殊信息。
一般來講,用Annotation
來記錄的信息以下:
爲了可以準確、深入理解Kubernetes ConfigMap
的功能和價值,能夠先從Docker提及。咱們都知道,Docker經過將程序、依賴庫、數據及配置文件等「打包固化」到一個不變的鏡像文件,以解決因應用部署差別的難題,但這同時帶來了另外一個棘手的問題,即:配置文件中的參數在運行期間如何修改的問題。爲了解決這個問題,Docker提供瞭如下兩種方式:
在大多數狀況下,咱們更傾向於後一種方式,應該大多數應用一般擁有多個參數,配置文件映射的方式簡潔。但這種方式也有明顯的缺陷:必須事先在宿主機上建立好配置文件,而後容器啓動時纔可以映射到容器裏。
若是在分佈式系統中,就會變得更加糟糕,多臺宿主機上建立相同的配置文件,而且要確保這些配置文件的一致性,是很難實現的。爲此,Kubernetes引入了ConfigMap
,巧妙的解決了這種問題。
把全部的配置項都看成key-value字符串,如:配置項host=192.168.1.一、user=root、password=123456用於表示鏈接FTP服務器的配置參數。這些配置項做爲Map表中的一項,整個Map的數據被持久化存儲在Kubernetes的etcd中,並提供API方便Kubernetes相關組件或應用CRUD操做,這裏用來保存配置參數的Map就是Kubernetes ConfigMap資源對象。
ConfigMap機制: 將存儲在etcd中的ConfigMap經過Volume映射方式變爲目標Pod內的配置文件,無論目標Pod被調度到哪臺服務器上,都會自歐東完成映射。若是ConfigMap中的key-value數據被修改,則映射到Pod中的「配置文件」也會隨之自動更新。因而,ConfigMap就造成了分佈式系統中最爲簡單且對應用無侵入的配置中心。
上述的這些概念術語也是Kubernetes的核心組件,它們共同構成了Kubernetes的框架和計算模型。經過對它們進行靈活組合,用戶就能夠快速、方便地對容器集羣進行配置、建立和管理。除了本文介紹的概念外,Kubernetes中還有許多其餘的概念,用於輔助配置資源對象,如:LimitRange、ResourceQuota等,更多概念術語可參照官方術語表:kubernetes.io/zh/docs/ref…