Kubernetes學習筆記(八):Deployment--聲明式的升級應用

概述

本文核心問題是:如何升級應用。
對於Pod的更新有兩種策略:html

  • 一是刪除所有舊Pod以後再建立新Pod。好處是,同一時間只會有一個版本的應用存在;缺點是,應用有一段時間不可用。
  • 二是先建立新Pod,再刪除舊Pod。能夠一次性建立所有,再刪除所有,也能夠逐漸建立刪除。好處是應用一直可用,缺點是要同時支持兩個版本。

藍綠部署

對於應用的版本v1和版本v2:node

  • 在運行v1前,流量一直都在v2上
  • 部署v1,而後測試經過後,將流量切換到v2,v2就成爲了新的生產環境
  • 一旦v2出現問題,能夠在切回v1

金絲雀部署(也稱灰度部署)

金絲雀部署一種增量發佈,先是在小範圍內發佈,而後觀察測試,如無問題逐漸發佈所有。web

kubectl rolling-update

由於kubectl rolling-update的方式已通過時,因此只是作一下簡介。
假設如今有一個名爲test-v1,Pod選擇器爲app=order的ReplicationController要升級爲test-v2,則執行下面命令可升級:docker

k rolling-update test-v1 test-v2 --image=test:v2

運行此命令後:json

  1. 馬上建立一個名爲test-v2的ReplicationController,他的Pod模板鏡像正是test:v2,並添加一個標籤deployment=xxxx
  2. test-v1以及app=order選中的Pod都會被加上一個標籤:deployment=yyyy。如此作法是防止Pod的管理混亂。
  3. 先將test-v2的Pod擴展爲1,使用更新後的模板建立新Pod;再將test-v1縮小1,如此循環。
  4. 由於在滾動過程當中Service的標籤選擇器一直是app=order,因此新老版本都會接收到流量。

過期的緣由是:伸縮的請求時由kubectl發起的,若是由於任何緣由丟失了網絡鏈接,升級將處於中間狀態。另外一個緣由是:指望只修改Pod定義中的鏡像tag,就能時Kubernetes運行升級工做api

使用Deployment聲明式的升級

Deployment是一種更高階的資源,用於部署程序並以聲明的方式升級應用,而不是經過ReplicationController或ReplicaSet進行部署。網絡

在使用Deployment時,Pod是由Deployment的ReplicaSet建立的。app

準備鏡像

將以前的文章(Kubernetes學習筆記(四):服務)裏的拿過來作一下微小的改動,生成兩個鏡像。改動內容就是在輸出內容加上版本號。curl

fmt.Fprintf(w,"this is v1, hostname: %v\n",hostname)
docker push registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v1

fmt.Fprintf(w,"this is v2, hostname: %v\n",hostname)
docker push registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v2

建立Deployment

Deployment與ReplicaSet的配置類似,都含有標籤選擇器、副本數量和Pod模板。此外Deployment還會包含一個部署策略。編輯器

定義Service

定義了一個NodePort類型的Service

# goweb-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: goweb
spec:
  type: NodePort
  selector:
    app: goweb
  ports:
    - port: 80
      targetPort: 8000
      nodePort: 31234

定義Deployment

# goweb-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb
spec:
  replicas: 3
  selector:
    matchLabels:
      app: goweb
  template:
    metadata:
      labels:
        app: goweb
    spec:
      containers:
      - name: goweb
        image: registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v1

運行查看

能夠看到名爲goweb-fdfcfdcc6的RS,有個label是pod-template-hash=fdfcfdcc6,顧名思義,fdfcfdcc6就是pod模板的hash值。

建立Deployment時指定 --record 記錄歷史版本號,很是有用

-> [root@kube0.vm] [~] k create -f goweb-svc.yaml
service/goweb created

-> [root@kube0.vm] [~] k create -f goweb-deployment.yaml --record

deployment.apps/goweb created
-> [root@kube0.vm] [~] k get all -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
pod/goweb-fdfcfdcc6-4wklw   1/1     Running   0          9s    10.244.2.37   kube2.vm   <none>           <none>
pod/goweb-fdfcfdcc6-bw8c4   1/1     Running   0          9s    10.244.2.36   kube2.vm   <none>           <none>
pod/goweb-fdfcfdcc6-xjcwf   1/1     Running   0          9s    10.244.1.33   kube1.vm   <none>           <none>

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
service/goweb        NodePort    10.100.193.94   <none>        80:31234/TCP   28s   app=goweb
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        54s   <none>

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                                            SELECTOR
deployment.apps/goweb   3/3     3            3           9s    goweb        registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v1   app=goweb

NAME                              DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                                            SELECTOR
replicaset.apps/goweb-fdfcfdcc6   3         3         3       9s    goweb        registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v1   app=goweb,pod-template-hash=fdfcfdcc6

升級Deployment

只要修改Deployment的Pod模板定義,Kubernetes會自動的將實際狀態收斂爲修改後的狀態。對於升級,只須要修改Pod中鏡像的tag。

升級策略由deployment.spec.strategy.type定義,值是Recreate或RollingUpdate,默認RollingUpdate。

kubectl patch及minReadySeconds

使用kubectl patch定義deployment.spec.minReadySeconds來減慢滾動升級時間,以便觀察升級過程

-> [root@kube0.vm] [~] k patch deployment goweb -p '{"spec":{"minReadySeconds":5}}'
deployment.apps/goweb patched

循環請求服務

在執行升級前新開窗口,運行下面的命令查看輸出

-> [root@kube0.vm] [~] while true; do curl http://192.168.199.231:31234/ ; sleep 1; done
this is v1, hostname: goweb-fdfcfdcc6-pw7b4
this is v1, hostname: goweb-fdfcfdcc6-pw7b4
this is v1, hostname: goweb-fdfcfdcc6-x8n7h
this is v1, hostname: goweb-fdfcfdcc6-pw7b4
this is v1, hostname: goweb-fdfcfdcc6-x8n7h
this is v1, hostname: goweb-fdfcfdcc6-j4mz8
this is v1, hostname: goweb-fdfcfdcc6-j4mz8
# 以上是升級以前的輸出、如下是開始升級後的
this is v1, hostname: goweb-fdfcfdcc6-x8n7h
this is v1, hostname: goweb-fdfcfdcc6-pw7b4
this is v1, hostname: goweb-fdfcfdcc6-pw7b4
this is v1, hostname: goweb-fdfcfdcc6-j4mz8
this is v2, hostname: goweb-65cc575865-25988
this is v2, hostname: goweb-65cc575865-25988
this is v1, hostname: goweb-fdfcfdcc6-x8n7h
this is v1, hostname: goweb-fdfcfdcc6-j4mz8
this is v2, hostname: goweb-65cc575865-bfd98
this is v2, hostname: goweb-65cc575865-bfd98
this is v2, hostname: goweb-65cc575865-25988
this is v2, hostname: goweb-65cc575865-25988
this is v2, hostname: goweb-65cc575865-25988
# 這以後就是升級完成了

kubectl set

使用 kubectl set image 更新任何包含容器資源的鏡像。

-> [root@kube0.vm] [~] k set image deployment goweb goweb=registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v2
deployment.apps/goweb image updated

kubectl rollout

查看升級狀態信息。執行完kubectl set image,馬上執行下面的命令。手速得快,否則趕不上熱乎的。

-> [root@kube0.vm] [~] k rollout status deployment goweb
Waiting for deployment "goweb" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "goweb" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "goweb" rollout to finish: 1 old replicas are pending termination...
deployment "goweb" successfully rolled out

修改Deployment或其餘資源的方式

方法 做用
kubectl edit 使用編輯器打開資源配置
kubectl patch 在命令行以merge的方式修改配置
kubectl apply 經過yaml或者json文件,修改新改動的值。若是指定的對象不存在則建立。
kubectl replace 使用yaml或者json文件替換一個必須已存在的對象配置。
kubectl set image 修改鏡像

回滾

使用kubectl rollout undo 回滾到上一個版本

-> [root@kube0.vm] [~] k rollout undo deployment goweb
deployment.apps/goweb rolled back

使用 kubectl rollout history 查看版本記錄

-> [root@kube0.vm] [~] k rollout history deployment goweb
deployment.apps/goweb
REVISION  CHANGE-CAUSE
6         kubectl create --filename=goweb-deployment.yaml --record=true
7         kubectl create --filename=goweb-deployment.yaml --record=true

回滾到特定版本

-> [root@kube0.vm] [~] k rollout undo deployment goweb --to-revision=5
error: unable to find specified revision 5 in history

-> [root@kube0.vm] [~] k rollout undo deployment goweb --to-revision=7
deployment.apps/goweb skipped rollback (current template already matches revision 7)

-> [root@kube0.vm] [~] k rollout undo deployment goweb --to-revision=6
deployment.apps/goweb rolled back

經過deployment.spec.revisionHistoryLimit指定歷史版本個數,默認爲2。也就是當前和上一個版本。

控制滾動升級速率

deployment.spec.strategy.rollingUpdate下有兩個字段,用來控制升級速率

  • maxSurge:超出指望副本數的Pod實例的比例或個數。默認25%,轉換成絕對值後四捨五入,也能夠直接指定爲絕對值。
  • maxUnavailable:滾動升級時,最多容許有多少實例不可用,默認25%,轉換成絕對值後四捨五入,也能夠直接指定爲絕對值。

暫停、恢復升級

  • 使用kubectl rollout pause暫停升級
  • 使用kubectl rollout resume取消暫停

阻止出錯版本的滾動升級

  • minReadySeconds:指定新建立的Pod至少要運行多久才視爲可用。
  • 配置就緒探針
  • 爲滾動升級配置progressDeadlineSeconds

小結

  • kubectl rolling-update 過期的緣由:伸縮的請求時由kubectl發起的,若是由於任何緣由丟失了網絡鏈接,升級將處於中間狀態
  • Deployment是一種更高階的資源,用於部署程序並以聲明的方式升級應用,而不是經過ReplicationController或ReplicaSet進行部署。
  • 建立Deployment時指定 --record 記錄歷史版本號
  • Deployment下的ReplicaSet命名是DeploymentName+Pod模板Hash,而ReplicaSet下的Pod是在此基礎拼接個隨機字符串。
  • 升級策略由deployment.spec.strategy.type定義,值是Recreate或RollingUpdate,默認RollingUpdate。
  • 定義deployment.spec.minReadySeconds來減慢滾動升級時間
  • maxSurge與maxUnavailable控制滾動升級速率
  • 命令:patch、set、rollout
  • kubectl rollout:status、undo、pause、resume、history。
相關文章
相關標籤/搜索