Chapter 8. Kubernetes Building BlocksIntroduction and Learning Objectives
在本章中,我們將探討Kubernetes物件模型,並討論它的一些基本構建塊,如Pods、ReplicaSets、Deployments、Namespaces等。我們還將討論Labels和Selectors在微服務驅動的體系結構中扮演的重要角色,因為它們將分離的物件組合在一起。
Kubernetes Building BlocksKubernetes Object ModelKubernetes有一個非常豐富的物件模型,表示Kubernetes叢集中不同的持久實體。這些實體描述:
我們在哪個節點上執行哪些容器化應用程式應用程式資源消耗情況附加到應用程式的不同策略,如重新啟動/升級策略、容錯等。對於每個物件,我們在spec部分宣告我們的意圖或期望的狀態。Kubernetes系統管理物件的status部分,其中記錄了物件的實際狀態。在任何給定的時間點上,Kubernetes控制平臺都會嘗試將物件的實際狀態與物件的期望狀態相匹配。Kubernetes物件有Pods、ReplicaSets、Deployments、Namespaces等,我們將在下一步對它們進行探討。
建立物件時,必須將spec欄位下面物件的配置資料部分提交給Kubernetes API Server。spec部分描述了目標狀態以及一些基本資訊,比如物件的名稱。建立物件的API請求必須包含spec部分以及其他詳細資訊。儘管API伺服器接受JSON格式的物件定義檔案,但我們通常以YAML格式提供這些檔案,kubectl將這些檔案轉成JSON並將其傳送到API伺服器。
下面是YAML格式的部署物件配置示例:
apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deployment labels: app: nginxspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.15.11 ports: - containerPort: 80apiVersion是第一個必填欄位,它指定API伺服器上的我們想要連線到的API端點,它必須與已定義的物件型別的現有版本匹配。第二個必需欄位是kind,指定物件型別——在我們的示例中是Deployment,但它可以是Pod、Replicaset、Namespace、Service等。第三個必需欄位metadata儲存物件的基本資訊,如name, labels, namespace等。我們的示例顯示了兩個spec欄位(spec和spec.template.spec)。第四個必需的欄位spec標記定義部署物件所需狀態的塊的開始。在我們的例子中,我們希望在任何給定的時間確保執行3個pod。Pods是使用spec.Template中定義的Pods模板建立的。巢狀的物件(如作為部署一部分的Pod)將保留其metadata和spec,但去掉apiVersion和kind——兩者都將被template替換。在spec.template.spec中,我們定義了Pod的期望狀態。我們的Pod建立了一個執行來自Docker Hub的nginx:1.15.11映象的容器。一旦建立了部署物件,Kubernetes系統就會將status欄位附加到該物件;我們稍後將對其進行研究。接下來,我們將更深入地研究一些Kubernetes物件以及其他組成部分。
PodsPod是最小最簡單的Kubernetes物件。它是Kubernetes中的部署單元,表示應用程式的單個例項。Pod是一個或多個容器的邏輯集合,容器有如下特點:
一個/多個Container與Pod編排在同一主機上共享相同的網路名稱空間訪問相同的外部儲存(卷)。Pods是一個或多個容器的集合
事實上Pod是短暫的,它們沒有自我恢復能力。這就是為什麼它們需要與處理Pod的複製、容錯、恢復等的控制器一起使用。控制器有Deployments, ReplicaSets, ReplicationControllers等。我們使用Pod模板將巢狀Pod的spec附加到控制器物件,如前一節所示。
下面是YAML格式的Pod物件配置示例:
apiVersion: v1kind: Podmetadata: name: nginx-pod labels: app: nginxspec: containers: - name: nginx image: nginx:1.15.11 ports: - containerPort: 80apiVersion欄位為Pod物件定義指定"v1"。第二個必需欄位是指定Pod物件型別的kind。第三個必需的欄位元資料包含物件的名稱和標籤。第四個必需的欄位spec定義Pod物件所需狀態,也稱為Pod spec。我們的Pod建立了一個執行來自Docker Hub的nginx:1.15.11 映象的容器。
LabelsLabel是附加到Kubernetes物件(例如Pods、ReplicaSets)的鍵值對。標籤用於根據現有需求組織和選擇物件的子集。許多物件可以具有相同的標籤。標籤不能為物件提供唯一性。控制器使用標籤將分離的物件邏輯地組合在一起,而不是使用物件的名稱或id。
在上圖中,我們使用了兩個Label的Key:app和env。根據我們的要求,我們給了四個吊艙不同的價值。Label env=dev在邏輯上選擇並分組前兩個pod,而Lable app=frontend在邏輯上選擇並分組左兩個pod。我們可以從左下角的四個pod中選擇一個,方法是使用兩個標籤:app=frontend和env=qa。
Label SelectorsControllers使用標籤選擇器選擇物件的子集。Kubernetes支援兩種型別的選擇器:
基於等式的選擇器基於相等的選擇器允許基於標籤鍵和值篩選物件。使用=,(等於,可替換使用)或!=(不等於)運算子實現匹配。例如,對於envdev或env=dev,我們選擇env Label鍵設定為value dev的物件。基於集合的選擇器基於集合的選擇器允許基於一組值篩選物件。我們可以使用In,NOTIN操作符中篩選標籤Value,以及用exist/not exist操作符篩選標籤的Key。例如,使用env in(dev,qa),我們選擇env標籤設定為dev或qa的物件; !app選擇沒有標籤app的物件應用程式。ReplicationControllers雖然不再推薦,但ReplicationController是一種控制器,它可以用於確保在任何給定時間執行指定數量的Pod副本。如果pod多於所需數量,則ReplicationController將終止額外的pod;如果pod較少,則複製控制器將建立更多的pod以匹配所需數量。通常,我們不會獨立部署Pod,因為如果因為錯誤終止,它將無法自己重新啟動。推薦的方法是使用某種型別的ReplicationController來建立和管理pod。預設控制器是一個Deployment ,它將配置ReplicaSet 為管理Pods的生命週期。
ReplicaSets IReplicaSet是下一代複製控制器。replicationset支援基於等式和集合的選擇器,而replicationcontroller只支援基於等式的選擇器。目前,這是唯一的區別。在ReplicaSet的幫助下,我們可以擴充套件執行特定容器應用程式映像的pod的數量。縮放可以手動完成,也可以通過使用autoscaler完成。接下來,您可以看到一個replicaSet的圖形表示,我們將Pod的replicas count設定為3。
ReplicaSets II現在,讓我們繼續同一個示例,假設其中一個pod被強制終止(由於資源不足、超時等),並且當前狀態不再與所需狀態匹配。
ReplicaSets IIIReplicaSet將檢測到當前狀態不再與所需狀態匹配。ReplicaSet將建立一個額外的Pod,從而確保當前狀態與所需狀態匹配。
ReplicaSet可以獨立用作Pod控制器,但它們只提供有限的一組功能。Deployment提供了一組補充功能,這是pod編排的推薦控制器。Deployment管理pod的建立、刪除和更新。Deployment會自動建立一個ReplicaSet,然後建立一個Pod。不需要單獨管理ReplicaSet和pod,Deployment將代表我們管理它們。下一步我們將更仔細地研究Deployment。
Deployments IDeployment物件為pod和ReplicaSet提供宣告性更新。DeploymentController是master node的控制器管理器的一部分,它確保當前狀態始終與所需狀態匹配。它允許通過rollouts和rollbacks無縫地更新和降級應用程式,並直接管理其ReplicaSet以進行應用程式擴充套件。在下面的示例中,一個新的Deployment建立了ReplicaSet A,然後它建立了3個Pod,每個Pod模板配置為執行一個nginx:1.7.9容器映像。在本例中,ReplicaSetA與nginx:1.7.9相關聯,nginx:1.7.9表示部署的狀態。此特定狀態記錄為修訂版1。
Deployments II現在,在Deployment中,我們更改了Pods的Template,並將容器映像從nginx:1.7.9更新為nginx:1.9.1。部署為1.9.1版本的新容器映像觸發新的ReplicaSet B,此關聯表示部署的新記錄狀態,版本2。這兩個ReplicaSet之間的無縫轉換是Deployment滾動更新,從帶有3個Pods版本1.7.9的ReplicaSet A到帶有3個Pods版本1.9.1的新ReplicaSet B,或者說從修訂版1到修訂版2。當我們為Deployment更新Pods Template時,會觸發滾動更新。scaling或labeling等操作不會觸發滾動更新,因此不會更改修訂號。一旦滾動更新完成,Deployment將同時顯示ReplicaSets A和B,其中A被縮放為0 pod,B被縮放為3 pod。這就是Deployment如何將其先前的狀態配置設定記錄為修訂版的方式。
Deployments III一旦ReplicaSet B及其版本為1.9.1的3個Pods準備就緒,Deployments就開始積極地管理它們。但是,Deployment將其先前的配置狀態儲存為歷史修訂版,修訂版在Deployment的回滾功能中起著關鍵作用—返回到先前已知的配置狀態。在我們的示例中,如果新nginx:1.9.1的效能不令人滿意,則可以將部署回滾到以前的版本,在本例中,從版本2回滾到執行nginx:1.7.9的版本1。
Namespaces
如果多個使用者和團隊使用同一個Kubernetes叢集,我們可以使用名稱空間將叢集劃分為虛擬子叢集。在名稱空間中建立的資源/物件的名稱是唯一的,但在群集中的名稱空間中不是唯一的。要列出所有名稱空間,可以執行以下命令:
$ kubectl get namespacesNAME STATUS AGEdefault Active 11hkube-node-lease Active 11hkube-public Active 11hkube-system Active 11h
通常,Kubernetes建立四個預設名稱空間:kube system、kube public、kube node lease和default。kube system名稱空間包含由Kubernetes系統建立的物件,主要是控制平面代理。default名稱空間包含管理員和開發人員建立的物件和資源。預設情況下,我們連線到default名稱空間。kube public是一個特殊的名稱空間,任何人都可以對其進行安全和可讀,用於特殊目的,例如公開叢集的公共(非敏感)資訊。最新的名稱空間是kube node lease,它儲存用於節點心跳資料的節點租約物件。然而,好的做法是建立更多的名稱空間來為使用者和開發團隊虛擬化叢集。通過Resource Quotas,我們可以在名稱空間內劃分叢集資源。我們將在未來的一章中簡要介紹Resource Quotas。
Deployment Rolling Update and Rollback (Demo)