Kubernetes-Deployment詳解

Deployment與控制器模型

Deployment可以幫我們做什么

  • 定義一組Pod期望數(shù)量,Controller會維持Pod數(shù)量與期望數(shù)量一致
  • 配置Pod的發(fā)布方式,controller會按照給定的策略更新Pod,保證更新過程中不可用Pod維持在限定數(shù)量范圍內(nèi)
  • 如果發(fā)布有問題支持回滾

實例

apiVersion: v1
kind: Deployment
metadata:
 name: nginx-deployment
spec:
 selector:
  matchLabels:
   app: nginx
 replicas: 3
 template:
  metadata:
   labels:
    app: nginx
  spec:
   containers:
   - name: nginx
     image: nginx:1.7.9
     ports:
     - containerPort: 80

控制器模型

在Kubernetes架構(gòu)中,有一個叫做kube-controller-manager的組件。這個組件,是一系列控制器的集合。

其中每一個控制器,都以獨有的方式負責某種編排功能。而Deployment正是這些控制器中的一種。它們都遵循Kubernetes中一個通用的編排模式,即:控制循環(huán)

用一段go語言偽代碼,描述這個控制循環(huán)

for {
    實際狀態(tài) := 獲取集群中對象X的實際狀態(tài)
    期望狀態(tài) := 獲取集群中對象X的期望狀態(tài)
    if 實際狀態(tài) == 期望狀態(tài) {
        什么都不做
    }else{
        執(zhí)行編排動作,將實際狀態(tài)調(diào)整為期望狀態(tài)
    }
}

在具體實現(xiàn)中,實際狀態(tài)往往來自于Kubernetes集群本身。比如Kubelet通過心跳匯報的容器狀態(tài)和節(jié)點狀態(tài),或者監(jiān)控系統(tǒng)中保存的應(yīng)用監(jiān)控數(shù)據(jù),或者控制器主動收集的它感興趣的信息,這些都是常見的實際狀態(tài)的來源;期望狀態(tài)一般來自用戶提交的YAML文件,這些信息都保存在Etcd中

對于Deployment,它的控制器簡單實現(xiàn)如下:

  1. Deployment Controller從Etcd中獲取到所有攜帶 “app:nginx”標簽的Pod,然后統(tǒng)計它們的數(shù)量,這就是實際狀態(tài)
  2. Deployment對象的replicas的值就是期望狀態(tài)
  3. Deployment Controller將兩個狀態(tài)做比較,然后根據(jù)比較結(jié)果,確定是創(chuàng)建Pod,還是刪除已有Pod

Deployment的滾動更新

Deployment滾動更新的實現(xiàn),依賴的是Kubernetes中的ReplicaSet

Deployment控制器實際操縱的,就是Replicas對象,而不是Pod對象。對于Deployment、ReplicaSet、Pod它們的關(guān)系如下圖:

image.png

ReplicaSet負責通過“控制器模式”,保證系統(tǒng)中Pod的個數(shù)永遠等于指定的個數(shù)。這也正是Deployment只允許容器的restartPolicy=Always的主要原因:只有容器能保證自己始終是running狀態(tài)的前提下,ReplicaSet調(diào)整Pod的個數(shù)才有意義。

Deployment同樣通過控制器模式,操作ReplicaSet的個數(shù)和屬性,進而實現(xiàn)“水平擴展/收縮”和“滾動更新”兩個編排動作

對于“水平擴展/收縮”的實現(xiàn),Deployment Controller只需要修改replicas的值即可。

用戶執(zhí)行這個操作的指令如下:

kubectl scale deployment nginx-deployment --replicas=4

滾動更新的過程

首先,創(chuàng)建上述Pod

[root@host1 deployment]# kubectl create -f nginx-deployment.yaml --record #record參數(shù)可以記錄每次操作所執(zhí)行的命令,方便日后查看
deployment.apps/nginx-deployment created
[root@host1 deployment]# kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           21s
[root@host1 deployment]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-76bf4969df   3         3         3       62s
[root@host1 deployment]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-76bf4969df-jq4tj   1/1     Running   0          70s
nginx-deployment-76bf4969df-jsln9   1/1     Running   0          70s
nginx-deployment-76bf4969df-nbl8j   1/1     Running   0          70s
test-projected-volume               1/1     Running   0          19h
[root@host1 deployment]# kubectl rollout status deployment/nginx-deployment  #通過該指令可以實時查看對象的狀態(tài)變化
deployment "nginx-deployment" successfully rolled out
[root@host1 deployment]# kubectl edit deployment/nginx-deployment #修改etcd中的API對象
deployment.extensions/nginx-deployment edited
[root@host1 deployment]# kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
[root@host1 deployment]# kubectl describe deployment/nginx-deployment
....
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  22m   deployment-controller  Scaled up replica set nginx-deployment-76bf4969df to 3
  Normal  ScalingReplicaSet  17m   deployment-controller  Scaled up replica set nginx-deployment-779fcd779f to 1
  Normal  ScalingReplicaSet  16m   deployment-controller  Scaled down replica set nginx-deployment-76bf4969df to 2
  Normal  ScalingReplicaSet  16m   deployment-controller  Scaled up replica set nginx-deployment-779fcd779f to 2
  Normal  ScalingReplicaSet  15m   deployment-controller  Scaled down replica set nginx-deployment-76bf4969df to 1
  Normal  ScalingReplicaSet  15m   deployment-controller  Scaled up replica set nginx-deployment-779fcd779f to 3
  Normal  ScalingReplicaSet  15m   deployment-controller  Scaled down replica set nginx-deployment-76bf4969df to 0

首先,當你修改了Deployment中的Pod定義之后,Deployment Controller會使用這個修改后的Pod模板,創(chuàng)建一個新的ReplicaSet,這個ReplicaSet的初始Pod副本數(shù)是:0

然后在17m的時候,Deployment Controller開始將這個新的ReplicaSet所控制的Pod副本數(shù)從0變?yōu)?,即水平擴展出與i個副本

接著,在16m的時候,Deployment Controller將舊的ReplicaSet所控制的舊Pod副本數(shù)減少一個

....

如此交替,就彎沉了一組Pod版本更新過程。

[root@host1 deployment]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-76bf4969df   0         0         0       26m
nginx-deployment-779fcd779f   3         3         3       21m

Deployment還會確保,在任何時間窗口內(nèi),只有指定比例的Pod處于離線狀態(tài),同時確保,在任何時間窗口內(nèi),只有指定比例的新Pod被創(chuàng)建出來,這兩個值都可以配置,默認是25%

這個策略,是Deployment對象的一個字段,叫做RollingUpdateStrategy,如下:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
 labels:
  app: nginx
spec:
...
 strategy:
  type: RollingUpdate
  rollingUpdate:
   maxSurge: 1
   maxUnavailable: 1

maxSurge指定的是除了DESIRED數(shù)量之外,在一次滾動中,Deployment控制器還可以創(chuàng)建多少個新Pod;

maxUnavailable指的是,在一次滾動中,Deployment控制器可以刪除多少個舊Pod

回滾

首先我們使用kubeclt rollout history命令,查看每次Deployment變更對應(yīng)的版本

然后使用kubeclt rollout undo deployment/[deployment-name] --to-revision=[版本號]

參考:阿里云大學云原生技術(shù)公開課 極客時間深入剖析Kubernetes

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容