.NET Core + Kubernetes:Deployment
摘要:基於 Pod 爲單位能更加合理進行容器編排,然而 Pod 只是個啓動了一個或一組容器的資源類型,在實際應用中,我們也需要 Pod 能實現動態擴展與收縮、滾動更新等,但 Pod 本身是沒有辦法做到的,它需要依賴上層的一種控制來達到這樣的效果,這就涉及到 Kubernetes 中的控制器(Controller)模型知識,本文將注意介紹 Deployment 這個最基本的控制器對象。Deployment 控制器根據修改後的 Pod 模板,創建新的 ReplicaSet( k8sdemo-deployment-68cb864ff6 ),Pod 數默認是 0,然後老的 ReplicaSet ( k8sdemo-deployment-84d777fb7 )Pod 數逐漸減少,新的 ReplicaSet 的 Pod 數逐漸增加,兩個過程交替進行,新的增加一個,老的減少一個,直到全部升級完成。
在上篇文章 .NET Core + Kubernetes:Pod 中,主要介紹了 Pod 的相關內容,
基於 Pod 爲單位能更加合理進行容器編排,然而 Pod 只是個啓動了一個或一組容器的資源類型,在實際應用中,我們也需要 Pod 能實現動態擴展與收縮、滾動更新等,但 Pod 本身是沒有辦法做到的,它需要依賴上層的一種控制來達到這樣的效果,這就涉及到 Kubernetes 中的控制器(Controller)模型知識,本文將注意介紹 Deployment 這個最基本的控制器對象。
我們繼續以 .NET Core + Kubernetes:快速體驗 文中配置爲例,將以下配置保存爲 k8sdemo-deployment.yaml
:
apiVersion: apps/v1 kind: Deployment metadata: name: k8sdemo-deployment spec: replicas: 2 selector: matchLabels: name: k8sdemo template: metadata: labels: name: k8sdemo spec: containers: - name: k8sdemo image: beckjin/k8sdemo:1.0.0 ports: - containerPort: 80 imagePullPolicy: IfNotPresent
這個 Deployment 指定創建 2 個含 name=k8sdemo
標籤的 Pod,template 字段指定了 Pod 的模板。從表面上來看,Deployment 和 Pod 是直接關係,然而實際上在 Deployment 與 Pod 直接還有 ReplicaSet 一層。如下:
Deployment 實際上一個兩層控制器,Deployment 控制 ReplicaSet,ReplicaSet 控制 Pod。ReplicaSet 有版本區分,滾動更新的能力就是基於 ReplicaSet 的版本來實現,下文會介紹。
通過以下命令創建 k8sdemo-deployment
:
kubectl apply -f k8sdemo-deployment.yaml
查看 k8sdemo-deployment
的狀態信息:
kubectl get deployments
輸出結果中含3個狀態字段,含義如下:
- READY:當前處於 Running 狀態的 Pod 的個數/用戶期望的 Pod 個數( 配置文件設置的
replicas
值 ); - UP-TO-DATE:當前處於最新版本的 Pod 個數( Pod 的 Spec 部分與 Deployment 裏 Pod 模板裏定義的完全一致 ),在滾動更新過程中會有不一致的階段;
- AVAILABLE:當前可用的 Pod 個數。
查看 k8sdemo-deployment
所控制的 ReplicaSet 信息:
kubectl describe replicaset
如上圖,Deployment 創建後,Deployment 控制器就會立即創建一個 Pod 個數爲 2 的 ReplicaSet,ReplicaSet 的名字是由 Deployment 名字 + 隨機字符串 ,Pod 的名字是由 ReplicaSet 名字 + 隨機字符串 。
動態伸縮
要實現 Pod 的伸縮只需要調整配置文件中的 replicas
字段,如擴展爲 3 個,擴展完成後結果如下:
收縮則類似。
滾動更新
假設現在將鏡像 beckjin/k8sdemo:1.0.0
升級爲 beckjin/k8sdemo:1.1.0
,重新 apply 後並查看 Deployment 的 Events 信息,輸出內容含 “滾動更新” 的整個流程。
kubectl describe deployment k8sdemo-deployment
Deployment 控制器根據修改後的 Pod 模板,創建新的 ReplicaSet( k8sdemo-deployment-68cb864ff6
),Pod 數默認是 0,然後老的 ReplicaSet ( k8sdemo-deployment-84d777fb7
)Pod 數逐漸減少,新的 ReplicaSet 的 Pod 數逐漸增加,兩個過程交替進行,新的增加一個,老的減少一個,直到全部升級完成。
查看當前 ReplicaSet 的狀態:
可以看出原來的 ReplicaSet 的 Pod 已經縮減爲 0 個,新的 ReplicaSet 的 Pod 擴展爲 3 個,每次配置修改重新部署都可能創建一個新的 ReplicaSet,所以 Deployment、ReplicaSet 和 Pod 的關係圖可擴展如下:
回滾
通過上文的介紹,已經瞭解應用版本與 ReplicaSet 具有一一對應關係,所以如果要回滾版本其實就是使原來的 ReplicaSet 重新擴展 Pod,當前的 ReplicaSet 收縮至 0 個 Pod。
通過 kubectl rollout history
命令查看每次 Deployment 變更對應的版本。
kubectl rollout history deployment/k8sdemo-deployment
由於在創建 Deployment 沒有加 –record
參數,所以 CHANGE-CAUSE 都是 none
現在如果需要回滾到版本 1,執行以下命令:
kubectl rollout undo deployment/k8sdemo-deployment --to-revision=1
這時 Deployment 控制器還是按 “滾動更新” 的方式,完成對 k8sdemo-deployment
的回滾操作。
故障轉移
故障轉移主要是指當集羣中某個節點掛了,Pod 會自動轉移到其他健康的節點上。當前的 Pod 分佈情況如下:
可以看出 node1 上分配了 2 個 Pod,node2 分配了 1 個 Pod,接下來將 node1 強制關機,然後當 Kubernetes 檢測到 node1 不可用時,node1 上的 Pod 會變成 Terminating 狀態,並在 node2 上新建,維持可用 Pod 總數不變。
當 node1 恢復後,Terminating 狀態的 Pod 會被自動刪除,不過已經轉移到 node2 的 Pod 是不會被重新調度回 node1 的。