先前有透過 Cloud Run 運行容器應用,也有試著在地端架了Kubernetes,這篇來談 GKS (google kubernetes engine),目前市面上的雲服務,都是基於 Kubernetes 的雲端架構服務,如:AWS、AKS、GKE,因此 Kubernetes的基礎知識就顯得很重要,但Kubernetes 的官方文件也真的很多東西,只好邊實作邊學習。
gcloud projects list gcloud config set project [PROJECT_ID]
gcloud components install kubectl gke-gcloud-auth-plugin gcloud components update
npx create-next-app@latest nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter" cd nextjs-blog
接著,複製官方範例的 Dockerfile 和 next.config.js 到專案根目錄。
docker build -t asia-east1-docker.pkg.dev/gcr-my-project01/my-registry/blog:v2 . docker run -d -p 8888:80 asia-east1-docker.pkg.dev/gcr-my-project01/my-registry/blog:v2 docker push asia-east1-docker.pkg.dev/gcr-my-project01/my-registry/blog:v2
Google 的 Clusters 有兩種模式
Standard Cluster:
Autopilot Cluster:
可以使用網頁或腳本指令建立 Kubernetes clusters。
標準叢集 (Standard Cluster)
gcloud container clusters create blog-cluster --num-nodes 2 --machine-type n1-standard-1 --zone asia-east1-a
自動叢集(Autopilot Cluster)
gcloud container clusters create-auto blog-autopilot-cluster --region asia-east1
連線至叢集:從 Cloud Shell 使用 kubectl 操作。
可從 CloudShell 執行kubectl腳本指令,或複製連線指令到地端執行這個連線
kubectl get nodes
建立 Deployment
vim nextjs-blog-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nextjs-blog labels: app: nextjs-blog spec: selector: matchLabels: app: nextjs-blog tier: web template: metadata: labels: app: nextjs-blog tier: web spec: containers: - name: nextjs-blog-app image: asia-east1-docker.pkg.dev/gcr-my-project01/my-registry/blog:v2 ports: - containerPort: 3000
運行應用:
kubectl apply -f nextjs-blog-deployment.yaml kubectl get deploy nextjs-blog
網路設定 - Load Balancer
kubectl expose deployment nextjs-blog-deployment --type="LoadBalancer"
kubectl expose deployment nextjs-blog-deployment --name=nextjs-blog-service --port=80 --target-port=3000 --type=LoadBalancer
點選服務進行訪問。 訪問 Next.js 網站:
kubectl set image
更新映像檔這種方式適合快速更新映像檔版本:
kubectl set image deployment/<deployment-name> <container-name>=<new-image>:<new-tag>
例如:
kubectl set image deployment/my-app my-container=my-app-image:v2
如果管理配置是基於 YAML 文件,您可以更新文件中的映像檔標籤,然後重新應用該文件:
# my-app-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 3 template: spec: containers: - name: my-container image: my-app-image:v2 # 更新映像檔標籤
重新應用更新過的 YAML 文件:
kubectl apply -f my-app-deployment.yaml
kubectl rollout restart
重新啟動 Deployment如果映像檔標籤已經更新(例如,如果您用相同標籤推送了一個新版本),可以使用重新啟動來強制刷新:
kubectl rollout restart deployment/<deployment-name>
kubectl patch
更新映像檔這種方式可以直接通過命令行進行部分更新:
kubectl patch deployment <deployment-name> -p '{"spec":{"template":{"spec":{"containers":[{"name":"<container-name>","image":"<new-image>:<new-tag>"}]}}}}'
例如:
kubectl patch deployment my-app -p '{"spec":{"template":{"spec":{"containers":[{"name":"my-container","image":"my-app-image:v2"}]}}}}'
無論採用哪種方法,可以使用以下命令來檢查更新是否成功:
kubectl rollout status deployment/<deployment-name>
這些方法都會觸發滾動更新,以保持服務不中斷的情況下逐步替換舊版本的容器。
/_next/static/<build-ID>/<static-file>
How to deploy NextJS app to Kubernetes Cluster in GCP with Custom Domain?