管理工作負載
您已部署您的應用程式並透過 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 create
、kubectl get
、kubectl delete
、kubectl 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].image
從 nginx: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 scale、kubectl autoscale 和 horizontal 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
這讓您可以更輕鬆地進行更重大的變更。請注意,您可以使用 EDITOR
或 KUBE_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 網站指南。
在提出新增額外第三方連結的變更之前,您應該閱讀 內容指南。