K8s -- Deployment

1. Deployment概述

Deployment對(duì)象,顧名思義,是用于部署應(yīng)用的對(duì)象。它使Kubernetes中最常用的一個(gè)對(duì)象,它為ReplicaSet和Pod的創(chuàng)建提供了一種聲明式的定義方法,從而無(wú)需像前兩篇文章中那樣手動(dòng)創(chuàng)建ReplicaSet和Pod對(duì)象(使用Deployment而不直接創(chuàng)建ReplicaSet是因?yàn)镈eployment對(duì)象擁有許多ReplicaSet沒(méi)有的特性,例如滾動(dòng)升級(jí)和回滾)。

一個(gè)最簡(jiǎn)單的nginx應(yīng)用,其Deployment文件如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  # 如果被指定, .spec.selector 必須匹配 .spec.template.metadata.labels,否則它將被API拒絕。如果 .spec.selector 沒(méi)有被指定, .spec.selector.matchLabels 默認(rèn)是 .spec.template.metadata.labels。
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: frontend
spec:
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 3
      maxUnavailable: 2
  replicas: 25
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google-samples/gb-frontend:v4
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
          # If your cluster config does not include a dns service, then to
          # instead access environment variables to find service host
          # info, comment out the 'value: dns' line above, and uncomment the
          # line below:
          # value: env
        ports:
        - containerPort: 80

通過(guò)kubectl create -f nginx-deployment.yaml命令或者kubectl apply -f nginx-deployment.yaml命令創(chuàng)建名為nginx-deployment的Deployment對(duì)象。

通過(guò)Deployment對(duì)象,你可以輕松的做到以下事情:

  • 創(chuàng)建ReplicaSet和Pod
  • 滾動(dòng)升級(jí)(不停止舊服務(wù)的狀態(tài)下升級(jí))和回滾應(yīng)用(將應(yīng)用回滾到之前的版本)
  • 平滑地?cái)U(kuò)容和縮容
  • 暫停和繼續(xù)Deployment

2. Deployment的創(chuàng)建

以上面的nginx-deployment.yaml文件為例,使用以下命令創(chuàng)建一個(gè)nginx的
Deployment:

kubectl create -f nginx-deployment.yaml --record

--record參數(shù)可以記錄當(dāng)前版本的Deployment都執(zhí)行過(guò)哪些命令。

創(chuàng)建完成后立即執(zhí)行g(shù)et命令可以查看這個(gè)Deployment:

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

NAME代表Deployment的名字,DESIRED代表這個(gè)Deployment期望的副本數(shù)量,CURRENT代表當(dāng)前已經(jīng)創(chuàng)建了的副本數(shù)量,UP-TO-DATE代表已經(jīng)更新完成的副本數(shù)量,AVAILABLE代表對(duì)于當(dāng)前用戶可用的副本數(shù)量,AGE代表當(dāng)前Deployment已經(jīng)運(yùn)行的時(shí)長(zhǎng)。

等待幾秒鐘,再次運(yùn)行g(shù)et命令,可以查看到變化:

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

通過(guò)kubectl get rs來(lái)查看系統(tǒng)中ReplicaSet對(duì)象,由此可以看出Deployment會(huì)自動(dòng)創(chuàng)建一個(gè)ReplicaSet對(duì)象。

通過(guò)kubectl get pods --show-labels命令來(lái)查看當(dāng)前系統(tǒng)中的Pod對(duì)象,可以成功觀察到nginx-deployment創(chuàng)建的3個(gè)Pod。

3. Deployment的更新

假如我們現(xiàn)在想要讓 nginx pod 使用 nginx:1.9.1 的鏡像來(lái)代替原來(lái)的 nginx:1.7.9 的鏡像,運(yùn)行以下命令:

kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

或者我們可以使用 edit 命令來(lái)編輯 Deployment,將image從nginx:1.7.9 改寫成 nginx:1.9.1。

kubectl edit deployment/nginx-deployment

查看更新進(jìn)度:

$ 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

擴(kuò)容:

kubectl scale deployment nginx-deployment --replicas 10

如果集群支持 horizontal pod autoscaling 的話,還可以為 Deployment 設(shè)置自動(dòng)擴(kuò)展:

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

Deployment更新時(shí)會(huì)創(chuàng)建一個(gè)新的ReplicaSet,然后將新的ReplicaSet中的Pod慢慢擴(kuò)容到指定的副本數(shù),將舊的ReplicaSet慢慢縮容到0。因此,更新時(shí)總能夠確保舊的服務(wù)不會(huì)停止,這就是滾動(dòng)更新。

4. Deployment的回滾

當(dāng)我們像上文一樣更新了Deployment之后,我們發(fā)現(xiàn)nginx:1.9.1的鏡像不是很穩(wěn)定,因此想要修改回nginx:1.7.9的版本,此時(shí)我們不需要手動(dòng)更改Deployment文件,而是利用Deployment的回滾功能。

使用rollout history命令查看Deployment的版本(revision):

$ kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment":
REVISION    CHANGE-CAUSE
1           kubectl create -f docs/user-guide/nginx-deployment.yaml --record
2           kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

因?yàn)槲覀儎?chuàng)建 Deployment 的時(shí)候使用了 —recored 參數(shù)可以記錄命令,我們可以很方便的查看每次 revison 的變化。

查看單個(gè) revision 的詳細(xì)信息:

kubectl rollout history deployment/nginx-deployment --revision=2

現(xiàn)在,可以使用rollout undo命令回滾到前一個(gè)revision:

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

也可以使用--to-revision參數(shù)指定某個(gè)歷史版本:

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

你可以通過(guò)設(shè)置 .spec.revisonHistoryLimit 項(xiàng)來(lái)指定 deployment 最多保留多少 revison 歷史記錄。默認(rèn)的會(huì)保留所有的 revision;如果將該項(xiàng)設(shè)置為 0,Deployment 就不允許回退了。

只有 Deployment 的 rollout 被觸發(fā)才會(huì)創(chuàng)建一個(gè) revision!注意!當(dāng)且僅當(dāng) Deployment 的 Pod template被更改,例如更新 template 中的 label 和容器鏡像時(shí),才會(huì)觸發(fā)一個(gè)rollout,從而為Deployment創(chuàng)建出一個(gè)新的 revision。

rollout命令的更多用法:

  • history(查看歷史版本)
  • pause(暫停Deployment)
  • resume(恢復(fù)暫停的Deployment)
  • status(查看資源狀態(tài))
  • undo(回滾版本)

滾動(dòng)更新相關(guān)配置:

  • .spec.minReadySeconds: 新創(chuàng)建的Pod狀態(tài)為Ready持續(xù)的時(shí)間至少為.spec.minReadySeconds才認(rèn)為Pod Available(Ready)。
  • .spec.strategy.rollingUpdate.maxSurge: specifies the maximum number of Pods that can be created over the desired number of Pods. The value cannot be 0 if MaxUnavailable is 0. 可以為整數(shù)或者百分比,默認(rèn)為desired Pods數(shù)的25%. Scale Up新的ReplicaSet時(shí),按照比例計(jì)算出允許的MaxSurge,計(jì)算時(shí)向上取整(比如3.4,取4)。
  • .spec.strategy.rollingUpdate.maxUnavailable: specifies the maximum number of Pods that can be unavailable during the update process. The value cannot be 0 if maxSurge is 0.可以為整數(shù)或者百分比,默認(rèn)為desired Pods數(shù)的25%. Scale Down舊的ReplicaSet時(shí),按照比例計(jì)算出允許的maxUnavailable,計(jì)算時(shí)向下取整(比如3.6,取3)。

因此,在Deployment rollout時(shí),需要保證Available(Ready) Pods數(shù)不低于 desired pods number - maxUnavailable; 保證所有的Pods數(shù)不多于 desired pods number + maxSurge。

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

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

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