kubernetes-Deployment部署無狀態服務的原理詳解(二十五)

公衆號:後端技術解憂鋪

引言

  k8s部署無狀態應用後,若須要更新應用時,能夠經過使用ReplicationController或ReplicaSet實現升級,主要有兩種方式:java

  • 直接刪除全部現有的pod,而後建立新的pod;
  • 先建立新的pod,再刪除舊pod。這裏面也有兩種方式,一種是先等全部新pod都運行成功後,應用切換到新pod訪問,一次性刪除全部舊pod;另外一種是滾動升級方式逐步新建pod代替舊pod。
      下面咱們將先看一下經常使用的相關術語,而後看一下升級pod的演進方式。

其餘相關術語

  Pod:每一個Pod是一個或一組緊密相關的容器,每一個Pod就像是一個獨立的邏輯機器,擁有本身的IP、主機名、進程等,運行一個獨立的應用程序,是K8S調度的基本單位。
  ReplicationController:簡稱RC,旨在建立和管理一個Pod的多個副本(replicas)。當Pod副本數少於指定數目,RC就會啓動運行新的Pod副本;多於指定數目,RC就會殺死多餘的Pod副本。
  ReplicaSet:是新一代的RC,其相比於RC,Pod選擇器的表達能力更強,其選擇器可匹配缺乏某個標籤或特定標籤名的Pod。python

刪舊pod,建新pod

  假設ReplicationController管理一組v1版本的pod,直接經過將pod模板修改成v2版本的鏡像,刪除舊的pod實例,RC檢測到當前沒有pod匹配標籤選擇器,就會建立新的實例。
刪除舊pod,建立新podshell

  1. 階段1:原v1版本的RC有3個副本pod-v1。
  2. 階段2:pod模板發生修改,由初始的v1版本修改成v2版本。
  3. 階段3:pod-v1被手動刪除。
  4. 階段4:RC檢測到當前沒有pod匹配標籤選擇器,根據模板建立新的pod-v2。在階段3過渡到階段4期間,服務會出現短暫的不可用。

建新pod,刪舊pod

  若是客戶不能接受升級更新期間出現短暫的不可用的服務,那就須要先建立新的pod,再刪除舊pod,這須要更多的硬件資源來支撐新舊pod同時存在的場景。json

建立全部新pod,刪除全部舊pod

  pod通常是經過Service來暴露服務的,在運行新版本pod前,Service都是訪問的舊版本pod,當新版本pod建立且正常運行後,修改服務標籤選擇器切換Service流量至新pod,切換完畢後,刪除舊RC,就能夠刪除全部舊pod。這種方式就是所謂的藍綠部署
藍綠部署後端

  1. 階段1:原v1版本的RC有3個副本pod-v1。
  2. 階段2:新建v2版本的RC,而且RC-v2自動建立了新的v2版本的pod。
  3. 階段3:Service的流量切換到pod-v2,正常運行起來。
  4. 階段4:刪除RC-v1,從而自動刪除pod-v1。

滾動新建和刪除pod

  除了一次性建立新pod再一次性刪除舊pod,咱們還能夠逐步遞進的對舊版本pod進行刪除,對新版本pod進行建立。這個能夠經過對舊版本RC逐步縮容,同時對新版本RC進行擴容來實現。
滾動升級RCapi

  1. 階段1:v1版本的RC副本數爲3,有3個pod-v1。
  2. 階段2:RC-v1副本數降爲2,自動刪除一個pod-v1,此時,建立一個v2版本的RC,且pod副本數爲1,會自動新建一個v2版本的pod。
  3. 階段3:RC-v1副本數降爲1,自動再刪除一個pod-v1,RC-v2的副本數爲2,再自動新建一個pod-v2。
  4. 階段4:RC-v1副本數降爲0,而且刪掉RC-v1,RC-v2副本數升爲3,從而建立第3個pod-v2,至此完成滾動升級。

引入Deployment

  ReplicationController和ReplicaSet這兩種資源對象須要其餘控制器進行配合才能夠實現滾動升級,而且難度大,所以k8s提供了一種基於ReplicaSet的資源對象Deployment能夠支持聲明式地更新應用。tomcat

Deployment介紹

Deployment概述

  Deployment是K8s在1.2版本引入的,是一種更高階的資源,用於部署應用程序並以聲明的方式升級應用,從而更好地解決pod編排問題。app

Deployment使用機制

使用Deployment機制
  Deployment在內部使用了ReplicaSet實現編排pod功能,當建立一個Deployment時,ReplicaSet資源會隨之建立,ReplicaSet是新一代的ReplicationController,並推薦使用它替代ReplicationController來複制和管理Pod,在使用Deployment時,實際的Pod是由Deployment的ReplicaSet建立和管理的。運維

Deployment使用場景

  1. 建立Deployment對象生成對應的ReplicaSet並完成pod副本建立;
  2. 經過檢查Deployment狀態(查看pod副本數量是否達到預期值)檢驗應用部署是否完成;
  3. 更新Deployment從而建立新的pod;
  4. 當前Deployment不穩定或故障,回滾到以前某個版本的Deployment(歷史版本revision)
  5. 暫停Deployment並修改多個pod的template spec配置項,再恢復Deployment進行新的發佈部署;
  6. 擴展Deployment從而應對高負載場景;
  7. 清理再也不須要使用的舊版本ReplicaSet;

Deployment使用

Deployment基本命令

  假設Deployment的服務名稱爲test-tomcat-deploy,yaml模板文件名爲test-tomcat.yaml。使用命令時,deploy等價於deployment等價於deployments。若須要指定命名空間ns_name時,須要加上-n ns_namecurl

建立deployment

  • 基於模板建立
    $ kubectl create -f test-tomcat.yaml

刪除deployment

  • 基於模板刪除
    $ kubectl delete -f test-tomcat.yaml
  • 基於名稱刪除
    $ kubectl delete deployment test-tomcat-deploy

更新deployment

  • 基於模板更新
    $ kubectl apply -f test-tomcat.yaml
  • 基於名稱更新
    $ kubectl edit deploy/test-tomcat-deploy

查看deployment

  • 基於模板查看
    $ kubectl get deploy test-tomcat-deploy -o yaml
  • 基於名稱查看
    $ kubectl describe deployments test-tomcat-deploy
  • 查看列表
    $ kubectl get deploy

資源對象信息

Deployment信息

[root@localhost ~]# kubectl get deploy -n kube-system
NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
st-ui-wnunzeyg   1         1         1            1           1d
st-ui-x3w4xumy   1         1         1            1           1d
  • DESIRED:pod副本數量的指望值(Deployment中定義的Replica數)
  • CURRENT:當前Replica值(Deployment實際建立的ReplicaSet中Replica值),該值會一直增長到DESIRED值爲止纔算整個應用實例建立完畢,部署纔算完成。
  • UP-TO-DATE:最新版本的pod副本數量,用於指示在滾動升級過程當中,有多少pod副本已成功升級。(Deployment滾動升級過程當中ReplicaSet的Replica成功數)
  • AVAILABLE:當前集羣中可用pod副本數。(Deployment建立的ReplicaSet中Replica存活數)
  • AGE:表示距離最後一次操做的時長。

ReplicaSet信息

[root@localhost ~]# kubectl get rs -n kube-system
NAME                        DESIRED   CURRENT   READY     AGE
st-ui-wnunzeyg-391614280    1         1         1         1d
st-ui-x3w4xumy-1656786196   1         1         1         1d

  咱們能夠看到ReplicaSet的命名和Deployment是相關的,ReplicaSet命名是以Deployment名爲前綴,在Deployment名字基礎上又加了一串隨機數。

Pods信息

[root@localhost ~]# kubectl get pods -n kube-system
NAME                              READY     STATUS    RESTARTS   AGE
st-ui-wnunzeyg-391614280-3brk8    1/1       Running   0          1d
st-ui-x3w4xumy-1656786196-f4w8z   1/1       Running   0          1d

  pod名稱以Deployment中的ReplicaSet名稱爲前綴,在此基礎上又加了隨機字符串。

Deployment更新

更新策略

  在Deployment中,能夠經過spec.strategy指定Pod更新的策略,目前支持:Recreate(重建)RollingUpdate(滾動更新),默認是RollingUpdate。
  Recreate:設置spec.strategy.type=Recreate,更新方式爲:Deployment在更新Pod時,會先殺掉全部正在運行的Pod,而後建立新的Pod。
  RollingUpdate:設置spec.strategy.type=RollingUpdate,更新方式爲:Deployment會以滾動的方式來漸變性的更新Pod,即Pod新版本的遞增,舊版本的遞減的一個過程。

滾動更新

概念

  「滾動」,給人的是一種「圓」的印象,持續,不中斷的意思,相似於「持續交付」的理念。RollingUpdate策略指一次僅更新一個Pod,而且逐個更新,而不是一次性將全部的服務都關閉,避免業務中斷。

原理

滾動更新流程

  1. 初始建立Deployment,系統建立了一個ReplicaSet,並按照用戶的需求建立了3個Pod副本;
  2. 當更新Deployment時,系統建立一個新的ReplicaSet,並將其副本數量擴展到1,而後將舊的ReplicaSet縮減爲2;
  3. 系統繼續按照相同的更新策略對新舊兩個ReplicaSet進行逐個調整。
  4. 最後,新的ReplicaSet運行了3個新版本的Pod副本,舊的ReplicaSet副本數量則縮減爲0。

Deployment回滾

概念

  回滾:經過滾動升級的策略能夠平滑的升級Deployment,若升級出現問題,須要最快且最好的方式回退到上一次可以提供正常工做的版本。爲此K8S提供了回滾機制。
  revision:更新應用時,K8S都會記錄當前的版次,即爲revision,當升級出現問題時,可經過回滾到某個特定的revision,默認配置下,K8S只會保留最近的幾個revision,能夠經過Deployment配置文件中的spec.revisionHistoryLimit屬性增長revision數量。
  更新或回滾:每次更新或回滾時,revision都會自增1,回滾能夠看做是一次更新,是一次更新爲原版本的操做。

kubectl命令使用

查看修訂版本記錄

$ kubectl rollout history deployment deployment_name

查看某個歷史記錄的詳細信息

$ kubectl rollout history deployment deployment_name --revision=2
其中--revision表示指定修訂版本;

回滾到上一個版本

$ kubectl rollout undo deployment deployment_name

回滾到指定版本

$ kubectl rollout undo deployment deployment_name --to-revision=2
其中,--to-revision表示回滾到指定的修訂版本。

API接口使用

POST

/apis/apps/v1beta1/namespaces/{namespace}/deployments/{name}/rollback
如:
curl -k -H 'Authorization: Bearer token_xxxx' -H 'Content-Type:application/json' -X POST -d '{
    "kind": "DeploymentRollback",
    "apiVersion": "extensions/v1beta1",
    "name": "deployment_name",
    "rollbackTo": {
        "revision": 2
    }
}' https://localhost:6443/apis/extensions/v1beta1/namespaces/default/deployments/deployment_name/rollback

  其中:name和rollbackTo.revision爲必須字段,name爲資源名稱,rollbackTo.revision爲回退的版本,若要回退上一個版本,即爲0。

Q&A

什麼是聲明式?和其餘方式有什麼區別?

  除了聲明式,咱們通常還有指令式,也就是命令式。咱們看看這二者定義和區別。
指令式

  1. 定義:使用計算機某種語言的指令(命令)來完成程序的運行,好比咱們經過編寫shell腳本、python腳本運行程序應用。
  2. 編寫:編寫複雜,強依賴開發人員的經驗,須要考慮目標環境以及流程細節,處理各類異常狀況和邊緣狀況等。
  3. 事務性:較難保持事務性,強依賴腳本流程,若腳本在執行過程當中出現異常,程序應用會處於一箇中間狀態,因此屢次運行,可能會達到不一樣的狀態和結果。
  4. 維護性:開發後,須要有對應的運維文檔來協助運維人員維護同一個腳本,不便於維護。

聲明式

  1. 定義:使用配置文件直接描述最終狀態,好比k8s中的yaml文件,描述最終要啓動多少副本,要多少cpu之類的狀態和結果。
  2. 編寫:易於編寫,只要會寫配置文件,告訴應用達到什麼樣的結果和狀態便可,不須要考慮流程和目標環境的細節,
  3. 事務性:自然的事務性,要麼執行成功,要麼失敗,不會出現多種中間狀態,重複執行保持一致的狀態和結果。
  4. 維護性:配置文件中直接描述了最終狀態和結果,無需過多的運維文檔來描述信息。

參考《Kubernetes in Action》《Kubernetes權威指南》k8s官網

相關文章
相關標籤/搜索