Deployment

Deploymentnginx

RC是kubernetes中的一個核心概念,Deployment 是新一代的RC,除了擁有RC的功能外,還具有一下特性:shell

  • 支持事件和狀態查看:能夠查看Deployment升級的狀態和詳細過程
  • 回滾:升級Pod後出現問題,可使用回滾功能回退到以前任一(總記錄歷史數之內)歷史版本
  • 版本記錄:每一次對Deployment的操做,都能記錄下來,保證回滾的基礎
  • 暫停和啓動:對於每一次更新都能暫停和啓動
  • 金絲雀發佈

Deployement 做爲新一代的RC,不只在功能上更豐富了,同時官方推薦使用,在一些官方組件上,也能看到是使用Deployment部署,好比kube-proxy,kube-dns。api

結構圖層app

能夠看出,Deployment管理一個或多個Replica Set,一個Replica Set管理一個或多個Pod。Deployment 管理多個rs的做用,主要是爲了支持回滾機制,每次操做Deployment後,都會生成一個新的RS對象保存下來,也能夠設置保留歷史版本數量,當須要之前的版本時能夠一鍵回滾。ide

用例

如下是部署的典型用例:ui

建立部署

官方模板 nginx-deployment.yamlthis

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

這是部署示例。它建立一個ReplicaSet來調出三個nginx Pod。code

經過下載示例文件,而後運行如下命令來運行示例:對象

kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml

將kubectl標誌設置--recordtrue容許您將當前命令記錄在正在建立或更新的資源的註釋中。這對於未來的自省頗有用:例如,查看每一個Deployment版本中執行的命令。blog

要查看「部署」推出狀態,請運行:

$ kubectl rollout status deployment/nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out

建立的ReplicaSet確保始終有三個nginx Pod。

注意:您必須在Deployment中指定適當的選擇器和pod模板標籤(在本例中爲 app = nginx)。也就是說,請勿與其餘控制器(包括其餘Deployment,ReplicaSet,StatefulSet等)重疊。Kubernetes不會阻止您重疊,而且若是多個控制器具備重疊的選擇器,那麼這些控制器可能會相互競爭,而且沒法正常運行。

Pod模板哈希標籤

注意: Do not change this label.

注意上面的pod標籤中示例輸出中的pod-template-hash標籤。此標籤由Deployment控制器添加到Deployment建立或採用的每一個ReplicaSet中。其目的是確保部署的子副本集不重疊。它是經過對ReplicaSet的PodTemplate進行散列並使用所得的散列做爲將添加到ReplicaSet選擇器,吊艙模板標籤以及ReplicaSet可能具備的任何現有吊艙中的標籤值來計算的。

更新部署

注意:只有且僅當.spec.template更改了部署的pod模板(即)(例如,模板的標籤或容器映像已更新)時,纔會觸發部署的推出。其餘更新,例如擴展部署,不會觸發部署。

假設咱們如今要更新nginx Pods以使用nginx:1.9.1圖像而不是nginx:1.7.9圖像。

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment "nginx-deployment" image updated

或者,咱們能夠edit部署和改變.spec.template.spec.containers[0].imagenginx:1.7.9nginx:1.9.1

$ kubectl edit deployment/nginx-deployment
deployment "nginx-deployment" edited

要查看部署狀態,請運行:

$ kubectl rollout status deployment/nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out

部署成功後,您可能須要get部署:

$ kubectl get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            3           36s

最新副本數代表部署已將副本更新爲最新配置。當前副本指示此Deployment管理的所有副本,可用副本指示可用的當前副本數。

咱們能夠kubectl get rs經過建立新的ReplicaSet並將其縮放到3個副本,以及將舊的ReplicaSet縮小到0個副原本看到Deployment更新了Pod。

過渡(又名進行中的多個更新)

每次部署控制器觀察到新的部署對象時,若是沒有現有的ReplicaSet,則會建立一個ReplicaSet來調出所需的Pod。標籤匹配.spec.selector但模板不匹配的現有ReplicaSet控制Pod .spec.template按比例縮小。最終,新的副本集將被縮放爲.spec.replicas,全部舊的副本集將被縮放爲0。

若是在進行現有部署時更新部署,則部署將根據更新建立一個新的ReplicaSet並開始進行擴展,並將其先前擴展的ReplicaSet進行滾動-它將添加到其列表中舊的ReplicaSets,並將開始按比例縮小比例。

例如,假設您建立了一個Deployment來建立5個的副本nginx:1.7.9,可是nginx:1.9.1當只建立了3個副本時,更新了Deployment來建立5個的副本nginx:1.7.9。在這種狀況下,Deployment將當即開始殺死nginx:1.7.9它已經建立的3個Pod,並將開始建立 nginx:1.9.1Pod。nginx:1.7.9更改路線以前,它不會等待建立5個副本。

標籤選擇器更新

一般不建議更新標籤選擇器,建議您預先計劃選擇器。不管如何,若是您須要執行標籤選擇器更新,請格外當心,並確保您已掌握全部含義。

  • 添加選擇器時,還須要使用新標籤來更新Deployment規範中的pod模板標籤,不然將返回驗證錯誤。此更改是不重疊的更改,這意味着新選擇器不會選擇使用舊選擇器建立的副本集和Pod,從而致使全部舊副本集孤立,並建立新的副本集。
  • 選擇器更新(即更改選擇器鍵中的現有值)會致使與添加操做相同的行爲。
  • 選擇器的刪除(即從「部署」選擇器中刪除現有的密鑰)不須要對窗格模板標籤進行任何更改。沒有孤立的現有ReplicaSet,也不會建立新的ReplicaSet,可是請注意,已刪除的標籤仍存在於任何現有Pod和ReplicaSet中。

滾動升級

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

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處於沒法服務的狀態。

而後執行命令:

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

回滾部署

有時您可能想回滾部署;例如,當部署不穩定時(例如崩潰循環)。默認狀況下,全部「部署」的推出歷史記錄都保留在系統中,以便您能夠隨時回滾(能夠經過修改修訂歷史記錄限制來更改它)。

注意:觸發展開部署時,將建立展開的修訂版。這意味着只有且僅當.spec.template更改了部署的吊艙模板()(例如,更新模板的標籤或容器映像)時,才建立新修訂。其餘更新(例如擴展Deployment)不會建立Deployment版本,所以咱們能夠促進同時進行手動或自動擴展。這意味着,當您回滾到較早的修訂版時,只會回滾Deployment的pod模板部分。

假設咱們在更新Deployment時輸入了圖像名稱,nginx:1.91而不是nginx:1.9.1

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.91
deployment "nginx-deployment" image updated

推出將被卡住。

$ kubectl rollout status deployments nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...

按Ctrl-C中止上述推出狀態監視。有關卡住的卷展欄的更多信息,參見 此處

您還將看到舊副本(nginx-deployment-1564180365和nginx-deployment-2035384211)和新副本(nginx-deployment-3066724191)的數量均爲2。

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-1564180365   2         2         0       25s
nginx-deployment-2035384211   0         0         0       36s
nginx-deployment-3066724191   2         2         2       6s

查看建立的Pod,您將看到由新的ReplicaSet建立的2個Pod陷入了圖像提取循環中。

$ kubectl get pods
NAME                                READY     STATUS             RESTARTS   AGE
nginx-deployment-1564180365-70iae   1/1       Running            0          25s
nginx-deployment-1564180365-jbqqo   1/1       Running            0          25s
nginx-deployment-3066724191-08mng   0/1       ImagePullBackOff   0          6s
nginx-deployment-3066724191-eocby   0/1       ImagePullBackOff   0          6s

注意: Deployment Controller將自動中止不良的部署,並將中止擴展新的ReplicaSet。這取決於maxUnavailable您指定的rollingUpdate參數(特別是)。Kubernetes默認狀況下將值設置爲1,spec.replicas設置爲1,所以若是您不關心設置這些參數,則默認狀況下您的Deployment可能不可用100%!未來的版本將在Kubernetes中修復此問題。

$ kubectl describe deployment

要解決此問題,咱們須要回滾到穩定的Deployment的先前版本。

檢查部署的推出歷史記錄

首先,檢查此部署的修訂:

$ kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment"
REVISION    CHANGE-CAUSE
1           kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
2           kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
3           kubectl set image deployment/nginx-deployment nginx=nginx:1.91

由於咱們在使用建立此Deployment時記錄了命令--record,因此咱們能夠輕鬆地看到咱們在每一個修訂版中所作的更改。

要進一步查看每一個修訂的詳細信息,請運行:

$ kubectl rollout history deployment/nginx-deployment --revision=2
deployments "nginx-deployment" revision 2
  Labels:       app=nginx
          pod-template-hash=1159050644
  Annotations:  kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
  Containers:
   nginx:
    Image:      nginx:1.9.1
    Port:       80/TCP
     QoS Tier:
        cpu:      BestEffort
        memory:   BestEffort
    Environment Variables:      <none>
  No volumes.

回滾到之前的修訂

如今,咱們決定撤消當前的推出並回滾到之前的版本:

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

另外,您能夠經過如下方式回滾到特定修訂--to-revision

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

有關與推出相關命令的更多詳細信息,請閱讀kubectl rollout

如今,部署已回滾到之前的穩定版本。

擴展部署

您可使用如下命令擴展部署:

$ kubectl scale deployment nginx-deployment --replicas=10
deployment "nginx-deployment" scaled

假設在集羣中啓用了水平Pod自動縮放,則能夠爲Deployment設置一個自動縮放器,並根據現有Pod的CPU利用率選擇要運行的Pod的最小和最大數量。

$ kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
deployment "nginx-deployment" autoscaled

比例縮放

RollingUpdate部署支持同時運行一個應用程序的多個版本。當您或自動縮放器縮放在推出期間(正在進行或已暫停)的RollingUpdate部署時,部署控制器將平衡現有活動副本集(帶有Pod的副本集)中的其餘副本,以下降風險。這稱爲比例縮放

例如,您正在運行具備10個副本,maxSurge = 3和maxUnavailable = 2 的Deployment 。

經過按比例縮放,咱們將其餘副本分佈在全部副本集中。較大比例的副本將進入具備最多副本的副本集,而較低比例的副本將進入具備較少副本的副本集。任何剩餘的都將被添加到具備最多副本的ReplicaSet中。副本數爲零的副本集不會按比例放大。

在上面的示例中,將3個副本添加到舊的ReplicaSet中,將2個副本添加到新的ReplicaSet中。假設新副本運行情況良好,推出過程最終應將全部副本移至新的ReplicaSet。

暫停和恢復部署

您能夠在觸發一個或多個更新以前暫停部署,而後再恢復它。這樣,您能夠在暫停和恢復之間應用多個修復程序,而不會觸發沒必要要的部署。

經過運行如下命令來暫停:

$ kubectl rollout pause deployment/nginx-deployment
deployment "nginx-deployment" paused

而後更新部署的映像:

$ kubectl set image deploy/nginx-deployment nginx=nginx:1.9.1
deployment "nginx-deployment" image updated

請注意,沒有新的部署開始:

$ kubectl rollout history deploy/nginx-deployment
deployments "nginx"
REVISION  CHANGE-CAUSE
1   <none>

$ kubectl get rs
NAME               DESIRED   CURRENT   READY     AGE
nginx-2142116321   3         3         3         2m

您能夠根據須要進行任意數量的更新,例如,更新將使用的資源:

$ kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi
deployment "nginx" resource requirements updated

部署在暫停以前的初始狀態將繼續其功能,可是隻要暫停部署,對部署的新更新將不會有任何效果。

最終,恢復部署並觀察新的ReplicaSet以及全部新更新:

$ kubectl rollout resume deploy/nginx-deployment
deployment "nginx" resumed
$ kubectl get rs -w
NAME               DESIRED   CURRENT   READY     AGE
nginx-2142116321   2         2         2         2m
nginx-3926361531   2         2         0         6s
nginx-3926361531   2         2         1         18s
nginx-2142116321   1         2         2         2m
nginx-2142116321   1         2         2         2m
nginx-3926361531   3         2         1         18s
nginx-3926361531   3         2         1         18s
nginx-2142116321   1         1         1         2m
nginx-3926361531   3         3         1         18s
nginx-3926361531   3         3         2         19s
nginx-2142116321   0         1         1         2m
nginx-2142116321   0         1         1         2m
nginx-2142116321   0         0         0         2m
nginx-3926361531   3         3         3         20s
^C
$ kubectl get rs
NAME               DESIRED   CURRENT   READY     AGE
nginx-2142116321   0         0         0         2m
nginx-3926361531   3         3         3         28s

注意:您不能回滾已暫停的部署,直到您將其恢復。

部署狀態

部署在其生命週期中會進入各類狀態。它能夠前進,同時推出新ReplicaSet,也能夠是完整的,也能夠不取得進展

進行中的部署

Kubernetes標記的部署做爲前進當執行下列任務之一:

  • 部署將建立一個新的ReplicaSet。
  • 部署正在擴展其最新的ReplicaSet。
  • 部署正在縮減其較舊的ReplicaSet。
  • Pod已準備就緒或可用(至少已準備好MinReadySeconds)。

您可使用監視部署的進度kubectl rollout status

完成部署

Kubernetes 具備如下特徵時,將Deployment標記爲完成

  • 與Deployment關聯的全部副本均已更新爲您指定的最新版本,這意味着您請求的全部更新均已完成。
  • 與部署關聯的全部副本都可用。
  • 沒有運行用於部署的舊副本。

您可使用來檢查部署是否已完成kubectl rollout status。若是推出成功完成,則kubectl rollout status返回零退出代碼。

$ kubectl rollout status deploy/nginx-deployment
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment "nginx" successfully rolled out
$ echo $?
0

部署失敗

嘗試部署其最新的ReplicaSet可能會遇到麻煩,而沒有完成。這多是因爲如下因素引發的:

  • 配額不足
  • 準備就緒探針故障
  • 圖像拉出錯誤
  • 權限不足
  • 極限範圍
  • 應用程序運行時配置錯誤

檢測這種狀況的一種方法是在「部署」規範中指定一個截止日期參數:(spec.progressDeadlineSeconds)。spec.progressDeadlineSeconds表示部署控制器在指示(處於部署狀態)部署進度已中止以前等待的秒數。

如下kubectl命令設置規範progressDeadlineSeconds以使控制器在10分鐘後報告部署進度不足:

$ kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'
"nginx-deployment" patched

一旦超過了最後期限,Deployment控制器就會將具備如下屬性的DeploymentCondition添加到Deployment的status.conditions

  • Type=Progressing
  • Status=False
  • Reason=ProgressDeadlineExceeded
相關文章
相關標籤/搜索