---
title: "從地端到雲端：從設定到壓測：一步步實現 Google Kubernetes Engine 水平擴容及縮容"
description: "逐步說明如何在 GKE 設定 HPA 水平自動擴容，並使用 K6 壓測工具驗證 CPU 超載時 Pod 自動擴展與縮容的行為。"
canonical_url: "https://blog.markkulab.net/post/gke-autoscaling-step-by-step"
author: "Mark Ku"
author_url: "https://blog.markkulab.net/author/mark-ku"
site: "Mark Ku's Blog"
date_published: "2024-11-15 01:01:35 +0800"
category: "Cloud"
tags: ["gke", "kubernetes", "autoscaling", "hpa", "google cloud", "k6", "load testing", "cloud"]
language: "zh-TW"
license: "CC BY 4.0"
license_url: "https://creativecommons.org/licenses/by/4.0/"
attribution: "轉載或引用請註明作者並附上原文連結"
---

# 從地端到雲端：從設定到壓測：一步步實現 Google Kubernetes Engine 水平擴容及縮容

## 什麼是水平擴展 ?
[接續上一篇文章+了解如何部署Next js 應用程式到Google Kubernetes Engine](https://blog.markkulab.net/deploy-nextjs-app-to-google-kubernetes-service/)，我們這篇來談談 Google Kubernetes Engine 水平擴容及縮容。　　

如同在組織中，即使一個人能力再強，最多也只能持續高效工作約 16 小時，如果工作負載過重，這個人可能會無法承受，此時，則需要聘請更多的人來分擔工作，這就是一種橫向擴展的概念。  
  
套用在技術領域中，無論一台伺服器的性能多麼強大，它的處理能力也有極限，當負載超過伺服器的能力時，單靠升級硬體（垂直擴展）可能不足以解決問題，此時就適合導入水平擴容的機制（Scaling Out）。  

## 什麼是 Kubernetes Pods？
在 Kubernetes 中，Pods 是部署的最小單位，負責承載容器化應用程序及其運行環境。

## 哪些網頁應用適合進行水平擴展？
並非所有服務都適合水平擴展，適合的服務通常為**無狀態服務**，例如 Web API 或微服務架構，這些應用可以輕鬆分散負載。

如果服務涉及**本地狀態**（如資料庫或未經設計的 Session 網頁應用），可能會因一致性問題導致無法進行水平擴展，在這種情況下，可以考慮使用**垂直擴展** (Vertical Pod Autoscaler, VPA)，提升單一 Pod 的資源能力以承擔更高負載。

## GKE 的優勢
Google Kubernetes Engine (GKE) 相較於自建 Kubernetes，提供了更方便的管理功能。例如，GKE 不需要額外安裝 `metrics-server`，即可直接監控容器的 CPU 和記憶體使用情況，大幅降低了初期設定的難度。

## 在設定水平擴容及縮容時，建立 Cluster 遇到的問題
[上篇文章+提到，GKE 提供兩種叢集模式：](https://blog.markkulab.net/deploy-nextjs-app-to-google-kubernetes-service/)
- **Standard Cluster**：靈活度高，適合需要細節控制的使用者，但需自行管理資源與設定。
- **Autopilot Cluster**：簡化管理，自動調整資源，適合專注於應用部署的使用者。

但實測發現，**Standard Cluster** 預設未啟用 Metrics，因此在執行 `kubectl get hpa` 時，無法取得 CPU 和記憶體的使用率，起初測試時，無法使用自動擴展功能。

![Standard Cluster Settings](https://blog.markkulab.net/content/markku/posts/gke-autoscaling-step-by-step/images/standard-cluster-settings.png)

![kubectl get hpa in cloud shell](https://blog.markkulab.net/content/markku/posts/gke-autoscaling-step-by-step/images/cannot-get-cpu-usage-rate.png)

## 首先，我們須需了解 Kubernetes 水平擴展所需要用到的指令
### 查詢容器應用的資源使用情況
以下指令可檢視節點或 Pod 的 CPU 和記憶體使用率：
```bash
kubectl top nodes
kubectl top pods
```

### 查詢水平擴展 (HPA) 狀態
```bash
kubectl get hpa
```

## 手動擴展容器
若需手動擴展容器，可使用以下指令：
```bash
kubectl scale deployment nextjs-blog-deployment --replicas=5
kubectl get pods
```

## 接著，我們必須設定 Deployment 自動水平擴展(容)功能
水平擴展有三種設定方式：透過 YAML 文件、指令操作或網頁介面（UI）。

### 1.使用 YAML 文件定義自動水平擴展
建立 YAML 檔並執行以下指令：
```bash
kubectl apply -f nextjs-blog-hpa.yaml
```

範例 YAML 檔案內容：
```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nextjs-blog-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nextjs-blog
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
```

說明：
- `scaleTargetRef`：指定 HPA 監控的 Deployment。
- `minReplicas`：最少保留 1 個 Pod。
- `maxReplicas`：最大擴展至 5 個 Pod。
- `metrics`：當 CPU 使用率超過 50% 時觸發擴展。

### 2. 使用指令設定自動水平擴展
```bash
kubectl autoscale deployment nextjs-blog-deployment --cpu-percent=50 --min=1 --max=5
```
### 3. 使用 GKE 網頁介面設定自動水平擴展
![Set up HorizontalPodAutoscaler](https://blog.markkulab.net/content/markku/posts/gke-autoscaling-step-by-step/images/configre-horizontaal-pod-autoscaler.png)

## 接著，我們來測試先前設定好水平擴展的設定
這次使用 Grafana 的壓測工具 K6

### 撰寫壓測腳本
以下是範例腳本：
```javascript
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '30s', target: 3000 },  // 負載測試從 0 個虛擬使用者增加到 20 個，並持續30 秒 
    { duration: '1m30s', target: 3000 }, 3000 // 維持 3000 個虛擬使用者持續 1 分 30 秒
    { duration: '20s', target: 0 },
  ]
};
// options 第一階段模擬快速增加負載，第二階段保持穩定負載，第三階段緩慢減少負載。
export default function () {
  const res = http.get('http://your-domain/');
  check(res, { 'status was 200': (r) => r.status == 200 });
  sleep(1);
```

### K6 Docker 版本，不需要額外安裝，直接執行就好 (`--rm` 會在壓測完成後刪除容器*)
```bash
// Windows 腳本
cat script.js | docker run --rm -i grafana/k6 run -
```
並同時在 Google Cloud Shell 執行下面指令， Watch指令每兩秒印出即時的cpu 消耗，就能夠驗證自動水平擴展的功能是不是有成功設定。
```bash
 watch -n 2 'date && kubectl get hpa'
```
## 最後，測試結果
當容器 CPU 使用率瞬間達到 102% 時，可能因使用率飆升的過快，容器尚未完全啟動。
![test restul 1](https://blog.markkulab.net/content/markku/posts/gke-autoscaling-step-by-step/images/test-result-1.png) 
當 CPU 使用率到 150% 時，系統自動擴展至 3 個 Pods 分擔負載。
![test restul 2](https://blog.markkulab.net/content/markku/posts/gke-autoscaling-step-by-step/images/test-result-2.png) 
當 CPU 使用率達到 超過200% 時，系統自動擴展至當初設置的 5 個 Pods 分擔負載。
![test restul 3](https://blog.markkulab.net/content/markku/posts/gke-autoscaling-step-by-step/images/test-result-3.png)
當 CPU 使用率下降後，Pods 會回到設定的最小 Pod 數量。
![test restul 4](https://blog.markkulab.net/content/markku/posts/gke-autoscaling-step-by-step/images/test-result-4.png)

## 心得
使用 GKE 真是太酷了！它的彈性和便利性讓我完全不需要在地端配置繁瑣的基礎設施，回想從過去的基礎設施管理（Infra）一路走到現在成為軟體工程師，這些累積的經驗竟然讓我在學習雲技術和 Kubernetes 時變得更加輕鬆。

## 參考資料
- [從異世界歸來的第二六天 - Kubernetes AutoScaling(二) - Horizontal Pod Autoscaler](https://ithelp.ithome.com.tw/articles/10298858)
- [怎麼在 GKE 上做 Autoscaling](https://youtu.be/jP4cg7itW6E?si=h4TDRqLSWULgzIw9)
- [实战 Kubernetes 的动态扩缩容](https://www.aneasystone.com/archives/2022/11/kubernetes-auto-scaling.html)
- [K6 官方文件](https://grafana.com/docs/k6/latest/get-started/running-k6/)

---

## 關於本文與作者

本文出自 [Mark Ku's Blog](https://blog.markkulab.net/post/gke-autoscaling-step-by-step)

授權條款： [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) — 轉載或引用請註明作者並附上原文連結

### 關於作者

**[Mark Ku](https://blog.markkulab.net/author/mark-ku)** — Software Solution Provider

- 10+ 年資深軟體工程師，現為 AI 應用 Builder
- 專注大型平台架構設計，從北美電商到AI SaaS訂閱收費系統
- 結合 AI Agent 與自動化，打造高效可演進的產品技術基礎

### 作者開發的免費工具

以下工具皆可免費使用：

- [免費 PDF 簽名工具](https://blog.markkulab.net/tools/pdf-sign): 線上 PDF 簽名工具，瀏覽器內完成手繪、打字、上傳簽名，可拖曳放置、縮放、下載。所有處理都在你的裝置完成，檔案不會上傳。
- [VS Code Refactory](https://blog.markkulab.net/tools/refactory): Refactory 是一款 VS Code 重構擴充套件：34 個重構動作、37 條 code smell 檢查、Code Health 儀表板、18 種語言、534 支測試。懂你的專案慣例：介面放哪、DI 註冊寫在哪、'use client' 該不該加；還會用 git 修改頻率 × 複雜度排出「該先修哪個檔案」，並一鍵把壞味道交給你自己電腦上的 Claude Code 修。免費使用，原始碼不離開你的機器。
- [DB-Kit 資料庫管理工具](https://blog.markkulab.net/tools/db-kit): DB-Kit 是一個用 Tauri + Rust + React 打造的輕量跨平台資料庫管理工具，用單一一致的介面同時管理 MySQL、MariaDB、PostgreSQL、SQL Server、Oracle、SQLite、MongoDB、Redis、Kafka、Elasticsearch 與 RabbitMQ 十一種資料來源：連線密碼以 OS keychain 加密、SSH Tunnel、完整 CRUD、視覺化查詢建構器、多結果集同時顯示、跨連線資料傳輸與比對同步、Excel / CSV 匯入匯出、執行計畫視覺化、ER 圖、排程備份、SQL 壓力測試（p50～p99 延遲百分位）、15 條規則的 SQL 審查、Kafka 訊息瀏覽與監控告警；繁中 / 英文雙語介面，內建 AI 助手（自然語言生成 SQL、AI 審查與調校建議）與命令列工具 dbk。免費開源（MIT），提供 Windows / macOS / Linux 安裝檔。
- [VS Code Super Mermaid](https://blog.markkulab.net/tools/super-mermaid): Super Mermaid 是一款 VS Code 擴充套件：開箱即用的漂亮 Mermaid 圖表，自動上色、即時預覽、滑鼠平移縮放、PNG / SVG 高解析匯出，內建 21 種範本與多種主題。免費開源（MIT）。
- [React Super Mermaid](https://blog.markkulab.net/tools/react-super-mermaid): react-super-mermaid 是一個開源 React 元件庫：一行 <MermaidViewer> 即可渲染漂亮的 Mermaid 圖表，內建 colorful / sketch 主題、平移縮放、圖內搜尋、SVG / PNG 高解析匯出。輕量、SSR 安全、完整 TypeScript 型別。免費開源（MIT）。
- [Jira / Confluence Super Mermaid](https://blog.markkulab.net/tools/jira-super-mermaid): Atlassian Forge app：在 Jira issue 與 Confluence 內文直接寫 Mermaid 語法，畫流程圖、時序圖、狀態機與甘特圖。11 種圖表、SVG / PNG 匯出、明暗主題、完整中日韓文字支援。取得 Runs on Atlassian 資格：圖表存在你自己的站台，app 不呼叫任何第三方服務。免費，即將上架 Atlassian Marketplace。
- [Mermaid 線上預覽](https://blog.markkulab.net/tools/mermaid-preview): 在瀏覽器裡寫 Mermaid、即時看圖，整張圖表壓進網址就能分享。免註冊、不上傳伺服器，相容 mermaid.live 的分享連結。
- [React Intl Phone Number](https://blog.markkulab.net/tools/react-intl-phone-number): react-intl-phone-number 是一個開源 React 元件：framework-agnostic、不依賴 antd，提供 E.164 進出、可搜尋國旗 / 國碼下拉、可配置驗證等級（strict / mobile-strict / loose）、可主題化 CSS 與 i18n，電話邏輯由 google-libphonenumber 驅動。輕量、完整 TypeScript 型別。免費開源（MIT）。
- [Uptime Kuma Cluster](https://blog.markkulab.net/tools/uptime-kuma-cluster): 把單機版 Uptime Kuma 改造成高可用叢集：OpenResty + Lua 智慧負載平衡、MariaDB 共享狀態、健康檢查與自動 Failover，附叢集管理 REST API，一行 Docker Compose 啟動。免費開源（MIT）。
- [特教專案](https://blog.markkulab.net/education): 為特殊教育學生製作的學習教材

### 每日 Podcast

- [科技新鮮事](https://blog.markkulab.net/category/tech-news): 每日精選 AI 與科技趨勢，透過語音摘要快速掌握最新技術動態，涵蓋 AI 應用、軟體架構、DevOps 與工程實戰。 — RSS: https://blog.markkulab.net/feed.xml
- [AI股市蝦聊](https://blog.markkulab.net/category/ai-stock-chat): 每個交易日用 AI 分析台股盤勢，以雙人對話聊當天的盤中觀察與隔日預測。 — RSS: https://blog.markkulab.net/ai-stock-chat/feed.xml

### 電子報

[訂閱電子報](https://blog.markkulab.net/subscribe) — 第一時間收到新文章通知，無垃圾信、隨時可取消訂閱。
