K8s Deployment

Deployment是ReplicaSet的升級(jí)版,支持在恒定速度的之下從一個(gè)狀態(tài)轉(zhuǎn)移到另一個(gè)狀態(tài)(滾動(dòng)升級(jí))。

和ReplicaSet Replication Controller的不同之處

ReplicaSet 和Replication Controller 也支持rollout update,但是存在問(wèn)題

kubectl rolling-update kubia-v1 kubia-v2 --image=luksa/kubia:v2

存在的問(wèn)題是rollout過(guò)程歸client端控制而不是server。如果在rollout過(guò)程中kubectl和server失去聯(lián)系,整個(gè)rollout會(huì)出現(xiàn)問(wèn)題。

Deployment的rollout過(guò)程歸server控制,不存在上述的問(wèn)題。

Deployment的實(shí)現(xiàn)依賴ReplicaSet(仍會(huì)創(chuàng)建ReplicaSet),Deployment是ReplicaSet的封裝。

Deployment可以做到什么

  • Delpoyment控制ReplicaSet的滾動(dòng)升級(jí)
  • 通過(guò)修改podTemplate的方式來(lái)滾動(dòng)升級(jí)(使用配置的速度限制滾動(dòng)升級(jí))
  • 回滾到更早的Deployment版本
  • 暫停和恢復(fù)Delpoyment滾動(dòng)升級(jí)過(guò)程

創(chuàng)建Deployment

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

以上配置:

  • 創(chuàng)建了一個(gè)名字為nginx-deployment的Deployment
  • 管理的pod具有app: nginx標(biāo)簽
  • 創(chuàng)建的pod具有3個(gè)副本
  • pod使用的鏡像為nginx:1.7.9

查看運(yùn)行的Deployment

kubectl get deployments

輸出表格有如下幾列:

  • NAME:集群中的deployments名稱
  • READY:目前已運(yùn)行pod/期待運(yùn)行多少個(gè)replicas
  • UP-TO-DATE: 已經(jīng)達(dá)到期待狀態(tài)的replica數(shù)目
  • AVAILABLE:application有多少個(gè)副本可用(啟動(dòng)完畢)
  • AGE:application已啟動(dòng)多長(zhǎng)時(shí)間

查看Deployment的細(xì)節(jié)

kubectl describe deployments

創(chuàng)建Deployment

kubectl create -f kubia-deployment-v1.yaml --record

--record會(huì)記錄deployment的歷史revision。

相關(guān)的修改命令會(huì)記錄在pod的kubernetes.io/change-cause annotation中。

pod-template-hash

查看pod-template-hash

kubectl get pods --show-labels
kubectl get rs --show-labels

Deployment自己創(chuàng)建的ReplicaSet以及pod的label會(huì)帶有一段hash,即pod-template-hash。它的作用為確保歸此deployment管理的ReplicaSet和pod不會(huì)和其他的發(fā)生沖突。

觸發(fā)滾動(dòng)升級(jí)

滾動(dòng)升級(jí)當(dāng)且僅當(dāng)在pod template修改之后才會(huì)觸發(fā)。

修改鏡像版本

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

或者是編輯deployment描述文件

kubectl edit deployment.v1.apps/nginx-deployment

Label selector 修改

  • 增加新的label:要求pod template的label和deployment的spec同步增加,否則會(huì)報(bào)錯(cuò)。新的selector并不會(huì)選定原先創(chuàng)建出來(lái)的ReplicaSet和Pod,他們會(huì)被孤立(不歸deployment管理),deployment接下來(lái)創(chuàng)建出新的ReplicaSet和Pod。
  • selector修改:和新增label相同。
  • selector刪除(減少label):不要求pod template隨著改變。執(zhí)行之后舊的ReplicaSet和Pod會(huì)保持不變,被移除的label在就的ReplicaSet和Pod中仍存在。不會(huì)創(chuàng)建出新的ReplicaSet,舊的ReplicaSet和Pod也不會(huì)孤立。

獲取滾動(dòng)升級(jí)狀態(tài)

kubectl rollout status deployment/nginx-deployment
# 或
kubectl rollout status deployment.apps/nginx-deployment
# 或
kubectl rollout status deployment.v1.apps/nginx-deployment

Deployment rollout過(guò)程

pod被update之后,deployment會(huì)創(chuàng)建新的replicaSet,并且逐步scale到配置的replica數(shù)。同時(shí)老的replicaSet會(huì)逐步scale到0。

如果在rollout過(guò)程中pod發(fā)生了更新,不會(huì)等到老的replicaSet scale到 desired state(達(dá)到指定的replica數(shù)量),會(huì)立刻開始scale到0的過(guò)程。

新的pod狀態(tài)變?yōu)閞eady或available(至少需要等待MinReadySeconds)。

查看deployment rollout歷史

kubectl rollout history deployment.v1.apps/nginx-deployment

輸入類似如下界面:

deployments "nginx-deployment"
REVISION    CHANGE-CAUSE
1           kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true
2           kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
3           kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true

可以通過(guò)如下方式指定CHANGE-CAUSE:

  • 增加deployment的annotation,類似于kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.9.1"
  • 修改Deployment的時(shí)候附帶--record參數(shù)
  • 手工修改資源的manifest信息

查看某一個(gè)revision更具體的信息

kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2

回滾到上一個(gè)版本

kubectl rollout undo deployment.v1.apps/nginx-deployment

回滾到指定revision

kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2

動(dòng)態(tài)擴(kuò)展deployment

kubectl scale deployment.v1.apps/nginx-deployment --replicas=10

水平自動(dòng)擴(kuò)展

kubectl autoscale deployment.v1.apps/nginx-deployment --min=10 --max=15 --cpu-percent=80

百分比擴(kuò)展

在滾動(dòng)升級(jí)的過(guò)程中,新老版本的pod同時(shí)在運(yùn)行。如果在升級(jí)過(guò)程尚未完成之時(shí)調(diào)大replica數(shù)值,比如說(shuō)增加5。由于百分比擴(kuò)展特性的存在,這新增的5個(gè)replica不會(huì)都分配給新的ReplicaSet,而是按照比例同時(shí)分配給新老ReplicaSet,新的ReplicaSet占比多,老的ReplicaSet占比少。以新增5個(gè)replica為例,新的ReplicaSet會(huì)增加3,老的ReplicaSet會(huì)增加2。

暫停rollout

kubectl rollout pause deployment.v1.apps/nginx-deployment

繼續(xù)rollout

kubectl rollout resume deployment.v1.apps/nginx-deployment

以watch狀態(tài)觀察rollout過(guò)程

kubectl get rs -w

minReadySeconds

pod至少多久之后才會(huì)被認(rèn)為可用。

只有在時(shí)間超過(guò)minReadySeconds,并且readness probe檢測(cè)狀態(tài)正常的時(shí)候,pod才會(huì)被k8s認(rèn)為是可用的,滾動(dòng)升級(jí)才會(huì)進(jìn)行。

progressDeadlineSeconds

增加deployment部署時(shí)間超時(shí)限制。

kubectl patch deployment.v1.apps/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'

Deployment超時(shí)的時(shí)候k8s不會(huì)自動(dòng)處理,只會(huì)返回狀態(tài)值Reason=ProgressDeadlineExceeded

Rollout時(shí)候暫停,k8s不會(huì)檢查部署超時(shí)限制(progressDeadlineSeconds),因此不用擔(dān)心rollout恢復(fù)操作的時(shí)候超時(shí)。

DEPLOYMENT STRATEGIES

  • Recreate 刪除所有的舊pod,再創(chuàng)建新的pod。中間服務(wù)會(huì)不可用。
  • RollingUpdate 滾動(dòng)升級(jí),默認(rèn)值。
spec:
    strategy:
        rollingUpdate:
            maxSurge: 1
            maxUnavailable: 0
        type: RollingUpdate

RollingUpdate參數(shù)解釋(英文描述還是比較精確的,因此從官網(wǎng)摘抄下來(lái)):

  • maxSurge: Determines how many pod instances you allow to exist above the desired replica count configured on the Deployment. It defaults to 25%, so there can be at most 25% more pod instances than the desired count. If the desired replica count is set to four, there will never be more than five pod instances running at the same time during an update. When converting a percentage to an absolute number, the number is rounded up. Instead of a percentage, the value can also be an absolute value (for example, one or two additional pods can be allowed).
  • maxUnavailable: Determines how many pod instances can be unavailable relative to the desired replica count during the update. It also defaults to 25%, so the number of available pod instances must never fall below 75% of the desired replica count. Here, when converting a percentage to an absolute number, the number is rounded down. If the desired replica count is set to four and the percentage is 25%, only one pod can be unavailable. There will always be at least three pod instances available to serve requests during the whole rollout. As with maxSurge, you can also specify an absolute value instead of a percentage.

個(gè)人對(duì)應(yīng)的理解為:

  • maxSurge:滾動(dòng)升級(jí)是一個(gè)新的ReplicaSet逐漸擴(kuò)容,舊的ReplicaSet逐漸縮容的過(guò)程。在這個(gè)過(guò)程中為了保障服務(wù)不被中斷,同時(shí)又希望同時(shí)啟動(dòng)更多的新版本pod,允許在這個(gè)期間,同時(shí)運(yùn)行的replica數(shù)量超過(guò)Deployment配置的replica數(shù)。這個(gè)超出數(shù)量的上限值為maxSurge。它的默認(rèn)值為25%。maxSurge既可以配置百分比(計(jì)算出的replica數(shù)量向上取整),也可以配置具體replica個(gè)數(shù)。
  • maxUnavailable:在滾動(dòng)升級(jí)過(guò)程中,新的pod不可能很快的啟動(dòng)完畢,進(jìn)入到能夠?qū)ν馓峁┓?wù)的狀態(tài)。但是為了加快滾動(dòng)升級(jí)的速度,k8s會(huì)盡可能同時(shí)啟動(dòng)最多的新版本pod。由于maxSurge的限制,同時(shí)啟動(dòng)的新版本pod不可能無(wú)限多。在保障業(yè)務(wù)不中斷(此時(shí)服務(wù)主要由舊的pod支撐)的情況下,k8s會(huì)kill掉一些舊的pod,騰出盡量多的replica余額來(lái)啟動(dòng)新的pod。在這個(gè)過(guò)程中系統(tǒng)需要保證無(wú)法對(duì)外提供服務(wù)的pod數(shù)量(未完成啟動(dòng)過(guò)程的pod數(shù)量)不得超過(guò)maxUnavailable。如果maxUnavailable配置的為百分比,含義為無(wú)法提供服務(wù)的pod占Deployment配置的replica數(shù)量的比例不得大于maxUnavailable。maxUnavailable的默認(rèn)值為25%。
?著作權(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)容