k8s學習 - 概念 - Deployment

軒脈刃發表於2019-07-19

k8s學習 - 概念 - Deployment

有了 ReplicaSet 還需要有 Deployment 的原因是希望有一個控制器能管理部署更新時候的版本控制問題。一個 Deployment 可以管理多個 ReplicaSet, 一個 ReplicaSet 可以管理多個 Pod。最通用的場景是當我們對某個 Pod 裡面的映象進行升級的時候,我們非常迫切需要有一個版本號概念,並且在發現問題的時候可以隨時回滾。那麼這個就是 Deployment 的使命。

使用

官方和很多文章都是使用 nginx 來做示例的。我們也不能免俗。我們來看一下最簡易的配置檔案:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.11.5
        ports:
        - containerPort: 80

很簡單吧,template 開始以下是 Pod 的內容,裡面有個 name=nginx 的容器,使用映象 nginx:1.11.5。 sepc.replicas 說明了這個 Deployment 管理了多少個 Pod。

k8s學習 - 概念 - Deployment

如圖,對應的 deployment:replicaset:pod = 1:1:3

下面我們要升級 pod 裡面的 nginx container,使用映象 nginx:1.10.1

kubectl set image deployment nginx-deployment nginx=nginx:1.10.1 --record

這裡的 record 表示這次升級記錄下命令,否則我們檢視這次升級的版本,就是 NONE

kubectl rollout history deployment nginx-deployment
deployments "nginx-deployment"
REVISION  CHANGE-CAUSE
2         kubectl set image deployment nginx-deployment nginx=nginx:1.10.1 --record=true

如果我們發現1.10.1映象是有問題,我們可以進行回滾

kubectl rollout undo deployment nginx-deployment

kubectl rollout history deployment nginx-deployment
deployments "nginx-deployment"
REVISION  CHANGE-CAUSE
2         kubectl set image deployment nginx-deployment nginx=nginx:1.10.1 --record=true
3         <none>

我們可以看到這裡就有了3個版本,第三個版本就是我們回滾的版本,由於我們沒有增加 --record,在CHANGE-CAUSE 就出現了NONE。

yaml 配置全解析

上述就是 Deployment 的基本用法。慣例,我們還是有必要全部解析一遍 Deployment 的配置。

kubectl get deployment nginx-deployment -o yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "3"
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"extensions/v1beta1","kind":"Deployment","metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},"spec":{"replicas":3,"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.11.5","name":"nginx","ports":[{"containerPort":80}]}]}}}}
  creationTimestamp: 2019-07-15T00:52:16Z
  generation: 4
  labels:
    app: nginx
  name: nginx-deployment
  namespace: default
  resourceVersion: "1638554"
  selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployment
  uid: cad03233-a69a-11e9-ac73-025000000001
spec:
  progressDeadlineSeconds: 600
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.11.5
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 3
  conditions:
  - lastTransitionTime: 2019-07-15T00:52:18Z
    lastUpdateTime: 2019-07-15T00:52:18Z
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: 2019-07-15T00:52:16Z
    lastUpdateTime: 2019-07-15T01:01:26Z
    message: ReplicaSet "nginx-deployment-dd74f8bcd" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 4
  readyReplicas: 3
  replicas: 3
  updatedReplicas: 3

把 template (Pod 內容),自身介紹性的欄位去掉:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  ...
spec:
  progressDeadlineSeconds: 600
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    ...
status:
  ...

spec.strategy

定義升級策略,Deployment 的升級有兩種策略,一種是 RollingUpdate,滾動升級。顧名思義,就是一個一個 pod 進行升級,而不是同時停止整個服務。這個升級能保證整個升級過程中服務的可用性。另外一種就是 Recreate,先將舊 Pod 下線,再啟動新 Pod。 預設是使用 RollingUpdate。

所以 sepc.strategy.rollingUpdate 就是滾動升級的一些詳細策略:

  • maxSurge: 在升級過程中,最多可以建立多少個 Pod。也就是說每次滾動的步長。該值不能為0。
  • maxUnavailable: 在升級過程中,最多不可用的 pod 的數量。該值不能為0。

spec.progressDeadlineSeconds

k8s 在升級過程中有可能由於各種原因升級卡住(這個時候還沒有明確的升級失敗),比如在拉取被牆的映象,許可權不夠等錯誤。那麼這個時候就需要有個 deadline ,在 deadline 之內如果還卡著,那麼就上報這個情況,這個時候這個 Deployment 狀態就被標記為 False,並且註明原因。但是它並不會阻止 Deployment 繼續進行卡住後面的操作。完全由使用者進行控制。

這個配置就是設定 deadline 的。單位為秒。

spec.revisionHistoryLimit

我們做的回滾操作並不是沒有代價的,代價就是舊版本的 ReplicaSet 會被保留,但是不會繼續提供服務了。當我們執行回滾操作的時候,就直接使用舊版本的 ReplicaSet。

這個配置就是控制保留多少個版本的 ReplicaSet。

參考

https://tachingchen.com/tw/blog/kubernetes-rolling-update-with-deployment/
https://www.cnblogs.com/breezey/p/8810094.html

相關文章