管理工作負載

您已部署您的應用程式並透過 Service 公開它。然後呢? Kubernetes 提供了許多工具來協助您管理應用程式部署,包括擴展和更新。

組織資源組態

許多應用程式需要建立多個資源,例如 Deployment 以及 Service。透過將多個資源分組在同一個檔案中(在 YAML 中以 --- 分隔),可以簡化多個資源的管理。例如

apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
  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

可以像建立單一資源一樣建立多個資源

kubectl apply -f https://k8s.io/examples/application/nginx-app.yaml
service/my-nginx-svc created
deployment.apps/my-nginx created

資源將按照它們在 Manifest 中的順序建立。因此,最好先指定 Service,因為這將確保排程器可以在控制器(例如 Deployment)建立 Pod 時分散與 Service 相關聯的 Pod。

kubectl apply 也接受多個 -f 參數

kubectl apply -f https://k8s.io/examples/application/nginx/nginx-svc.yaml \
  -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml

建議的做法是將與同一個微服務或應用程式層級相關的資源放在同一個檔案中,並將與您的應用程式相關聯的所有檔案分組在同一個目錄中。如果您的應用程式層級使用 DNS 相互綁定,您可以一起部署堆疊的所有元件。

URL 也可以指定為組態來源,這對於直接從來源控制系統中的 Manifest 部署非常方便

kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx created

如果您需要定義更多 Manifest,例如新增 ConfigMap,您也可以這樣做。

外部工具

本節僅列出用於管理 Kubernetes 工作負載的最常用工具。若要查看更完整的清單,請檢視 應用程式定義和映像檔建置 中的 CNCF Landscape。

Helm

Helm 是一個用於管理預先設定的 Kubernetes 資源套件的工具。這些套件稱為Helm Chart

Kustomize

Kustomize 遍歷 Kubernetes Manifest 以新增、移除或更新組態選項。它既可以作為獨立二進位檔使用,也可以作為 kubectl 的 原生功能

kubectl 中的批次操作

資源建立並不是 kubectl 可以批量執行的唯一操作。它也可以從組態檔案中提取資源名稱,以便執行其他操作,特別是刪除您建立的相同資源

kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted

對於兩個資源的情況,您可以使用 resource/name 語法在命令列上指定兩個資源

kubectl delete deployments/my-nginx services/my-nginx-svc

對於大量資源,您會發現使用 -l--selector 指定的選擇器(標籤查詢)來依標籤篩選資源更容易

kubectl delete deployment,services -l app=nginx
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted

鏈結和篩選

由於 kubectl 以它接受的相同語法輸出資源名稱,您可以使用 $()xargs 鏈結操作

kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service/ )
kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service/ | xargs -i kubectl get '{}'

輸出可能類似於

NAME           TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)      AGE
my-nginx-svc   LoadBalancer   10.0.0.208   <pending>     80/TCP       0s

使用上述指令,首先在 examples/application/nginx/ 目錄下建立資源,並以 -o name 輸出格式(將每個資源印成 resource/name)印出已建立的資源。接著,使用 grep 過濾出 Service,然後使用 kubectl get 印出。

遞迴操作本機檔案

如果您碰巧將資源組織在特定目錄下的數個子目錄中,您也可以遞迴地對這些子目錄執行操作,方法是在 --filename/-f 參數旁邊指定 --recursive-R

例如,假設有一個目錄 project/k8s/development,其中包含開發環境所需的所有 manifests,並依資源類型組織。

project/k8s/development
├── configmap
│   └── my-configmap.yaml
├── deployment
│   └── my-deployment.yaml
└── pvc
    └── my-pvc.yaml

預設情況下,對 project/k8s/development 執行批次操作將在目錄的第一層停止,而不會處理任何子目錄。如果您嘗試使用以下指令在此目錄中建立資源,則會遇到錯誤。

kubectl apply -f project/k8s/development
error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin)

相反地,請在 --filename/-f 命令列參數旁邊指定 --recursive-R 參數。

kubectl apply -f project/k8s/development --recursive
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created

--recursive 參數適用於任何接受 --filename/-f 參數的操作,例如:kubectl createkubectl getkubectl deletekubectl describe,甚至 kubectl rollout

當提供多個 -f 參數時,--recursive 參數也有效。

kubectl apply -f project/k8s/namespaces -f project/k8s/development --recursive
namespace/development created
namespace/staging created
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created

如果您有興趣了解更多關於 kubectl 的資訊,請繼續閱讀 命令列工具 (kubectl)

在不中斷服務的情況下更新應用程式

在某些時候,您最終需要更新已部署的應用程式,通常是透過指定新的映像檔或映像檔標籤。kubectl 支援多種更新操作,每種操作都適用於不同的情境。

您可以執行應用程式的多個副本,並使用 *rollout* 逐步將流量轉移到新的健康 Pod。最終,所有正在執行的 Pod 都將擁有新的軟體。

本節將引導您了解如何使用 Deployments 建立和更新應用程式。

假設您正在執行 nginx 1.14.2 版本。

kubectl create deployment my-nginx --image=nginx:1.14.2
deployment.apps/my-nginx created

確保有 1 個副本。

kubectl scale --replicas 1 deployments/my-nginx --subresource='scale' --type='merge' -p '{"spec":{"replicas": 1}}'
deployment.apps/my-nginx scaled

並允許 Kubernetes 在 rollout 期間新增更多臨時副本,方法是將 *surge maximum* 設定為 100%。

kubectl patch --type='merge' -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge": "100%" }}}}'
deployment.apps/my-nginx patched

若要更新到 1.16.1 版本,請使用 kubectl edit.spec.template.spec.containers[0].imagenginx:1.14.2 變更為 nginx:1.16.1

kubectl edit deployment/my-nginx
# Change the manifest to use the newer container image, then save your changes

就是這樣!Deployment 將在幕後以宣告方式逐步更新已部署的 nginx 應用程式。它確保在更新期間,只有一定數量的舊副本可能會關閉,並且只允許建立高於所需 Pod 數量的特定數量的新副本。若要了解更多關於此過程的詳細資訊,請造訪 Deployment

您可以將 rollout 與 DaemonSets、Deployments 或 StatefulSets 一起使用。

管理 rollout

您可以使用 kubectl rollout 來管理現有應用程式的漸進式更新。

例如:

kubectl apply -f my-deployment.yaml

# wait for rollout to finish
kubectl rollout status deployment/my-deployment --timeout 10m # 10 minute timeout

kubectl apply -f backing-stateful-component.yaml

# don't wait for rollout to finish, just check the status
kubectl rollout status statefulsets/backing-stateful-component --watch=false

您也可以暫停、恢復或取消 rollout。造訪 kubectl rollout 以了解更多資訊。

Canary 部署

需要多個標籤的另一個情境是區分同一組件的不同版本或組態的部署。常見的做法是將新應用程式版本的 *canary* 版本(透過 pod 範本中的映像檔標籤指定)與先前的版本並排部署,以便新版本在完全 rollout 之前可以接收即時生產流量。

例如,您可以使用 track 標籤來區分不同的版本。

主要的穩定版本將具有 track 標籤,其值為 stable

name: frontend
replicas: 3
...
labels:
   app: guestbook
   tier: frontend
   track: stable
...
image: gb-frontend:v3

然後您可以建立 guestbook frontend 的新版本,該版本帶有 track 標籤,其值不同(即 canary),以便兩組 pod 不會重疊。

name: frontend-canary
replicas: 1
...
labels:
   app: guestbook
   tier: frontend
   track: canary
...
image: gb-frontend:v4

frontend 服務將透過選擇其標籤的共同子集(即省略 track 標籤)來跨越兩組副本,以便流量將被重新導向到兩個應用程式。

selector:
   app: guestbook
   tier: frontend

您可以調整穩定版本和 canary 版本的副本數量,以決定每個版本將接收即時生產流量的比率(在本例中為 3:1)。一旦您有信心,就可以將穩定 track 更新為新的應用程式版本,並移除 canary 版本。

更新註解

有時您會想要將註解附加到資源。註解是任意的非識別中繼資料,供 API 用戶端(例如工具或程式庫)檢索。這可以使用 kubectl annotate 完成。例如:

kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx'
kubectl get pods my-nginx-v4-9gw19 -o yaml
apiVersion: v1
kind: pod
metadata:
  annotations:
    description: my frontend running nginx
...

如需更多資訊,請參閱 註解kubectl annotate

擴展您的應用程式

當應用程式上的負載增加或減少時,請使用 kubectl 來擴展您的應用程式。例如,若要將 nginx 副本的數量從 3 減少到 1,請執行:

kubectl scale deployment/my-nginx --replicas=1
deployment.apps/my-nginx scaled

現在您只有一個由 deployment 管理的 pod。

kubectl get pods -l app=nginx
NAME                        READY     STATUS    RESTARTS   AGE
my-nginx-2035384211-j5fhi   1/1       Running   0          30m

若要讓系統根據需要自動選擇 nginx 副本的數量(範圍從 1 到 3),請執行:

# This requires an existing source of container and Pod metrics
kubectl autoscale deployment/my-nginx --min=1 --max=3
horizontalpodautoscaler.autoscaling/my-nginx autoscaled

現在您的 nginx 副本將根據需要自動擴展和縮減。

如需更多資訊,請參閱 kubectl scalekubectl autoscalehorizontal pod autoscaler 文件。

資源的就地更新

有時需要對您建立的資源進行狹隘、非破壞性的更新。

kubectl apply

建議在原始碼控制中維護一組組態檔(請參閱 基礎設施即程式碼),以便可以與它們所組態的資源程式碼一起維護和版本控制。然後,您可以使用 kubectl apply 將您的組態變更推送至叢集。

此指令會將您正在推送的組態版本與先前的版本進行比較,並套用您所做的變更,而不會覆寫對您未指定的屬性所做的任何自動變更。

kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx configured

若要了解更多關於底層機制的資訊,請閱讀 伺服器端套用

kubectl edit

或者,您也可以使用 kubectl edit 更新資源。

kubectl edit deployment/my-nginx

這相當於先 get 資源,在文字編輯器中編輯它,然後 apply 具有更新版本的資源。

kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml
vi /tmp/nginx.yaml
# do some edit, and then save the file

kubectl apply -f /tmp/nginx.yaml
deployment.apps/my-nginx configured

rm /tmp/nginx.yaml

這讓您可以更輕鬆地進行更重大的變更。請注意,您可以使用 EDITORKUBE_EDITOR 環境變數指定編輯器。

如需更多資訊,請參閱 kubectl edit

kubectl patch

您可以使用 kubectl patch 來就地更新 API 物件。此子指令支援 JSON patch、JSON merge patch 和 strategic merge patch。

如需更多詳細資訊,請參閱 使用 kubectl patch 就地更新 API 物件

破壞性更新

在某些情況下,您可能需要更新資源欄位,這些欄位一旦初始化就無法更新,或者您可能想要立即進行遞迴變更,例如修復 Deployment 建立的損壞 pod。若要變更這些欄位,請使用 replace --force,它會刪除並重新建立資源。在這種情況下,您可以修改原始組態檔。

kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force
deployment.apps/my-nginx deleted
deployment.apps/my-nginx replaced

接下來是什麼?

此頁面上的項目參考了提供 Kubernetes 所需功能的第三方產品或專案。Kubernetes 專案作者不對這些第三方產品或專案負責。如需更多詳細資訊,請參閱 CNCF 網站指南

在提出新增額外第三方連結的變更之前,您應該閱讀 內容指南

最後修改時間:2024 年 2 月 19 日下午 4:54 PST:修訂 workload management concept (5639b8bb45)