Kubernetes Deployment滾動升級

咱們k8s集羣使用的是1.7.7版本的,該版本中官方已經推薦使用Deployment代替Replication Controller(rc)了,Deployment繼承了rc的所有功能外,還能夠查看升級詳細進度和狀態,當升級出現問題的時候,可使用回滾操做回滾到指定的版本,每一次對Deployment的操做,都會保存下來,變能方便的進行回滾操做了,另外對於每一次升級均可以隨時暫停和啓動,擁有多種升級方案:Recreate刪除如今的Pod,從新建立;RollingUpdate滾動升級,逐步替換現有Pod,對於生產環境的服務升級,顯然這是一種最好的方式。nginx

建立Deployment

Deployment結構能夠看出一個Deployment擁有多個Replica Set,而一個Replica Set擁有一個或多個Pod。一個Deployment控制多個rs主要是爲了支持回滾機制,每當Deployment操做時,Kubernetes會從新生成一個Replica Set並保留,之後有須要的話就能夠回滾至以前的狀態。 下面建立一個Deployment,它建立了一個Replica Set來啓動3個nginx pod,yaml文件以下:api

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deploy
  labels:
    k8s-app: nginx-demo
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

將上面內容保存爲: nginx-deployment.yaml,執行命令:app

$ kubectl create -f nginx-deployment.yaml
deployment "nginx-deploy" created

而後執行一下命令查看剛剛建立的Deployment:ide

$ kubectl get deployments
NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   3         0         0            0           1s

隔一會再次執行上面命令:ui

$ kubectl get deployments
NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   3         3         3            3           4m

咱們能夠看到Deployment已經建立了3個Replica Set了,執行下面的命令查看rs和pod:spa

$ kubectl get rs
NAME                     DESIRED   CURRENT   READY     AGE
nginx-deploy-431080787   3         3         3         6m
$ kubectl get pod --show-labels
NAME                           READY     STATUS    RESTARTS   AGE       LABELS
nginx-deploy-431080787-53z8q   1/1       Running   0          7m        app=nginx,pod-template-hash=431080787
nginx-deploy-431080787-bhhq0   1/1       Running   0          7m        app=nginx,pod-template-hash=431080787
nginx-deploy-431080787-sr44p   1/1       Running   0          7m        app=nginx,pod-template-hash=431080787

上面的Deployment的yaml文件中的replicas:3將會保證咱們始終有3個POD在運行。3d

滾動升級Deployment

如今咱們將剛剛保存的yaml文件中的nginx鏡像修改成nginx:1.13.3,而後在spec下面添加滾動升級策略:code

minReadySeconds: 5
strategy:
  # indicate which strategy we want for rolling update
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 1
  • minReadySeconds:
    • Kubernetes在等待設置的時間後才進行升級
    • 若是沒有設置該值,Kubernetes會假設該容器啓動起來後就提供服務了
    • 若是沒有設置該值,在某些極端狀況下可能會形成服務服務正常運行
  • maxSurge:
    • 升級過程當中最多能夠比原先設置多出的POD數量
    • 例如:maxSurage=1,replicas=5,則表示Kubernetes會先啓動1一個新的Pod後才刪掉一箇舊的POD,整個升級過程當中最多會有5+1個POD。
  • maxUnavaible:
    • 升級過程當中最多有多少個POD處於沒法提供服務的狀態
    • maxSurge不爲0時,該值也不能爲0
    • 例如:maxUnavaible=1,則表示Kubernetes整個升級過程當中最多會有1個POD處於沒法服務的狀態。

而後執行命令:orm

$ kubectl apply -f nginx-deployment.yaml
deployment "nginx-deploy" configured

而後咱們可使用rollout命令:blog

  • 查看狀態:

    $ kubectl rollout status deployment/nginx-deploy
    Waiting for rollout to finish: 1 out of 3 new replicas have been updated..
    deployment "nginx-deploy" successfully rolled out
  • 暫停升級

    $ kubectl rollout pause deployment <deployment>
  • 繼續升級

    $ kubectl rollout resume deployment <deployment>

升級結束後,繼續查看rs的狀態:

$ kubectl get rs
NAME                      DESIRED   CURRENT   READY     AGE
nginx-deploy-2078889897   0         0         0         47m
nginx-deploy-3297445372   3         3         3         42m
nginx-deploy-431080787    0         0         0         1h

根據AGE咱們能夠看到離咱們最近的當前狀態是:3,和咱們的yaml文件是一致的,證實升級成功了。用describe命令能夠查看升級的所有信息:

Name:     nginx-deploy
Namespace:    default
CreationTimestamp:  Wed, 18 Oct 2017 16:58:52 +0800
Labels:     k8s-app=nginx-demo
Annotations:    deployment.kubernetes.io/revision=3
      kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"apps/v1beta1","kind":"Deployment","metadata":{"annotations":{},"labels":{"k8s-app":"nginx-demo"},"name":"nginx-deploy","namespace":"defa...
Selector:   app=nginx
Replicas:   3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:   RollingUpdate
MinReadySeconds:  0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels: app=nginx
  Containers:
   nginx:
    Image:    nginx:1.13.3
    Port:   80/TCP
    Environment:  <none>
    Mounts:   <none>
  Volumes:    <none>
Conditions:
  Type    Status  Reason
  ----    ------  ------
  Progressing   True  NewReplicaSetAvailable
  Available   True  MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet:  nginx-deploy-3297445372 (3/3 replicas created)
Events:
  FirstSeen LastSeen  Count From      SubObjectPath Type    Reason      Message
  --------- --------  ----- ----      ------------- --------  ------      -------
  50m   50m   1 deployment-controller     Normal    ScalingReplicaSet Scaled up replica set nginx-deploy-2078889897 to 1
  45m   45m   1 deployment-controller     Normal    ScalingReplicaSet Scaled down replica set nginx-deploy-2078889897 to 0
  45m   45m   1 deployment-controller     Normal    ScalingReplicaSet Scaled up replica set nginx-deploy-3297445372 to 1
  39m   39m   1 deployment-controller     Normal    ScalingReplicaSet Scaled down replica set nginx-deploy-431080787 to 2
  39m   39m   1 deployment-controller     Normal    ScalingReplicaSet Scaled up replica set nginx-deploy-3297445372 to 2
  38m   38m   1 deployment-controller     Normal    ScalingReplicaSet Scaled down replica set nginx-deploy-431080787 to 1
  38m   38m   1 deployment-controller     Normal    ScalingReplicaSet Scaled up replica set nginx-deploy-3297445372 to 3
  38m   38m   1 deployment-controller     Normal    ScalingReplicaSet Scaled down replica set nginx-deploy-431080787 to 0

回滾Deployment

咱們已經可以滾動平滑的升級咱們的Deployment了,可是若是升級後的POD出了問題該怎麼辦?咱們可以想到的最好最快的方式固然是回退到上一次可以提供正常工做的版本,Deployment就爲咱們提供了回滾機制。

首先,查看Deployment的升級歷史:

$ kubectl rollout history deployment nginx-deploy
deployments "nginx-deploy"
REVISION  CHANGE-CAUSE
1   <none>
2   <none>
3   kubectl apply --filename=Desktop/nginx-deployment.yaml --record=true

從上面的結果能夠看出在執行Deployment升級的時候最好帶上record參數,便於咱們查看歷史版本信息。一樣咱們可使用下面的命令查看單個REVISION的信息:

$ kubectl rollout history deployment nginx-deploy --revision=3
deployments "nginx-deploy" with revision #3
Pod Template:
  Labels: app=nginx
  pod-template-hash=3297445372
  Annotations:  kubernetes.io/change-cause=kubectl apply --filename=nginx-deployment.yaml --record=true
  Containers:
   nginx:
    Image:  nginx:1.13.3
    Port: 80/TCP
    Environment:  <none>
    Mounts: <none>
  Volumes:  <none>

假如如今要直接回退到當前版本的前一個版本:

$ kubectl rollout undo deployment nginx-deploy
deployment "nginx-deploy" rolled back

固然也能夠用revision回退到指定的版本:

$ kubectl rollout undo deployment nginx-deploy --to-revision=2
deployment "nginx-deploy" rolled back

如今能夠用命令查看Deployment如今的狀態了。

注意清除機制

前面在用apply命令滾動升級Deployment後,無心間在Dashboard中發現了Replica Sets下面有不少Pods爲0/0的RS,因爲本人有輕微的強迫症,眼裏是容不下0/0這種東西的,而後就給刪除了,結果後面更新的時候又出現了,覺得是yaml腳本有誤,結果到如今才清楚這個是用於Deployment回滾用的,不能隨便刪除的(感受本身就是個棒槌啊~~~)。RS不能隨便刪除

Kubernetes默認是會將Deployments的每次改動操做生成一個新的RS,並保存下來的。不過你能夠設置參數.spec.revisonHistoryLimit來來指定Deployment最多保留多少revision 歷史記錄。若是將該項設置爲0,Deployment就不容許回退了

參考文檔

相關文章
相關標籤/搜索