# GCP Compute Engine 部署指南
:::info
**Author: Tai Ming Chen ==[About me](https://mingchen.dev)==**
**Lead, Google Developer Group On Campus NCUE**
:::
**目錄**
[TOC]
> [!Important]**摘要**:
> 本文旨在提供 Google Cloud Platform (GCP) Compute Engine 的完整介紹與配置說明。內容涵蓋基礎設施層級介紹、資源階層管理、以及 VM 部署過程中的關鍵決策點(運算規格選擇、儲存效能調優、網路層級與安全性配置)。
---
## 前言:GCP 簡介 — 全球化基礎設施與核心服務
Google Cloud Platform (GCP) 並非僅是遠端伺服器的集合,它是 Google 將其支撐 Search、YouTube、Gmail 等十億級用戶產品的內部基礎建設,標準化後對外提供的服務。

### 1. 基礎設施即服務 (Infrastructure as a Service, IaaS)
我們要探討的核心主題 **Compute Engine (GCE)**,屬於 IaaS 層級。
* **定義**:提供虛擬化的硬體資源(CPU、記憶體、儲存、網路)。
* **優勢**:擁有最高的 OS 層級控制權(Root Access),適合遷移傳統應用 (Lift and Shift)、執行客製化核心、或建置 Kubernetes 叢集節點。
### 2. 全球基礎設施概念 (Global Infrastructure)
GCP 的物理架構由以下層級組成,部署前須先瞭解才能選擇合適的部署策略:
* **Region (區域)**:獨立的地理位置(如 `asia-east1` 台灣、`us-central1` 愛荷華)。每個 Region 包含多個 Zone。
* **Zone (可用區)**:區域內的部署區域(如 `asia-east1-a`, `asia-east1-b`)。Zone 之間具有獨立的電力、冷卻與網路基礎設施,彼此透過高頻寬、低延遲的網路互連。
>[!Note] **小結**
>
>
> * Google 把各個資料中心的區域,區分成了 Region 與 Zone。 Region 是由多個 Zone 組成的實體地理位置,通常在同一個 Region 中的網路傳輸延遲會低於 5 ms;而 Zone 是 Region 中可以部屬裝置的區域,每一個 Zone 可以視為一個故障域 (failure domain),在考慮可用性的前題下,我們可以把服務部屬在同個 Region 的多個 Zone 中,以防止故障的發生。而通常選擇不同的 Region,是為了可以讓服務更接近使用者,以降低延遲。舉例來說,Google 在台灣彰濱工業區的資料中心,其 Region 為 `asia-east-1` ,它有 3 個 Zone ,分別為 `asia-east1-a`、`asia-east1-b`、`asia-east1-c`。
>
> * GCP 的服務資源,也有分為 Zonal 、 Regional 與 Multi-regional 。Zonal 的資源就只會存在於一個 Zone 中,如果 Zone 發生了故障,則資源就完全無法存取。 Regional 的資源會在 Region 中有更高的可用性。而 Multi-regional 則同時將資源跨在多個 Region 中,有更高的可用性、性能與效率。`asia-east-1` 擁有 3 個 Zone,分別為 `asia-east1-a`, `asia-east1-b`, `asia-east1-c`。
> * 為了獲得較高的 SLA (服務層級協議),架構師必須設計 **跨可用區 (Multi-Zone)** 甚至 **跨區域 (Multi-Region)** 的高穩定性架構。
---
## 第一章:資源管理與計費架構 (Resource Governance)
GCP 的資源管理邏輯都遵循著 **「繼承 (Inheritance)」** 與 **「隔離 (Isolation)」** 兩大原則。
### 1. 資源階層模型 (The Resource Hierarchy)
想像一個由上而下的樹狀結構,權限像水流一樣,會從最頂層一路流到底層。
#### 層級拆解與架構視角:
1. **機構 (Organization) - 公司**
* **定義**:最高層級節點,通常與公司的 Domain Name (如 `@company.com`) 綁定。
* **架構意義**:這是實施 **「全域政策 (Organization Policy)」** 的地方。
* **實務範例**:資安長可以在此層級設定規則,例如:「禁止為任何 VM 分配外部 IP」。這條規則會強制繼承到公司內所有的部門與專案,無人能例外。
2. **資料夾 (Folder) — 部門**
* **定義**:位於機構之下、專案之上的群組容器(可多層巢狀)。
* **架構意義**:用於 **「隔離」** 與 **「批量管理」**。
* **實務範例**:
* **部門隔離**:建立 `部門A` 和 `部門B` 資料夾。當賦予 職員A `部門A` 的管理員權限,他能管理該資料夾下所有專案,但完全看不到 `部門B` 的內容。
* **環境隔離**:常見做法是建立 `Production (正式環境)` 與 `Non-Prod (測試環境)` 資料夾,以便針對正式環境設定更嚴格的存取控管。
3. **專案 (Project) — 專案小組**
* **定義**:GCP 的 **「原子管理單位」**。所有資源(VM, Storage, Network)都必須隸屬於某個專案。
* **架構意義**:
* **信任邊界 (Trust Boundary)**:此為最重要的概念。預設情況下,Project A 的網路與 Project B 是完全切斷的 (Network Isolation)。
* **計費主體**:GCP 的帳單是依據 Project 來計算的。每個 Project 必須連結到一個 Billing Account 才能運作。
* **API 開關**:如要使用 Compute Engine (或其他服務) 則必須在 Project 層級啟用 API。
4. **資源 (Resources) — 資產設備**
* **定義**:最底層的實體。
* **範例**:一台 VM、一個靜態 IP、一顆 Persistent Disk。
> [!Tip]**權限繼承 (Inheritance) 的效果**:
> 如果你在 `Organization` 層級給予某人 `Owner` 角色,那麼他將自動擁有底下所有 Folder、Project 和 VM 的最高權限,且無法在底層被移除。因此在給予頂層權限時需十分謹慎。
---
### 2. 專案 (Project) 的技術識別碼
| 識別名稱 | 特性 | 用途與情境 | 比喻 |
| :--- | :--- | :--- | :--- |
| **專案名稱**<br>**Project Name** | **可隨時更改**<br>不具唯一性 | **給人看的 (GUI)**。<br>顯示在儀表板左上角,讓人類得以快速辨識。 | 綽號 |
| **專案 ID**<br>**Project ID** | **全域唯一**<br>**建立後不可改** | **給程式 / 指令看的 (CLI / API)**。<br>最重要的識別碼!在 gcloud 指令或 API 呼叫中,即是認這個 ID。 | 身分證字號 |
| **專案編號**<br>**Project Number** | **系統自動產生**<br>不可改 | **給 Google 內部系統看的**。<br>主要用於 IAM 綁定或 Service Account 的識別。 | 健保卡號 |
> [!Tip] **為什麼架構師要在意「Project ID」?**
> 因為 **Project ID 是全 Google Cloud 用戶共用的命名空間 (Global Namespace)**。
>
> * **唯一性**:你想將 ID 取名為 `my-test-project` ? 但這個名字可能早已被其他人註冊走了...
> * **最佳實踐 (Naming Convention)**: 建議企業制定一套標準的 ID 命名規範,以確保唯一性並易於識別, 例如: `<公司縮寫>-<環境>-<專案代號>-<隨機碼>`
> * ❌ 錯誤示範:`test-vm-1` (無法辨識歸屬)
> * ✅ 正確示範:`tsmc-prod-sap-hana-892` (台積電-正式區-SAP專案-隨機碼)
---
### 3. 圖解總結
```mermaid
graph TD
Root[機構 Organization: MyCompany.com] -->|繼承: 資安政策| F1(資料夾: Engineering)
Root --> F2(資料夾: HR)
F1 -->|繼承: 部門權限| P1(專案 Project A: app-dev-001)
F1 --> P2(專案 Project B: app-prod-001)
P1 -->|計費與隔離邊界| VM1[資源: Web-Server-VM]
P1 --> DB1[資源: Cloud-SQL-DB]
style Root fill:#f9f,stroke:#333,stroke-width:2px
style P1 fill:#bbf,stroke:#333,stroke-width:2px
style VM1 fill:#bfb,stroke:#333,stroke-width:1px
```
* **Project 是邊界**:圖中 VM 和 DB 雖然都在 Engineering 部門下,但如果他們分屬不同專案,預設是無法通訊的。
* **ID 是關鍵**:當你在操作 `gcloud` 指令時,系統需要知道你指的是哪一個專案,這時必須輸入 `app-dev-001` (Project ID),輸入 `Project A` (Name) 是無效的。
---
## 第二章:環境準備與 API 生命週期
GCP 採用高度模組化的 **「微服務架構」** 來提供功能。當您建立一個新專案時,它就是一個乾淨的沙盒環境。預設情況下,大多數的服務入口(API)都是關閉的。這種設計是為了 **減少攻擊面 (Attack Surface)** 並 **避免意外費用**。
### 1. 啟用 Compute Engine API
在建立第一台 VM 之前,你必須先告訴 Google:「我要在這個專案使用運算資源」。
* **操作路徑**:
導航至 `APIs & Services` > `Library` > 搜尋 `Compute Engine API` > 點擊 **Enable**。
> **註:** 第一次點擊 Compute Engine 選單時,GCP Console 也會自動提示並幫您執行此動作
> [!Tip]**Behind the Scenes:**
> 啟用 API 時,它在後端觸發了一系列複雜的初始化流程:
>
>1. **分配控制平面資源 (Control Plane Provisioning)**:
Google 會為專案分配專屬的 API 端點資源,讓您可以透過 gcloud 或 Console 發送指令。
>2. **建立 Google 託管服務帳戶 (Google-managed Service Agents)**:
系統會自動建立一個服務帳戶。這是 Google 內部系統用來幫您執行自動化任務(如:自動擴展 Autoscaling、負載平衡配置)的身分。
>3. **初始化配額 (Quota Initialization)**:
系統會根據您的帳號等級與區域,載入預設的資源配額(例如:`us-central1` 區域預設允許 24 顆 vCPU、1 個靜態 IP 等)。
>4. **關聯依賴服務**:
啟用 Compute Engine API 通常會連帶啟用 `OS Login API` 等相依服務,確保 VM 的登入機制運作正常。
---
### 2. 服務帳戶 (Service Account) 規劃
這是 GCP 與 AWS/Azure 最顯著的差異之一,也是資安架構的核心。
**什麼是服務帳戶 (SA)?**
服務帳戶是一種特殊的 Google 帳號,它不代表「人類使用者」,而是代表 **「應用程式」** 或 **「虛擬機 (VM)」**。當你的 VM 需要去讀取 Cloud Storage 的檔案或寫入 BigQuery 資料庫時,GCP 不會檢查「你是誰(開發者)」,而是檢查「這台 VM 綁定了哪個服務帳戶」。
#### A. 預設服務帳戶的風險 (The Default Service Account Trap)
當 Compute Engine API 啟用時,系統會自動建立一個 **Default Compute Engine Service Account**。
* **格式**:`[PROJECT_NUMBER]-compute@developer.gserviceaccount.com`
* **預設權限**:**Editor (編輯者)**。
> [!Caution]**Warning:**
> 這是極度危險的設定。`Editor` 權限意味著這台 VM 擁有對專案內**所有資源**的讀寫權限。如果這台 VM 被駭客入侵,駭客就等同於拿到了整個專案的鑰匙,可以刪除整個資料庫或進行挖礦。因此在生產環境 (Production) 中,應**停用**或**避免使用**此預設帳戶。
#### B. 使用者代管服務帳戶 (User-managed Service Account)
最佳實踐是為每一個不同的應用角色,手動建立專屬的身分。
* **實務場景**:
* **Web Server VM**:只需要「讀取」存放在 Storage Bucket 裡的圖片。
* **建立 SA**:`web-app-sa@project-id...`
* **賦予權限**:`Storage Object Viewer` (僅讀取)。
* **Backup Server VM**:需要「寫入」備份檔到 Storage,並「讀取」資料庫。
* **建立 SA**:`backup-job-sa@project-id...`
* **賦予權限**:`Storage Object Creator` (寫入) + `Cloud SQL Viewer`。
* **最小權限原則 (Least Privilege)**:
透過上述拆分,即使 Web Server 被攻破,駭客也無法篡改備份檔或刪除資料庫,因為 `web-app-sa` 根本沒有那些權限。這就是 **「縱深防禦 (Defense in Depth)」** 的具體實踐。
#### C. 存取權範圍 (Access Scopes) vs IAM
在建立 VM 時,會看到 `Access scopes` 的選項。
* **Access Scopes**:這是舊時代的遺跡,主要用於限制「預設服務帳戶」的權限範圍。
* **IAM (Identity and Access Management)**:這是現代標準。
* **最佳配置**:
1. 將 VM 的 Access Scopes 設定為 **"Allow full access to all Cloud APIs"**。
2. 然後在 **IAM 頁面** 中,精確設定該 Service Account 的權限。
>[!Tip] **Why?**
>讓權限控管回歸到 IAM 層級統一管理,而不是分散在網路層 (Firewall) 或 API 範圍層 (Scopes)。
---
## 第三章:VM Instance 配置 (Configuration Strategy)
本章節將深入解析 `Create Instance` 介面中各項參數的意義。
### 1. 區域與可用區策略 (Region & Zone)
* **延遲 (Latency)**:服務台灣用戶首選 `asia-east1` (台灣,彰化)。
* **成本 (Cost)**:非延遲敏感的批次處理建議選擇 `us-central1` 或 `us-east1`,成本通常比亞洲區低 **15%~20%**。
### 2. 機器設定 (Machine Configuration)
* **E2 系列 (推薦)**:利用動態資源調度,在不同實體 CPU 間切換。CP 值最高,適合 Web 服務與開發環境。
* **共享核心 (Shared-core)**:`e2-micro` 與 `e2-small` 採用時間切片 (Time-sliced) 技術,負載高時可進行爆發 (Bursting)。
### 3. 儲存子系統 (Boot Disk)
* **pd-balanced (平衡永久磁碟)**:SSD。**推薦預設值**。在成本與 IOPS 間取得平衡。
* **關鍵知識**:GCP 的磁碟 IOPS 是線性成長的。容量越大,讀寫速度越快。
### 4. 網路與安全性 (Networking & Security)
* **VPC**:企業環境應自建 VPC 並劃分 Subnets。
* **防火牆 (Firewall Rules)**:GCP 採用軟體定義防火牆。建議使用 Network Tags (網路標記) 來管理規則。
---
## 第四章:生命週期與成本管理 (Cost Management)
理解 VM 的狀態對於控制成本至關重要。
| 狀態 | CPU/RAM 費用 | 磁碟 (PD) 費用 | 靜態 IP 費用 | 說明 |
| :--- | :---: | :---: | :---: | :--- |
| **Running** | ✅ | ✅ | ✅ | 全額計費。 |
| **Stopped** | ❌ | ✅ | ✅ | 僅停止運算資源計費。資料與 IP 仍被佔用。 |
| **Deleted** | ❌ | ❌ | ❌ | 資源釋放,停止所有計費。 |
---
## 第五章:實務演練 — 雲端部署 ==[Google Skills 連結](https://www.skills.google/catalog_lab/1427)==

本章節將結合 **Google Cloud Console (GUI)** 與 **gcloud CLI** 兩種方式,進行端到端的 VM 部署與 Nginx 服務架設。除了熟悉操作方法,亦可透過此實務演練理解「主控台操作」與「基礎設施即程式碼 (IaC)」的差異。
**實驗目標**
1. **VM 1 (`gcelab`)**:透過 Console 建立,手動配置 Nginx 網頁伺服器,模擬傳統維運流程。
2. **VM 2 (`gcelab2`)**:透過 Cloud Shell 指令自動化建立,模擬現代化 DevOps 流程。
>[!Caution] 注意事項
> 按下 **Start Lab** 後,請務必將鼠標懸浮於 **Open Google Cloud console** 上方,點擊右鍵使用 **無痕視窗 (private window)** 開啟。如此可確保正確綁定到教學帳號,避免本地環境有其他 Google 帳號導致錯誤。
>
---
### 第一階段:透過 Console 部署基礎設施 (`gcelab`)
於此階段,我們將先從圖形化介面開始,這有助於視覺化理解 GCP 的參數選項。
#### 1. 導航與初始化
* **操作**:進入 GCP Console,點擊左側導覽選單 (Navigation menu) > **Compute Engine** > **VM instances**。
* **動作**:點擊 **Create Instance**。
#### 2. 核心規格配置
在建立頁面中,請依據以下架構進行配置:
* **Name**: `gcelab`
> [!Tip]**說明:**
> DNS 兼容的名稱,將成為內部 DNS 解析的主機名稱 (Hostname)。
* **Region/Zone**: 選擇指定的區域(如 `us-central1` / `us-central1-f`)。
> [!Tip]**說明:**
> VM 與掛載的磁碟 (Persistent Disk) 必須位於同一個 Zone。
* **Machine Configuration**:
* **Series**: `E2`
* **Machine Type**: `e2-medium` (2 vCPU, 4GB Memory)
> [!Tip]**說明:**
> E2 系列利用動態資源排程提供高性價比,適合實驗室與 Web 伺服器負載。
#### 3. 儲存與作業系統 (OS & Storage)
點擊 **Boot Disk** 下方的 **Change**:
* **OS**: `Debian`
* **Version**: `Debian GNU/Linux 12 (bookworm)`
* **Boot Disk Type**: `Balanced persistent disk`
* **Size**: `10 GB`
> [!Tip]**說明:**
> 選擇 Debian 是因為其輕量且穩定(GCP 的原生優化最好)。`Balanced PD` 提供了 SSD 的隨機讀寫能力,但價格低於一般 SSD,是目前 GCP 的主流推薦。
#### 4. 網路安全性 (Networking)
* **Firewall**: 勾選 **Allow HTTP traffic**。
> [!Tip]**說明:**
> 這個勾選動作其實是一個「巨集 (Macro)」。它做了兩件事:
> 1. 在這個 VM 上打上了一個 `http-server` 的 **Network Tag**。
> 2. 檢查 VPC 防火牆規則,若不存在,則自動建立一條規則:允許 `0.0.0.0/0` (全世界) 存取 TCP Port 80,目標對象為帶有 `http-server` 標籤的 VM。
#### 5. 執行部署
點擊 **Create**。等待 30~60 秒,狀態燈號轉綠即代表 Control Plane 已完成資源分配。
---
### 第二階段:應用層服務部署 (Nginx Web Server)
基礎設施就緒後,我們需要進入 OS 層級安裝應用程式。
#### 1. 建立 SSH 連線
* **操作**:在 VM 列表中,點擊 `gcelab` 右側的 **SSH** 按鈕。
* **背後機制**:GCP 會自動生成一組臨時的 SSH Key,將公鑰注入到 VM 的 Metadata Server,並透過瀏覽器開啟 SSH 終端機。這是最安全的連線方式之一,無需管理永久金鑰。
#### 2. 權限提升與套件管理
在 SSH視窗中執行:
```bash
sudo apt-get update
sudo apt-get install -y nginx
```
> [!Tip] **說明:**
>* `sudo`:以 Root 權限執行,因為安裝軟體涉及寫入系統目錄。
>* `apt-get update`:更新本地的套件索引清單,確保下載到最新、最安全的版本。
>* `nginx`:安裝高效能的 Web 伺服器。
#### 3. 驗證服務狀態
確認 Nginx 行程是否在背景執行:
```bash
ps auwx | grep nginx
```
* **預期結果**:應看到 `master process` 與 `worker process`。
#### 4. 驗收成果
回到 GCP Console,點擊 `gcelab` 的 **External IP** 連結。

* **預期結果**:瀏覽器開啟新分頁,顯示 "Welcome to nginx!",若無法顯示,通常是 Firewall 規則尚未生效,或瀏覽器快取問題(嘗試無痕視窗)。
---
### 第三階段:基礎設施即程式碼 (IaC) 實踐 (`gcelab2`)
視覺化界面常因 GCP 版本迭代而造成排版異動,故會有較大的不確定性,因此雲端工程師較少手動點擊 **Console**。在這個階段,我們將使用 **Cloud Shell** 與 **gcloud CLI** 來體驗自動化部署。
#### 1. 啟動 Cloud Shell
* **操作**:點擊 Console 右上角的 `>_` 圖示 (Activate Cloud Shell)。
* **說明**:Cloud Shell 是一台由 Google 代管的小型 VM (5GB Home 目錄),預裝了 `gcloud`, `docker`, `kubectl` 等所有開發工具。
#### 2. 理解 gcloud 語法
在 Cloud Shell 中輸入以下指令(請將 `<ZONE>` 替換為分配到的 Zone,如 `us-central1-f`):
```bash
gcloud compute instances create gcelab2 \
--machine-type e2-medium \
--zone <ZONE>
```
* **指令說明**:
* `compute instances create`:宣告我們要操作的資源 (Instance) 與動作 (Create)。
* `--machine-type`:指定規格。若不指定,預設通常為 `e2-medium`(視專案設定而定)。
* `--zone`:指定部署位置。
* **預設值**:在此例我們沒有指定 Image 和 Network。gcloud 會自動使用預設的 Debian Image 與 Default VPC。這是 CLI 的高效之處,但也需要工程師清楚「預設值」為何。
#### 3. 透過 CLI 進行 SSH 連線
VM 建立完成後,可直接在 Cloud Shell 連線進去,無需打開新視窗:
```bash
gcloud compute ssh gcelab2 --zone <ZONE>
```
* 系統會詢問是否建立 SSH Key(輸入 Y)。
* 詢問 Passphrase(按 Enter 留空即可)。
* 此時 gcloud 正在背景生成 RSA 金鑰對,並將公鑰透過 API 寫入專案的 Metadata,幾秒鐘後即可登入。
#### 4. 清理資源 (Clean Up)
實驗結束後,務必輸入 `exit` 離開 SSH,並刪除測試用的 VM 以免產生費用
* 此為 Lab 環境,於倒數時間歸零後,GCP 會自動收回資源並關閉該學習帳號。但於綁定帳單帳戶的真實環境中,如未正確刪除則會造成額外花費)
```bash
# 危險操作:僅在確認不再需要時執行
gcloud compute instances delete gcelab2 --zone <ZONE>
```
---
>[!Tip] **Summarize**
>透過這個 Lab 的實作,體驗了兩種不同的部署模式:
> 1. **Console 模式**:適合除錯與視覺化管理。
> 2. **CLI 模式**:適合重複性任務、自動化腳本與大規模部署。
>
> 在真實的企業架構中,會進一步將這些指令轉化為 **Terraform** 或 **Deployment Manager** 等 IaC 工具,實現「版本控制基礎設施」。
:::success
**🎉 Congratulations!您已成功建構雲端基礎設施**
您已經掌握了 GCP 的核心概念、資源階層配置,並學會如何部署 **VM instance**。
硬體環境就緒後,下一步是學習如何駕馭這台強大的伺服器。接下來的章節將帶您深入 **Linux 系統核心**,掌握系統管理與操作實務。
==[**下一章:Linux 系統核心與操作實務**](https://hackmd.io/@mingchen/linux)==
:::