Kubernetes-Deployment


1. 簡介

一個 DeploymentPodsReplicaSets 提供聲明式的更新能力。

用戶負責描述 Deployment 中的 目標狀態,而 Deployment 控制器(Controller)以受控速率更改實際狀態, 使其變為期望狀態。你可以定義 Deployment 以創建新的 ReplicaSet,或刪除現有 Deployment, 並通過新的 Deployment 收養其資源。

ReplicaSet 的目的是維護一組在任何時候都處於運行狀態的 Pod 副本的穩定集合。 因此,它通常用來保證給定數量的、完全相同的 Pod 的可用性。

也就是 Deployment 通過管理 ReplicaSet 來確保任何時間都有指定數量的 Pod 副本在運行。

2. quick start

2.1 創建deploy

如果沒有現成的模板,可以使用 --dry-run 快速生成一個deploy資源模板

$ kubectl create deploy nginx-test --image=nginx --dry-run=client --replicas=3  -oyaml -n test1

# 輸出內容如下
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx-test
  name: nginx-test
  namespace: test1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-test
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx-test
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

新建一個deploy模板 deploy-nginx.yaml,內容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    # 自定義標簽
    app: nginx-deploy-test
  # 資源名稱
  name: nginx-test-1
  namespace: test1
spec:
  # pod 副本數量
  replicas: 3
  # 模板選擇器
  selector:
    matchLabels:
      # 選擇下方聲明的 template
      app: nginx-test
  template:
    metadata:
      labels:
        app: nginx-test
    spec:
      containers:
      - image: nginx
        name: nginx

創建deploy

$ kubectl create -f deploy-nginx.yaml

在該例中:

  • 創建名為nginx-test-1(由 .metadata.name 字段標明)的 deployment
  • 該deployment創建三個(由 replicas 字段標明)Pod副本
  • selector 字段定義 Deployment 如何查找要管理的 Pods。 在這里,選擇在 Pod 模板中定義的標簽(app: nginx-test)。 不過,更復雜的選擇規則是也可能的,只要 Pod 模板本身滿足所給規則即可。
  • template字段包含以下子字段:
    • Pod 被使用 labels 字段打上 app: nginx-test 標簽。
    • Pod 模板約定(即 .template.spec 字段) Pods nginx 容器。
    • 創建一個容器並使用 name 字段將其命名為 nginx

說明:

spec.selector.matchLabels 字段是 {key,value} 鍵值對映射。 在 matchLabels 映射中的每個 {key,value} 映射等效於 matchExpressions 中的一個元素, 即其 key 字段是 “key”,operator 為 “In”,values 數組僅包含 “value”。 在 matchLabelsmatchExpressions 中給出的所有條件都必須滿足才能匹配。

2.2 查看deploy

查看deploy 基本信息

# kubectl get -f deploy-nginx.yaml
$ kubectl get deploy -n test1

NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-test-1   3/3     3            3           4m20s

查看deploy 詳細信息

# kubectl get -f deploy-nginx.yaml -o wide
$ kubectl get deploy -n test1 -o wide

NAME           READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES   SELECTOR
nginx-test-1   3/3     3            3           4m54s   nginx        nginx    app=nginx-test

查看deploy 詳情信息

# kubectl describe deploy/nginx-test-1 -n test1
$ kubectl describe -f deploy-nginx.yaml

Name:                   nginx-test-1
Namespace:              test1
CreationTimestamp:      Sun, 12 Dec 2021 22:38:12 +0800
Labels:                 app=nginx-deploy-test
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=nginx-test
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-test
  Containers:
   nginx:
    Image:        nginx
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-test-1-795d659f45 (3/3 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  6m58s  deployment-controller  Scaled up replica set nginx-test-1-795d659f45 to 3

查看pod情況

$ kubectl get po -n test1

NAME                            READY   STATUS    RESTARTS   AGE
nginx-test-1-795d659f45-7rlq7   1/1     Running   0          15m
nginx-test-1-795d659f45-dfjfb   1/1     Running   0          15m
nginx-test-1-795d659f45-m45qn   1/1     Running   0          15m

查看deploy上線狀態

$ kubectl rollout status deploy/nginx-test-1 -n test1

deployment "nginx-test-1" successfully rolled out

2.3 修改deploy

說明: 僅當 Deployment Pod 模板(即 .spec.template)發生改變時,例如模板的標簽或容器鏡像被更新, 才會觸發 Deployment 上線。 其他更新(如對 Deployment 執行擴縮容的操作)不會觸發上線動作。

  1. 直接修改資源模板,修改完直接apply即可

    $ kubectl apply -f deploy-nginx.yaml
    
  2. 使用命令修改,修改完保存即可

    $ kubectl edit deploy/nginx-test-1 -n test1
    
  3. 修改鏡像版本

    • --record=true 記錄當前操作,后續會用到
    $ kubectl set image deploy/nginx-test-1 nginx=nginx:1.16.1 -n test1 --record=true
    

2.4 刪除deploy

  1. 使用命令刪除

    $ kubectl delete deploy/nginx-test-1 -n test1
    
  2. 使用資源文件

    $ kubectl delete -f deploy-nginx.yaml
    

3. 更新服務版本

3.1 創建deploy

deploy-nginx.yaml deploy 模板信息如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy-test
  name: nginx-test-1
  namespace: test1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-test
  template:
    metadata:
      labels:
        app: nginx-test
    spec:
      containers:
      - image: nginx:1.16.1
        name: nginx

3.2 修改deploy文件更新

# 修改模板文件中的鏡像版本號
$ sed -i 's/nginx:1.16.1/nginx:latest/g' deploy-nginx.yaml
# 應用修改后的模板文件
# --record的作用是將當前命令記錄到 revision 記錄中,這樣就可以知道每個 revison 對應的是哪個配置文件。
$ kubectl apply -f deploy-nginx.yaml --record

我們從圖中可以看到pod執行過程是等待新的pod啟動完成,在進行銷毀舊的pod,這樣就完成了集群的滾動更新工作

更新完成后我們也可以查看一下迭代信息和修訂歷史詳細信息

3.2 使用edit命令更新

$ kubectl edit deploy/nginx-test-1 -n test1

deployment.apps/nginx-test-1 edited

一般臨時修改一下部署信息會使用一下edit。

一般不太推薦使用edit進行編輯,推出即保存。雖然版本更新成功了,history也有保留,但是最終的修改記錄沒有持久化到模板文件中。

3.3 使用set image 命令更新

# nginx=nginx:1.16.1 <container-name>=<image-name>:<version>
$ kubectl set image deploy/nginx-test-1 -n test1 nginx=nginx:1.16.1 --record

能比edit更新強點,至少可以很清楚的在history中查看版本更新的情況

4. 回滾服務版本

我們使用上面的更新應用時k8s都會記錄一個revision(版本),這樣我們就可以通過這個版本記錄回滾到特定的版本中

說明: Deployment 被觸發上線時,系統就會創建 Deployment 的新的修訂版本。 這意味着僅當 Deployment 的 Pod 模板(.spec.template)發生更改時,才會創建新修訂版本 -- 例如,模板的標簽或容器鏡像發生變化。 其他更新,如 Deployment 的擴縮容操作不會創建 Deployment 修訂版本。 這是為了方便同時執行手動縮放或自動縮放。 換言之,當你回滾到較早的修訂版本時,只有 Deployment 的 Pod 模板部分會被回滾。

  1. 回滾到上一個版本

    $ kubectl rollout undo deploy/nginx-test-1  -n test1
    
  2. 回滾到指定版本

    $ kubectl rollout undo deploy/nginx-test-1 --to-revision=3 -n test1
    

rollout命令參數如下

$ kubectl rollout -h
Manage the rollout of a resource.

 Valid resource types include:

  *  deployments
  *  daemonsets
  *  statefulsets

Examples:
  # Rollback to the previous deployment
  kubectl rollout undo deployment/abc

  # Check the rollout status of a daemonset
  kubectl rollout status daemonset/foo

Available Commands:
  history     顯示 rollout 歷史
  pause       標記提供的 resource 為中止狀態
  restart     Restart a resource
  resume      繼續一個停止的 resource
  status      顯示 rollout 的狀態
  undo        撤銷上一次的 rollout

Usage:
  kubectl rollout SUBCOMMAND [options]

默認配置下,k8s 只會保留最近的幾個 revision,可以在 Deployment 配置文件中通過 revisionHistoryLimit 屬性增加 revision 數量。(同時rs和我們rollout中記錄的版本號相同,可以理解為rollout中顯示的REVISION版本號實際上就是rs中的版本)

revisionHistoryLimit(歷史版本記錄):Deployment revision history存儲在它控制的ReplicaSets中。默認保存記錄10個     .spec.revisionHistoryLimit 是一個可選配置項,用來指定可以保留的舊的ReplicaSet數量。
    該理想值取決於心Deployment的頻率和穩定性。如果該值沒有設置的話,默認所有舊的Replicaset或會被保留,將資源存儲在etcd中,是用kubectl get rs查看輸出。
    每個Deployment的該配置都保存在ReplicaSet中,然而,一旦刪除的舊的RepelicaSet,Deployment就無法再回退到那個revison了。   
    如果將該值設置為0,所有具有0個replica的ReplicaSet都會被刪除。在這種情況下,新的Deployment rollout無法撤銷,因為revision history都被清理掉了。 PS:為了保存版本升級的歷史,需要再創建Deployment對象時,在命令中使用"record"選項

一般配合revisionHistoryLimit使用的strategy (更新策略)

strategy(更新策略):  
    .spec.strategy 指定新的Pod替換舊的Pod的策略。 .spec.strategy.type 可以是"Recreate"或者是 "RollingUpdate"。"RollingUpdate"是默認值。  
    Recreate: 重建式更新,就是刪一個建一個。類似於ReplicaSet的更新方式,即首先刪除現有的Pod對象,然后由控制器基於新模板重新創建新版本資源對象。   
    rollingUpdate:滾動更新,簡單定義 更新期間pod最多有幾個等。可以指定maxUnavailable 和 maxSurge 來控制 rolling update 進程。   
    maxSurge:.spec.strategy.rollingUpdate.maxSurge 是可選配置項,用來指定可以超過期望的Pod數量的最大個數。該值可以是一個絕對值(例如5)或者是期望的Pod數量的百分比(例如10%)。如果 MaxUnavailable 為 0,則此值不能為 0。百分比值會通過向上取整轉換為絕對數。 此字段的默認值為 25%。   
    例如,該值設置成30%,啟動rolling update后新的ReplicatSet將會立即擴容,新老Pod的總數不能超過期望的Pod數量的130%。舊的Pod被殺掉后,新的ReplicaSet將繼續擴容,舊的ReplicaSet會進一步縮容,確保在升級的所有時刻所有的Pod數量和不會超過期望Pod數量的130%。   
    maxUnavailable:.spec.strategy.rollingUpdate.maxUnavailable 是可選配置項,用來指定在升級過程中不可用Pod的最大數量。該值可以是一個絕對值(例如5),也可以是期望Pod數量的百分比(例如10%)。通過計算百分比的絕對值向下取整。如果.spec.strategy.rollingUpdate.maxSurge 為0時,則此值不能為 0。 默認值為 25%。   
    例如,該值設置成30%,啟動rolling update后舊的ReplicatSet將會立即縮容到期望的Pod數量的70%。新的Pod ready后,隨着新的ReplicaSet的擴容,舊的ReplicaSet會進一步縮容確保在升級的所有時刻可以用的Pod數量至少是期望Pod數量的70%。 PS:maxSurge和maxUnavailable的屬性值不可同時為0,否則Pod對象的副本數量在符合用戶期望的數量后無法做出合理變動以進行更新操作。   
    在配置時,用戶還可以使用Deployment控制器的spec.minReadySeconds屬性來控制應用升級的速度。新舊更替過程中,新創建的Pod對象一旦成功響應就緒探測即被認為是可用狀態,然后進行下一輪的替換。而spec.minReadySeconds能夠定義在新的Pod對象創建后至少需要等待多長的時間才能會被認為其就緒,在該段時間內,更新操作會被阻塞。

完整的revisionHistoryLimit配置如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy-test
  name: nginx-test-1
  namespace: test1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-test
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx-test
    spec:
      containers:
      - image: nginx:latest
        name: nginx

5. 服務副本縮放

  1. 使用scale命令修改

    $ kubectl scale deploy/nginx-test-1 --replicas=2 -n test1
    

  1. 使用edit命令修改

    直接使用edit命令修改 .spec.replicas 屬性值即可

    $ kubectl edit deploy/nginx-test-1 -n test1
    
  2. 直接修改模板中的 .spec.replicas屬性值即可

當然我們也可以設置自動縮放功能,這里先簡單提及一下,完了專門寫一篇說這個事情。

基於現有 Pods 的 CPU 利用率選擇 要運行的 Pods 個數下限和上限。

$ kubectl autoscale deploy/nginx-test-1 --min=10 --max=15 --cpu-percent=80


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM