在上一章中,學習如何利用ReplicaSet部署 Pod。但是,很少以這種方式部署工作負載,因為ReplicaSet不提供輕鬆更新這些 Pod 所需的功能。 此功能由Deployment物件類型提供。

在開始之前,請確保Kiada套件的 Pod、服務和其他物件存在於您的叢集中。如果您遵循了上一章中的練習,它們應該已經存在。 如果沒有,您可以建立Kiada命名空間,並且使用以下指令apply Chapter14/SETUP/目錄中的所有yaml來建立它們:

$ kubectl apply -f SETUP -R

14.1 介紹Deployment

將工作負載部署到k8s時,通常利用建立Deployment物件來實現。 Deployment物件不直接管理Pod物件,而是建立Deployment物件時,利用自動建立的ReplicaSet物件來管理pod。 如下圖所示,Deployment控制著ReplicaSet,而ReplicaSet控制著各個Pod。

圖 14.1 Deployments、ReplicaSets 和 Pods 之間的關係。

圖 14.1 Deployments、ReplicaSets 和 Pods 之間的關係。

Deployment允許您以declaratively(宣告式)更新應用程式。 這表示您無需手動執行一系列操作來將一組Pod替換為運行應用程式更新後版本的Pod,您只需更新Deployment物件中的設定並讓k8s自動更新。

與ReplicaSet一樣,您可以在Deployment中指定Pod模板、期望副本數和標籤選擇器。基於此Deployment建立的Pod是彼此的精確副本,並且是可替代的。 由於這個和其他原因,Deployment主要用於無狀態工作負載,但您也可以使用Deployment來運行有狀態工作負載的單個實例。 但是,由於沒有內建方法可以防止用戶將Deployment擴展到多個實例,因此應用程式本身必須確保在多個副本同時運行時只有一個實例處於active狀態。

<aside> 💡 要運行可複製的有狀態工作負載,StatefulSet是更好的選擇。

</aside>

在本節中,您將使用Deployment替換kiada ReplicaSet。在不刪除Pod的情況下刪除ReplicaSet,如下所示:

$ kubectl delete rs kiada --cascade=orphan

查看在Deployment的spec部分需要指定什麼,以及Deployment與ReplicaSet的比較。

Deployment物件的spec部分與ReplicaSet的spec部分沒有太大區別。如下表,主要字段與ReplicaSet中的字段相同,只有一個附加字段。

字段名稱 描述
replicas 期望的副本數。當您建立Deployment物件時,k8s會從Pod模板建立多少Pod。
k8s會保留此數量的Pod,直到您刪除Deployment。
selector 標籤選擇器包含matchLabels子字段中的標籤映射或matchExpressions子字段中的標籤選擇器要求列表。
與標籤選擇器匹配的Pod會被視為此Deployment的一部分。
template 部署的Pod模板。每當需要季戀新Pod時,會使用此模板建立物件。
strategy 更新策略定義了當您更新Pod模板時,會如何替換此Deployment中的Pod。

replicasselectortemplate字段與 ReplicaSet 中的用途相同。在strategy附加字段中,您可以設定更新此Deployment時要採用的更新策略。

當我們需要建立新的Deployment manifest時,我們大多數人通常會複製現有的yaml來進行修改它。 但是,如果您手邊沒有現有的yaml,那麼有一種巧妙的方法可以從頭開始建立yaml。

您可能還記得您在本書的第 3 章中第一次建立了一個Deployment。以下是當時的指令:

$ kubectl create deployment kiada --image=luksa/kiada:0.1

但由於這指令會直接建立物件而不是建立yaml,因此並不是您想要的。 如果您想建立物件yaml而不將它發佈到API,則可以將--dry-run=client-o yaml選項傳遞給kubectl create指令。 因此,要建立一個初始版本的Deployment manifest,您可以使用以下指令:

$ kubectl create deployment my-app --image=my-image --dry-run=client -o yaml > deploy.yaml