最近進到新專案,需要開始熟悉 GCP 相關服務,順手先嘗試將一個 Nginx 應用部署到 Google Kubernetes Engine (GKE) 上。過程中,使用 Helm 來簡化與管理部署流程,將過程記錄下來分享。

開發環境與前置準備

在開始之前,需要先確認了本地環境已具備以下工具,並且 GKE Cluster 也已備妥。

  1. Google Cloud SDK (gcloud): 用於與 GCP 互動。在 macOS 上,我習慣用 Homebrew 安裝:

    brew install --cask google-cloud-sdk
    
  2. kubectl: Kubernetes 的命令列工具。gcloud 中其實已包含 kubectl,可以透過以下指令安裝:

    gcloud components install kubectl
    
  3. Helm: Kubernetes 的套件管理器。同樣,用 Homebrew 就能快速安裝:

    brew install helm
    
  4. 一個已啟用的 GCP 專案: 確保專案已啟用計費 (Billing) 與 GKE API。

  5. 一個執行中的 GKE Cluster: 需要一個 Kubernetes Cluster 來部署應用。這次我選擇建立一個 GKE Autopilot Cluster,因為它會自動管理節點,省去不少維運心力。建立的指令如下:

    # 將 your-cluster-name 替換為你的 Cluster 名稱
    gcloud container clusters create-auto your-cluster-name --region=us-central1
    

起手式:建立 Helm Chart

第一步,為 Nginx 建立了一個基本的 Helm Chart。Helm 提供了方便的指令來生成一個標準的 Chart 結構。

helm create my-nginx-chart

這個指令會建立一個 my-nginx-chart 資料夾,裡面包含了部署應用所需的所有模板檔案。

客製化部署:調整 values.yaml

values.yaml 是 Helm Chart 的靈魂,它讓可以方便地客製化部署參數。為了控制資源用量,這裏主要調整了 CPU 和 Memory 的設定。

my-nginx-chart/values.yaml 中,找到 resources 區塊,並設定如下:

# my-nginx-chart/values.yaml
replicaCount: 1

image:
  repository: nginx
  pullPolicy: IfNotPresent
  tag: "stable"

# ... 其餘設定 ...

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 200m
    memory: 256Mi

這裡定義了 Pod 啟動時最少需要的資源 (requests),以及它最多能使用的資源上限 (limits)。

連接到 GKE Cluster

部署前,需要讓 kubectl 能與 GKE Cluster 溝通。

  1. 安裝 GKE 認證插件:

    gcloud components install gke-gcloud-auth-plugin
    
  2. 登入 GCP 帳號:

    gcloud auth login
    
  3. 取得 Cluster 憑證:

    # 將 your-cluster-name 和 your-zone 替換成你的 GKE Cluster 資訊
    gcloud container clusters get-credentials your-cluster-name --zone your-zone
    

    這個指令會自動設定好 kubectl 的 context。

執行部署

一切就緒後,使用 helm install 指令來部署 Nginx Chart。

# 我在 my-nginx-chart 的上一層目錄執行此指令
helm install my-nginx-release ./my-nginx-chart
  • my-nginx-release 是這次部署的名稱 (Release Name),可以自訂。
  • ./my-nginx-chart 則是 Chart 的路徑。

部署後,習慣用這兩個指令來確認部署狀態:

helm list -A
kubectl get pods

也能隨時用 kubectl 來調整副本數。例如,將 Nginx 擴展到 2 個副本:

# deployment 名稱會與 helm install 的 release name 相同
kubectl scale deployment my-nginx-release --replicas=2

快速驗證:使用 Port-Forward 在本機測試

在正式對外開放前,通常會先用 port-forward 在本地快速驗證應用是否正常。

  1. 取得 Pod 名稱:

    export POD_NAME=$(kubectl get pods -l "app.kubernetes.io/name=my-nginx-chart,app.kubernetes.io/instance=my-nginx-release" -o jsonpath="{.items[0].metadata.name}")
    
  2. 執行 Port-Forward:

    kubectl port-forward $POD_NAME 8080:80
    
  3. 在本機瀏覽: 接著就能在本地瀏覽器打開 http://127.0.0.1:8080 看到 Nginx 畫面了。

公開服務:讓外部存取 Nginx

要讓服務能被公開存取,有三種常見的方法,主要透過修改 values.yaml 來達成。

方法一:使用 LoadBalancer (最直接)

最簡單的方式,GCP 會自動配置一個網路負載平衡器並提供一個公開 IP。

  1. 設定 values.yaml
    service:
      type: LoadBalancer
      port: 80
    
  2. 更新部署並取得 IP:
    helm upgrade my-nginx-release ./my-nginx-chart
    kubectl get svc my-nginx-release
    
    稍待幾分鐘,EXTERNAL-IP 欄位就會出現公開 IP。

方法二:使用 NodePort

NodePort 會在每個 Cluster 節點上開一個 Port,適合測試或特定網路架構。

  1. 設定 values.yaml
    service:
      type: NodePort
      port: 80
    

方法三:使用 Ingress 搭配 DNS (最靈活)

Ingress 是管理外部存取的 API 物件,功能最強大,適合生產環境。

  1. 設定 values.yaml
    ingress:
      enabled: true
      annotations:
        kubernetes.io/ingress.class: "gce" # GKE 預設 Ingress
      hosts:
        - host: your-app.your-domain.com # 替換成你的網域
          paths:
            - path: /
              pathType: Prefix
    
  2. 更新 DNS: 部署後,需要將 DNS your-app.your-domain.com 指向 Ingress Controller 提供的外部 IP。

管理與更新部署

當我修改了 Chart 設定後,會用 helm upgrade 來套用變更。在套用前,我習慣先用 helm diff 預覽一下變更點,確保一切都在預期之中。

# 預覽變更
helm diff upgrade my-nginx-release ./my-nginx-chart

# 確認無誤後,正式更新
helm upgrade my-nginx-release ./my-nginx-chart

最後一步:清理資源

測試完成後,為了避免產生不必要的費用,清理資源是很重要的一步。

方法一:使用 Helm Uninstall (推薦)

最推薦的方式是使用 helm uninstall,它會智慧地刪除所有相關資源。

helm uninstall my-nginx-release

方法二:手動使用 kubectl 刪除

因為是測試用途,這裏順手用 kubectl 手動刪除節省資源。

  1. 暫停服務 (縮減副本至 0):
    kubectl scale deployment my-nginx-release --replicas=0
    
  2. 刪除 Deployment、Service 等:
    kubectl delete deployment my-nginx-release
    kubectl delete service my-nginx-release
    
  3. 刪除 PVC (儲存卷):
    # 警告:此操作會刪除當前 namespace 中所有的 PVC
    kubectl delete pvc --all
    

以上就是這次使用 Helm 將 Nginx 部署到 GKE 的完整過程。希望這份經驗分享對正在研究雲端部署的朋友們能有所幫助。