管理工作負載

你已經部署了你的應用程式並透過 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

資源將按照它們在清單中出現的順序建立。因此,最好先指定 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 也可以指定為配置源,這對於直接從原始碼管理系統中的清單進行部署很方便。

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

如果你需要定義更多清單,例如新增一個 ConfigMap,你也可以這樣做。

外部工具

本節只列出了用於管理 Kubernetes 工作負載的最常用工具。要檢視更長的列表,請參閱 應用程式定義和映象構建(在 CNCF Landscape 中)。

Helm

Helm 是一個用於管理預配置 Kubernetes 資源包的工具。這些包被稱為 Helm Charts

Kustomize

Kustomize 遍歷 Kubernetes 清單以新增、刪除或更新配置選項。它既可以作為獨立二進位制檔案使用,也可以作為 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,它按資源型別組織了開發環境所需的所有清單

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 支援多種更新操作,每種操作都適用於不同的場景。

你可以執行應用程式的多個副本,並使用“滾動更新”來逐步將流量轉移到新的健康 Pod。最終,所有執行的 Pod 都將具有新的軟體。

本頁的這一部分將指導你如何使用 Deployment 建立和更新應用程式。

假設你正在執行 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

並透過設定 100% 的“最大激增數”(surge maximum)來允許 Kubernetes 在滾動更新期間新增更多臨時副本。

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

你可以將滾動更新與 DaemonSet、Deployment 或 StatefulSet 一起使用。

管理滾動更新

你可以使用 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

你還可以暫停、恢復或取消滾動更新。訪問 kubectl rollout 瞭解更多資訊。

金絲雀部署

需要多個標籤的另一個場景是區分同一組件不同釋出版本或配置的部署。通常的做法是將新應用程式版本(透過 Pod 模板中的映象標籤指定)的“金絲雀”版本與之前的版本並行部署,以便在新版本完全釋出之前接收即時生產流量。

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

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

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

然後你可以建立一個新的 guestbook 前端版本,它帶有一個不同值(即 canary)的 track 標籤,這樣兩組 Pod 就不會重疊。

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

前端服務將透過選擇其標籤的公共子集(即忽略 track 標籤)來覆蓋兩組副本,以便流量被重定向到兩個應用程式。

selector:
   app: guestbook
   tier: frontend

你可以調整穩定版和金絲雀版副本的數量,以確定每個版本將接收即時生產流量的比例(在此例中為 3:1)。一旦你確信,就可以將穩定版更新為新的應用程式版本,並移除金絲雀版。

更新註解

有時你希望將註解附加到資源。註解是任意的非標識性元資料,供 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 補丁、JSON 合併補丁和策略性合併補丁。

有關更多詳細資訊,請參閱使用 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:修訂工作負載管理概念 (5639b8bb45)