最近進到新專案,需要開始熟悉 GCP 相關服務,順手先嘗試將一個 Nginx 應用部署到 Google Kubernetes Engine (GKE) 上。過程中,使用 Helm 來簡化與管理部署流程,將過程記錄下來分享。
開發環境與前置準備
安裝 GKE 認證插件:
bash gcloud components install gke-gcloud-auth-plugin
登入 GCP 帳號:
bash gcloud auth login
在開始之前,需要先確認了本地環境已具備以下工具,並且 GKE Cluster 也已備妥。
-
Google Cloud SDK (gcloud): 用於與 GCP 互動。在 macOS 上,我習慣用 Homebrew 安裝:
brew install --cask google-cloud-sdk
-
kubectl: Kubernetes 的命令列工具。
gcloud
中其實已包含kubectl
,可以透過以下指令安裝:gcloud components install kubectl
-
Helm: Kubernetes 的套件管理器。同樣,用 Homebrew 就能快速安裝:
brew install helm
-
一個已啟用的 GCP 專案: 確保專案已啟用計費 (Billing) 與 GKE API。
-
一個執行中的 GKE Cluster: 需要一個 Kubernetes Cluster 來部署應用。這次我選擇建立一個 GKE Autopilot Cluster,因為它會自動管理節點,省去不少維運心力。建立的指令如下:
# 將 your-cluster-name 替換為你的 Cluster 名稱 gcloud container clusters create-auto your-cluster-name --region=us-central1
-
取得 Cluster 憑證:
本地,設定 gcloud 與 kubeconfig,這會把 GKE 的 kubeconfig 設定寫入本地 ~/.kube/config,讓你能用 kubectl / helm 操作 GKE。
gcloud config set project [YOUR_PROJECT_ID]
gcloud container clusters get-credentials your-cluster-name --region=[REGION]
可以查看本地 kubconfig
cat ~/.kube/config
- 建立一個 namespace
建立 Namespace
kubectl create ns myk8s-ns
確認 namespace 是否建立,這樣 GKE 環境就準備好了,接下來就可以在這個 namespace 中用 Helm 安裝應用
kubectl get namespace
透過 kubectl 查看 namespace 內部的資源:
> kubectl -n myk8s-ns get all
NAME READY STATUS RESTARTS AGE
pod/myk8s-nginx-755fff4646-rxlqf 1/1 Running 0 9m12s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/myk8s-nginx LoadBalancer 34.118.230.147 34.44.164.237 80:31815/TCP,443:32628/TCP 9m13s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/myk8s-nginx 1/1 1 1 9m14s
NAME DESIRED CURRENT READY AGE
replicaset.apps/myk8s-nginx-755fff4646 1 1 1 9m13s
起手式:建立 Helm Chart
第一步,為 Nginx 建立了一個基本的 Helm Chart。Helm 提供了方便的指令來生成一個標準的 Chart 結構。
> helm create myk8s
Creating myk8s
這個指令會建立一個 myk8s
資料夾,裡面包含了部署應用所需的所有模板檔案。
加入 chart repo(這裡以 Bitnami 的 nginx 為例)
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
注意!Bitnami 預告 2025/8/28 起會限制免費的 chart/image,建議你:
備份重要 chart 和 Docker image
考慮改用其他 Helm Chart source(例如官方 NGINX 或自己維護的)
關注 Bitnami 的 GitHub 通知:bitnami/containers/issues/83267
安裝與部署
透過 helm install
就可以安裝及部署服務到你的 k8s cluster
這裡先不修改設定,直接快速安裝一個 nginx 推送到 k8s 裡,安裝 chart 到指定 namespace
helm install myk8s bitnami/nginx --namespace myk8s-ns
可以看到 GKE 上面會建立
名稱 狀態 類型 Pod 機群 命名空間 叢集
myk8s-nginx OK Deployment 1/1 myk8s-web myk8s-ns myk8s-cluster
查看 namespace 取得外部 IP
kubectl -n myk8s-ns get all
從輸出的內容可以看出 EXTERNAL-IP ,透過外部 IP 可以直接確認是否有 Nginx 歡迎頁面
NAME READY STATUS RESTARTS AGE
pod/myk8s-nginx-755fff4646-rxlqf 1/1 Running 0 17m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/myk8s-nginx LoadBalancer <CLUSTER IP> <外部IP> 80:31815/TCP,443:32628/TCP 17m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/myk8s-nginx 1/1 1 1 17m
NAME DESIRED CURRENT READY AGE
replicaset.apps/myk8s-nginx-755fff4646 1 1 1 17m
現階段,已經走完一個 Helm 安裝及部署服務到 K8S,接著來繼續一些參數調整設定。
客製化部署:調整 values.yaml
先從基礎客製化的 Value 開始,values.yaml
是 Helm Chart 的靈魂,它讓可以方便地客製化部署參數。為了控制資源用量,這裏主要調整了 CPU 和 Memory 的設定。
在 myk8s/values.yaml
中,找到 resources
區塊,並設定如下:
# myk8s/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
)。
前面安裝的 nginx ,也可以先查看 values
helm show values bitnami/nginx
執行部署
一切就緒後,使用 helm install
指令來部署 Nginx Chart。
# 我在 myk8s 的上一層目錄執行此指令
helm install myk8s ./myk8s/
Release 就是「某個 Helm chart 被安裝到 Kubernetes 的一次實體部署實例
Helm Chart | Release | Kubernetes 中出現的東西 |
---|---|---|
一份模板 | 一次部署實體 | Deployment、Service、Pod、Ingress 等 |
myk8s
是這次部署的名稱 (Release Name),可以自訂。./myk8s
則是 Chart 的路徑。
部署後,習慣用這兩個指令來確認部署狀態:
helm list -A
kubectl get pods
也能隨時用 kubectl
來調整副本數。例如,將 Nginx 擴展到 2 個副本:
# deployment 名稱會與 helm install 的 release name 相同
kubectl scale deployment myk8s --replicas=2
刪除一個 K8S instance (Release)
首先,透過 helm 查看目前的 release, 可以看到 NAME(就是 Release name) 以及 NAMESPACE
helm list -A
透過以下指令可以刪除 Relase
helm uninstall <RELEASE_NAME> -n <NAMESPACE>
更新 value.yaml 同步到 K8S
如果需要調整 value.yaml 設定,執行 helm install
會遇到 INSTALLATION FAILED ,
陸續調整 value.yaml 後,可以透過以下指令 force 更新值到 K8S
helm upgrade [RELEASE] [CHART] [flags]
RELEASE 是你部署這個 chart 時取的名字(也叫 “release name”)
CHART 是 chart 的路徑(例如 .)或名稱(如 bitnami/nginx)
> helm upgrade myk8s ./myk8s -f ./myk8s/values.yaml --namespace=myk8s-ns
=
Release "myk8s" has been upgraded. Happy Helming!
NAME: myk8s
LAST DEPLOYED: Sat Jul 26 10:53:57 2025
NAMESPACE: myk8s-ns
STATUS: deployed
REVISION: 3
查看目前 k8s deployments
> helm list
myk8s myk8s-ns 1 2025-07-26 09:52:06.049365 +0800 CST deployed nginx-21.0.8 1.29.0
查看設定細節
helm get all myk8s -n myk8s-ns
快速驗證:使用 Port-Forward 在本機測試
在正式對外開放前,通常會先用 port-forward
在本地快速驗證應用是否正常。
-
取得 Pod 名稱:
export POD_NAME=$(kubectl get pods -l "app.kubernetes.io/name=myk8s,app.kubernetes.io/instance=myk8s" -o jsonpath="{.items[0].metadata.name}")
-
執行 Port-Forward:
kubectl port-forward $POD_NAME 8080:80
-
在本機瀏覽: 接著就能在本地瀏覽器打開
http://127.0.0.1:8080
看到 Nginx 畫面了。
公開服務:讓外部存取 Nginx
要讓服務能被公開存取,有三種常見的方法,主要透過修改 values.yaml
來達成。
方法一:使用 LoadBalancer
(最直接)
最簡單的方式,GCP 會自動配置一個網路負載平衡器並提供一個公開 IP。
- 設定
values.yaml
:service: type: LoadBalancer port: 80
- 更新部署並取得 IP:
稍待幾分鐘,
helm upgrade myk8s ./myk8s -f ./myk8s/values.yaml --namespace=myk8s-ns kubectl get svc myk8s kubectl get deployments myk8s -o yaml --namespace=myk8s-ns
EXTERNAL-IP
欄位就會出現公開 IP。
方法二:使用 NodePort
NodePort
會在每個 Cluster 節點上開一個 Port,適合測試或特定網路架構。
-
設定
values.yaml
:service: type: NodePort port: 80
更新部署
helm upgrade myk8s ./myk8s -f ./myk8s/values.yaml --namespace=myk8s-ns kubectl get svc myk8s kubectl get deployments myk8s -o yaml --namespace=myk8s-ns
方法三:使用 Ingress
搭配 DNS (最靈活)
Ingress
是管理外部存取的 API 物件,功能最強大,適合生產環境。
- 設定
values.yaml
:ingress: enabled: true annotations: kubernetes.io/ingress.class: "gce" # GKE 預設 Ingress hosts: - host: your-app.your-domain.com # 替換成你的網域 paths: - path: / pathType: Prefix
- 更新 DNS:
部署後,需要將 DNS
your-app.your-domain.com
指向 Ingress Controller 提供的外部 IP。
管理與更新部署
當我修改了 Chart 設定後,會用 helm upgrade
來套用變更。在套用前,我習慣先用 helm diff
預覽一下變更點,確保一切都在預期之中。
# 預覽變更
helm diff upgrade myk8s ./myk8s
# 確認無誤後,正式更新
helm upgrade myk8s ./myk8s
最後一步:清理資源
測試完成後,為了避免產生不必要的費用,清理資源是很重要的一步。
方法一:使用 Helm Uninstall (推薦)
最推薦的方式是使用 helm uninstall
,它會智慧地刪除所有相關資源。
helm uninstall myk8s
方法二:手動使用 kubectl 刪除
因為是測試用途,這裏順手用 kubectl
手動刪除節省資源。
- 暫停服務 (縮減副本至 0):
kubectl scale deployment myk8s --replicas=0
- 刪除 Deployment、Service 等:
kubectl delete deployment myk8s kubectl delete service myk8s
- 刪除 PVC (儲存卷):
# 警告:此操作會刪除當前 namespace 中所有的 PVC kubectl delete pvc --all
以上就是這次使用 Helm 將 Nginx 部署到 GKE 的完整過程。希望這份經驗分享對正在研究雲端部署的朋友們能有所幫助。