本教學課程提供建立有狀態應用程式的建議做法,以及升級執行該應用程式的 Google Kubernetes Engine (GKE) 叢集。本教學課程以 Redis 為例,說明如何部署有狀態應用程式,但相同概念也適用於部署在 GKE 的其他有狀態應用程式。
目標
本教學課程包含下列步驟:
- 建立已在發布管道註冊的 GKE 叢集。
- 在 GKE 上建立 Redis 叢集。
- 將 Redis 用戶端應用程式部署至 GKE。
- 請遵循下列節點集區升級最佳做法:
- 設定 Pod disruption budget (PDB)。
- 設定維護期間和排除時段。
- 將節點升級策略設為節點數擴充升級或藍綠升級。
- 測試應用程式。
- 升級叢集。
- 測試工作負載中斷情形。
下圖顯示本教學課程的叢集架構概略視圖:
費用
在本文件中,您會使用下列 Google Cloud的計費元件:
如要根據預測用量估算費用,請使用 Pricing Calculator。
完成本文所述工作後,您可以刪除建立的資源,避免繼續計費,詳情請參閱「清除所用資源」。
事前準備
設定專案
- 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
Roles required to create a project
To create a project, you need the Project Creator role (
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles. -
Verify that billing is enabled for your Google Cloud project.
Enable the GKE API.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
Roles required to create a project
To create a project, you need the Project Creator role (
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles. -
Verify that billing is enabled for your Google Cloud project.
Enable the GKE API.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.
設定 Google Cloud CLI 的預設值
在 Google Cloud 控制台中啟動 Cloud Shell 執行個體:
開啟 Cloud Shell下載這個範例應用程式的原始碼:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/quickstarts/hello-app-redis/manifests設定預設環境變數:
gcloud config set project PROJECT-ID gcloud config set compute/zone COMPUTE-ZONE替換下列值:
- PROJECT_ID:您的 Google Cloud 專案 ID。
- COMPUTE_ZONE:Compute Engine 區域。
建立已註冊發布管道的 GKE 叢集
如要建立 GKE 叢集,請完成下列步驟:
建立名為
redis-test的叢集,其中包含三個節點:gcloud container clusters create redis-test \ --location CONTROL_PLANE_LOCATION \ --num-nodes=3 \ --release-channel regular將 CONTROL_PLANE_LOCATION 替換為叢集控制層的 Compute Engine 位置。為地區叢集提供區域,或為區域叢集提供可用區。
叢集建立完成後,您應該會看到類似以下範例的輸出內容:
NAME: redis-test LOCATION: us-central1-c MASTER_VERSION: 1.22.10-gke.600 MASTER_IP: 34.69.67.7 MACHINE_TYPE: e2-medium NODE_VERSION: 1.22.10-gke.600 NUM_NODES: 3 STATUS: RUNNING設定
kubectl與叢集通訊:gcloud container clusters get-credentials redis-test
在 GKE 上建立 Redis 叢集
在本節中,您將部署 ConfigMap、StatefulSet 和無頭服務,在先前建立的 GKE 叢集上新增 Redis 叢集。
如要建立 Redis 叢集,請完成下列步驟:
請參閱儲存 Redis 設定的 ConfigMap 檔案 (
redis-configmap.yaml)。以下程式碼片段顯示 Readiness 探測和 Liveness 探測指令碼。readiness.sh和liveness.sh指令碼會使用 redis-cli ping 檢查 Redis 伺服器是否正在執行。如果傳回PONG,表示 Redis 伺服器已啟動並執行中。這些指令碼會用於redis-cluster.yaml。如要進一步瞭解這個 ConfigMap 中的 Redis 參數,請參閱 Redis Cluster 教學課程中的「Redis Cluster 設定參數」一節。
部署 ConfigMap:
kubectl apply -f redis-configmap.yaml請參閱下方的 StatefulSet (
redis-cluster.yaml) 程式碼片段,瞭解 Readiness 探測器和 Liveness 探測器的用法。如要瞭解如何在 Kubernetes 中設定探測,請參閱「設定探測」。
強烈建議您在升級節點集區時使用就緒和即時性探針,確保 Pod 在升級期間處於就緒狀態。
部署 StatefulSet:
kubectl apply -f redis-cluster.yaml名為
redis-service.yaml的無標題 Service 用於 Redis 節點的連線。「clusterIP」欄位設為「None」,以便建立無頭服務。部署服務:
kubectl apply -f redis-service.yaml等待約兩分鐘,然後使用下列指令確認所有 Pod 都在執行:
kubectl get pods您會看到類似以下範例的輸出內容:
NAME READY STATUS RESTARTS AGE redis-0 1/1 Running 0 2m29s redis-1 1/1 Running 0 2m8s redis-2 1/1 Running 0 107s redis-3 1/1 Running 0 85s redis-4 1/1 Running 0 54s redis-5 1/1 Running 0 23s執行下列指令,確認已建立永久磁碟區:
kubectl get pv您會看到類似以下範例的輸出內容:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-HASH 1Gi RWO Delete Bound default/data-redis-5 standard 75s pvc-HASH 1Gi RWO Delete Bound default/data-redis-1 standard 2m59s pvc-HASH 1Gi RWO Delete Bound default/data-redis-3 standard 2m16s pvc-HASH 1Gi RWO Delete Bound default/data-redis-2 standard 2m38s pvc-HASH 1Gi RWO Delete Bound default/data-redis-0 standard 3m20s pvc-HASH 1Gi RWO Delete Bound default/data-redis-4 standard 104s在這個輸出內容中,HASH 代表附加至每個永久磁碟區名稱的雜湊。
將角色指派給 Redis 叢集
設定完成後,請將角色指派給 Redis 叢集。
下列指令碼會取得 Pod IP 位址,然後將每個 Pod IP 位址傳遞至指令,指派領導者和追隨者角色:
如要將角色指派給 Redis 叢集,請完成下列步驟:
執行指令碼:
chmod +x ./roles.sh ./roles.sh在系統提示時輸入
yes。登入 Redis 節點,檢查節點的角色。舉例來說,如要確認
redis-0具有領導者角色,請執行下列指令:kubectl exec -it redis-0 -- redis-cli role您會看到類似以下範例的輸出內容:
1) "master" 2) (integer) 574 3) 1) 1) "10.28.2.3" 2) "6379" 3) "574"
部署 Redis 用戶端應用程式
如要將應用程式部署至您建立的 GKE 叢集,請為應用程式定義 Deployment。名為 app-deployment.yaml 的檔案包含應用程式的部署定義。
如要進一步瞭解這項 Deployment 中使用的探查和 Pod 相依性規則,請參閱「GKE 最佳做法:設計及建構高可用性叢集」。
如要建立 Deployment,請完成下列步驟:
套用部署作業:
kubectl apply -f app-deployment.yaml透過負載平衡器公開應用程式:
kubectl expose deployment hello-web \ --type=LoadBalancer \ --port 80 \ --target-port 8080等待約一分鐘,然後執行下列指令,擷取應用程式的外部 IP 位址:
kubectl get service從輸出內容中,複製
hello-web'sEXTERNAL-IP欄列出的值:NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-web LoadBalancer 10.13.10.55 EXTERNAL_IP 80:30703/TCP 166m將 EXTERNAL_IP 貼到網路瀏覽器中,確認應用程式運作正常。您會看到類似以下範例的輸出內容:
I have been hit [1] times since deployment!記下造訪次數。您需要在「測試應用程式中斷情形」一節中使用。
為您剛複製的 EXTERNAL_IP 設定變數。您會在下一節建立指令碼來測試應用程式時,使用這個值:
export IP=EXTERNAL_IP
設定節點集區升級最佳做法
請為有狀態應用程式執行這些最佳做法,在節點集區升級期間,盡量提升可用性。
設定 Pod disruption budget (PDB)
建立 Pod disruption budget,限制自願中斷期間同時停止的備用 Pod 數量。對於有狀態應用程式而言,這項功能相當實用,因為升級期間需要一定數量的備用資源才能使用。
在 PDB 定義中:
app指定這個 PDB 適用的應用程式。minAvailable會設定中斷期間可用的 Pod 數量下限。可以是值或百分比 (例如 30%)。maxUnavailable會設定中斷期間可停用的 Pod 數量上限。也可以是值或百分比。
如要設定 PDB,請完成下列步驟:
部署 PDB:
kubectl apply -f pdb-minavailable.yaml確認 PDB 是否已建立:
kubectl get pdb
設定維護期間和排除時段
系統代您升級控制層時,節點自動升級功能可簡化升級程序,並更新叢集中的節點。這項功能預設為啟用。 詳情請參閱自動升級節點。
使用維護期間和維護排除項目設定時間範圍,控管 GKE 叢集維護作業的執行時間:
設定維護期間,從 2022 年 8 月 19 日凌晨 2 點 (世界標準時間) 開始,並在四小時後結束。這項維護作業每天都會執行。在這段時間內,系統可以自動執行維護作業。
gcloud container clusters update redis-test \ --maintenance-window-start 2022-08-19T02:00:00Z \ --maintenance-window-duration 4H \ --maintenance-window-recurrence FREQ=DAILY設定排除期,避免在新年假期期間執行維護作業。這項維護排除條件使用
no_upgrades範圍。在這段期間內,系統不得自動執行任何維護作業。詳情請參閱「排除的維護範圍」。gcloud container clusters update redis-test \ --add-maintenance-exclusion-name new-year \ --add-maintenance-exclusion-start 2022-12-26T00:00:00Z \ --add-maintenance-exclusion-end 2023-01-02T02:00:00Z \ --add-maintenance-exclusion-scope no_upgrades確認維護期間和排除時段已套用。查看「
maintenancePolicy:」下方的內容gcloud container clusters describe redis-test
詳情請參閱「設定維護期間和排除時段」。
設定節點升級策略
您可以為 GKE 叢集中的節點集區使用兩種節點升級策略:藍綠升級和節點數擴充升級。詳情請參閱「節點升級策略」。
藍綠升級
如果工作負載較無法容忍服務中斷,且可接受因資源用量增加而導致的暫時性費用增加,請選擇藍綠升級。
執行下列指令,將目前的節點集區變更為藍綠升級策略。
gcloud container node-pools update default-pool \
--cluster=redis-test \
--enable-blue-green-upgrade \
--location CONTROL_PLANE_LOCATION \
--node-pool-soak-duration=120s
為節省節點集區過渡期時間,本教學課程將節點集區過渡期設為兩分鐘。這個階段用於驗證藍色集區節點清空後的工作負載健康狀態。建議將節點集區浸泡時間設為一小時 (3600 秒),或最適合應用程式的時間長度。
如要進一步瞭解如何管理 Pod 分配,請參閱「將 Pod 部署至特定節點集區」和「將服務部署至特定節點集區」。
如要進一步瞭解如何設定藍綠升級,請參閱「設定藍綠升級」。
節點數擴充升級
如果成本效益很重要,且工作負載可在 60 分鐘內容許正常關機 (GKE 最多會尊重 PDB 60 分鐘),請選擇突波升級。
執行下列指令,將目前的節點集區變更為突增升級策略。
gcloud container node-pools update default-pool \
--max-surge-upgrade=1 \
--max-unavailable-upgrade=0 \
--cluster=redis-test
使用這項設定 (maxSurge=1 和 maxUnavailable=0) 時,升級期間只能在節點集區中新增一個突增節點,因此一次只能升級一個節點。這項設定會加快升級期間的 Pod 重新啟動速度,同時保守地進行升級。
如要進一步瞭解如何設定突波升級,請參閱「設定突波升級」。
檢查目前的節點集區設定:
gcloud container node-pools describe default-pool \
--cluster redis-test \
--location CONTROL_PLANE_LOCATION
如要進一步瞭解如何查看節點集區,請參閱「查看叢集中的節點集區」。
測試應用程式
在本節中,您會使用兩個指令碼,一個用於將要求傳送至應用程式,另一個則用於評估要求成功率。您可以使用這些指令碼,評估升級叢集後發生的情況。
如要建立指令碼,請按照下列步驟操作:
變更為包含指令碼的目錄:
cd cd kubernetes-engine-samples/quickstarts/hello-app-redis/scripts請參閱名為
generate_load.sh的指令碼,該指令碼會將每秒查詢次數 (QPS) 要求傳送至應用程式。指令碼會將 HTTP 回應代碼儲存到目前目錄中,並命名為output。您會在下一個步驟建立的指令碼中使用output的值。請參閱名為
print_error_rate.sh的指令碼,該指令碼會根據generate_load.sh產生的輸出內容計算成功率。授予自己執行指令碼的權限:
chmod u+x generate_load.sh print_error_rate.sh設定每秒查詢次數的變數。這個值會用於
generate_load.sh指令碼,與您為 EXTERNAL_IP 設定的變數相同。建議您將值設為 40。export QPS=40執行
generate_load.sh指令碼,開始傳送 QPS:./generate_load.sh $IP $QPS 2>&1讓
generate_load.sh指令碼保持執行狀態,然後開啟新的終端機。在新終端機中執行print_error_rate.sh指令碼,檢查錯誤率:cd cd kubernetes-engine-samples/quickstarts/hello-app-redis/scripts watch ./print_error_rate.sh您應該會看到 100% 的成功率和 0% 的錯誤率,因為 QPS 是由您建立。
請讓這兩個指令碼保持執行狀態,並開啟第三個終端機,準備進行下一節。
升級叢集
如要升級叢集,請完成下列步驟:
判斷
redis-test叢集使用的 GKE 版本:V=$(gcloud container clusters describe redis-test | grep "version:" | sed "s/version: //") echo $V您會看到類似以下範例的輸出內容:
1.22.9-gke.2000。擷取可用 Kubernetes 版本清單:
gcloud container get-server-config在版本清單中找出
validMasterVersions:區段,並尋找您在上一個步驟中擷取的redis-test版本。如要避免因選擇與節點不相容的版本而違反 GKE 版本差異政策,請從redis-test版本前一個列出的版本複製版本。將叢集的控制層升級至所選版本,並在系統提示時輸入
y:gcloud container clusters upgrade redis-test \ --master \ --cluster-version VERSION將 VERSION 替換為您在上一個步驟中從清單選取的版本。
控制層升級作業需要幾分鐘才能完成。
將叢集節點升級至所選版本,並在系統提示時輸入
y:gcloud container clusters upgrade redis-test \ --cluster-version=VERSION \ --node-pool=default-pool將 VERSION 替換為您從清單中選取的版本。
測試工作負載中斷
在本節中,您將測試應用程式的狀態,並觀察工作負載中斷情形。
返回執行
./print_error_rate.sh的終端機視窗,觀察升級期間的成功率變化。節點關閉升級時,您應該會發現成功率略為下降,應用程式網路錯誤率則略為上升。Success rate欄位會顯示網站的成功造訪次數。請記下這個值。在相關終端機中輸入
CTRL+C,停止執行這兩個指令碼。在瀏覽器中輸入應用程式的 IP 位址 (這是您在「部署 Redis 用戶端應用程式」一節中複製的 EXTERNAL_IP),返回應用程式的網站。
觀察應用程式的造訪次數。顯示的數字應等於:
ORIGINAL_VISIT_NUMBER + SUCCESSFUL_VISIT_NUMBER其中 ORIGINAL_VISIT_NUMBER 是您在「部署 Redis 用戶端應用程式」最後一個步驟中記錄的數字,而 SUCCESSFUL_VISIT_NUMBER 是您在本節第一個步驟中記錄的值。
清除所用資源
完成教學課程後,您可以清除所建立的資源,這樣資源就不會繼續使用配額,也不會產生費用。下列各節將說明如何刪除或關閉這些資源。
刪除專案
如要避免付費,最簡單的方法就是刪除您為了本教學課程所建立的專案。
刪除專案的方法如下:
- 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。
- 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)。
- 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。
刪除叢集
如要刪除為本教學課程建立的叢集,請執行下列指令:
gcloud container clusters delete redis-test