1. 程式人生 > 其它 >Kubernetes 學習筆記 4 工作負載 Deployments

Kubernetes 學習筆記 4 工作負載 Deployments

https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/

工作負載是在 Kubernetes 上執行的應用程式。

無論你的負載是單一元件還是由多個一同工作的元件構成,在 Kubernetes 中你 可以在一組 Pods 中執行它。 在 Kubernetes 中,Pod 代表的是叢集上處於執行狀態的一組 容器

Kubernetes Pods 有確定的生命週期。 例如,當某 Pod 在你的叢集中執行時,Pod 執行所在的 節點 出現致命錯誤時, 所有該節點上的 Pods 都會失敗。Kubernetes 將這類失敗視為最終狀態: 即使該節點後來恢復正常執行,你也需要建立新的 Pod 來恢復應用。

不過,為了讓使用者的日子略微好過一些,你並不需要直接管理每個 Pod。 相反,你可以使用 負載資源 來替你管理一組 Pods。 這些資源配置 控制器 來確保合適型別的、處於執行狀態的 Pod 個數是正確的,與你所指定的狀態相一致。

Kubernetes 提供若干種內建的工作負載資源:

  • DeploymentReplicaSet (替換原來的資源 ReplicationController)。 Deployment 很適合用來管理你的叢集上的無狀態應用,Deployment 中的所有 Pod 都是相互等價的,並且在需要的時候被換掉。
  • StatefulSet 讓你能夠執行一個或者多個以某種方式跟蹤應用狀態的 Pods。 例如,如果你的負載會將資料作持久儲存,你可以執行一個 StatefulSet
    ,將每個 Pod 與某個 PersistentVolume 對應起來。你在 StatefulSet 中各個 Pod 內執行的程式碼可以將資料複製到同一 StatefulSet 中的其它 Pod 中以提高整體的服務可靠性。
  • DaemonSet 定義提供節點本地支撐設施的 Pods。這些 Pods 可能對於你的叢集的運維是 非常重要的,例如作為網路連結的輔助工具或者作為網路 外掛 的一部分等等。每次你向叢集中新增一個新節點時,如果該節點與某 DaemonSet 的規約匹配,則控制面會為該 DaemonSet 排程一個 Pod 到該新節點上執行。
  • JobCronJob。 定義一些一直執行到結束並停止的任務。Job
    用來表達的是一次性的任務,而 CronJob 會根據其時間規劃反覆執行。

在龐大的 Kubernetes 生態系統中,你還可以找到一些提供額外操作的第三方 工作負載資源。通過使用 定製資源定義(CRD), 你可以新增第三方工作負載資源,以完成原本不是 Kubernetes 核心功能的工作。 例如,如果你希望執行一組 Pods,但要求所有 Pods 都可用時才執行操作 (比如針對某種高吞吐量的分散式任務),你可以實現一個能夠滿足這一需求 的擴充套件,並將其安裝到叢集中執行。

Deployments

一個 DeploymentPodsReplicaSets 提供宣告式的更新能力。

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

用例

以下是 Deployments 的典型用例:

建立 Deployment

下面是 Deployment 示例。其中建立了一個 ReplicaSet,負責啟動三個 nginx Pods:

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.14.2
        ports:
        - containerPort: 80

在該例中:

  • 建立名為 nginx-deployment(由 .metadata.name 欄位標明)的 Deployment。
  • 該 Deployment 建立三個(由 replicas 欄位標明)Pod 副本。
  • selector 欄位定義 Deployment 如何查詢要管理的 Pods。 在這裡,你選擇在 Pod 模板中定義的標籤(app: nginx)。 不過,更復雜的選擇規則是也可能的,只要 Pod 模板本身滿足所給規則即可。

    說明:

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

  • template 欄位包含以下子欄位:
    • Pod 被使用 labels 欄位打上 app: nginx 標籤。
    • Pod 模板規約(即 .template.spec 欄位)指示 Pods 執行一個 nginx 容器, 該容器執行版本為 1.14.2 的 nginx Docker Hub映象。
    • 建立一個容器並使用 name 欄位將其命名為 nginx

1 通過執行以下命令建立 Deployment :

kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml

2執行 kubectl get deployments 檢查 Deployment 是否已建立。如果仍在建立 Deployment, 則輸出類似於:

NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         0         0            0           1s

3要檢視 Deployment 上線狀態,執行 kubectl rollout status deployment/nginx-deployment

deployment "nginx-deployment" successfully rolled out

4幾秒鐘後再次執行 kubectl get deployments。輸出類似於:

NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            3           18s

5要檢視 Deployment 建立的 ReplicaSet(rs),執行 kubectl get rs。 輸出類似於:

NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-75675f5897   3         3         3       18s

6 要檢視每個 Pod 自動生成的標籤,執行 kubectl get pods --show-labels。返回以下輸出:

NAME                                READY     STATUS    RESTARTS   AGE       LABELS
nginx-deployment-75675f5897-7ci7o   1/1       Running   0          18s       app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-kzszj   1/1       Running   0          18s       app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-qqcnn   1/1       Running   0          18s       app=nginx,pod-template-hash=3123191453

說明: 你必須在 Deployment 中指定適當的選擇算符和 Pod 模板標籤(在本例中為 app: nginx)。 標籤或者選擇算符不要與其他控制器(包括其他 Deployment 和 StatefulSet)重疊。 Kubernetes 不會阻止你這樣做,但是如果多個控制器具有重疊的選擇算符,它們可能會發生衝突 執行難以預料的操作

Pod-template-hash 標籤

Deployment 控制器將 pod-template-hash 標籤新增到 Deployment 所建立或收留的 每個 ReplicaSet

此標籤可確保 Deployment 的子 ReplicaSets 不重疊。 標籤是通過對 ReplicaSet 的 PodTemplate 進行雜湊處理。 所生成的雜湊值被新增到 ReplicaSet 選擇算符、Pod 模板標籤,並存在於在 ReplicaSet 可能擁有的任何現有 Pod 中。

更新 Deployment

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

按照以下步驟更新 Deployment:

1 先來更新 nginx Pod 以使用 nginx:1.16.1 映象,而不是 nginx:1.14.2 映象。

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

或者,可以 edit Deployment 並將 .spec.template.spec.containers[0].imagenginx:1.14.2 更改至 nginx:1.16.1

kubectl edit deployment.v1.apps/nginx-deployment

2要檢視上線狀態,執行:

kubectl rollout status deployment/nginx-deployment

獲取關於已更新的 Deployment 的更多資訊:

在上線成功後,可以通過執行 kubectl get deployments 來檢視 Deployment

執行 kubectl get rs 以檢視 Deployment 通過建立新的 ReplicaSet 並將其擴容到 3 個副本並將舊 ReplicaSet 縮容到 0 個副本完成了 Pod 的更新操作:

現在執行 kubectlget pods 應僅顯示新的 Pods:

Deployment 可確保在更新時僅關閉一定數量的 Pod。預設情況下,它確保至少所需 Pods 75% 處於執行狀態(最大不可用比例為 25%)。

Deployment 還確保僅所建立 Pod 數量只可能比期望 Pods 數高一點點。 預設情況下,它可確保啟動的 Pod 個數比期望個數最多多出 25%(最大峰值 25%)。

例如,如果仔細檢視上述 Deployment ,將看到它首先建立了一個新的 Pod,然後刪除了一些舊的 Pods, 並建立了新的 Pods。它不會殺死老 Pods,直到有足夠的數量新的 Pods 已經出現。 在足夠數量的舊 Pods 被殺死前並沒有建立新 Pods。它確保至少 2 個 Pod 可用,同時 最多總共 4 個 Pod 可用。

獲取 Deployment 的更多資訊

kubectl describe deployments

翻轉(多 Deployment 動態更新)

Deployment 控制器每次注意到新的 Deployment 時,都會建立一個 ReplicaSet 以啟動所需的 Pods。 如果更新了 Deployment,則控制標籤匹配 .spec.selector 但模板不匹配 .spec.template 的 Pods 的現有 ReplicaSet 被縮容。最終,新的 ReplicaSet 縮放為 .spec.replicas 個副本, 所有舊 ReplicaSets 縮放為 0 個副本。

當 Deployment 正在上線時被更新,Deployment 會針對更新建立一個新的 ReplicaSet 並開始對其擴容,之前正在被擴容的 ReplicaSet 會被翻轉,新增到舊 ReplicaSets 列表 並開始縮容。

例如,假定你在建立一個 Deployment 以生成 nginx:1.14.2 的 5 個副本,但接下來 更新 Deployment 以建立 5 個 nginx:1.16.1 的副本,而此時只有 3 個nginx:1.14.2 副本已建立。在這種情況下,Deployment 會立即開始殺死 3 個 nginx:1.14.2 Pods, 並開始建立 nginx:1.16.1 Pods。它不會等待 nginx:1.14.2 的 5 個副本都建立完成 後才開始執行變更動作。

回滾 Deployment

有時,你可能想要回滾 Deployment;例如,當 Deployment 不穩定時(例如進入反覆崩潰狀態)。 預設情況下,Deployment 的所有上線記錄都保留在系統中,以便可以隨時回滾 (你可以通過修改修訂歷史記錄限制來更改這一約束)。

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

檢查 Deployment 上線歷史

1檢查 Deployment 修訂歷史

kubectl rollout history deployment.v1.apps/nginx

2要檢視修訂歷史的詳細資訊,執行:

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

回滾到之前的修訂版本

1假定現在你已決定撤消當前上線並回滾到以前的修訂版本:

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

或者

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

2檢查回滾是否成功以及 Deployment 是否正在執行,執行:

kubectl get deployment nginx-deployment

縮放 Deployment

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

比例縮放

RollingUpdate 的 Deployment 支援同時執行應用程式的多個版本。 當自動縮放器縮放處於上線程序(仍在進行中或暫停)中的 RollingUpdate Deployment 時, Deployment 控制器會平衡現有的活躍狀態的 ReplicaSets(含 Pods 的 ReplicaSets)中的額外副本, 以降低風險。這稱為 比例縮放(Proportional Scaling)

例如,你正在執行一個 10 個副本的 Deployment,其 maxSurge=3,maxUnavailable=2。

確保 Deployment 的這 10 個副本都在執行。

更新 Deployment 使用新映象,碰巧該映象無法從叢集內部解析。

暫停、恢復 Deployment

Deployment 狀態

Deployment 的生命週期中會有許多狀態。上線新的 ReplicaSet 期間可能處於 Progressing(進行中),可能是 Complete(已完成),也可能是 Failed(失敗)以至於無法繼續進行。

失敗的 Deployment

你的 Deployment 可能會在嘗試部署其最新的 ReplicaSet 受挫,一直處於未完成狀態。 造成此情況一些可能因素如下:

  • 配額(Quota)不足
  • 就緒探測(Readiness Probe)失敗
  • 映象拉取錯誤
  • 許可權不足
  • 限制範圍(Limit Ranges)問題
  • 應用程式執行時的配置錯誤