Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

GCP 筆記: Deploy, Scale, and Update Your Website on Google Kubernetes Engine

雲端服務開發流程:

  1. 用 GKE 建立叢集
  2. 建立 Docker 容器
  3. 將容器部署至 GKE 叢集
  4. 透過服務公開容器
  5. 將容器縮放為數個複本
  6. 調整網站
  7. 在 0 停機的狀態下發布新版本

建立 GKE 叢集

需要先啟用 Container Registry API。

gcloud services enable container.googleapis.com

啟用後可以建立新的叢集 fancy-cluster,並用 --num-nodes 指定建立 3 個節點,接著可以用 instances list 檢視所有的實體:

gcloud container clusters create fancy-cluster --num-nodes 3
gcloud compute instances list

# 結果
NAME                                          ZONE        MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
gke-fancy-cluster-default-pool-ad92506d-1ng3  us-east4-a  n1-standard-1               10.150.0.7   XX.XX.XX.XX    RUNNING
gke-fancy-cluster-default-pool-ad92506d-4fvq  us-east4-a  n1-standard-1               10.150.0.5   XX.XX.XX.XX    RUNNING
gke-fancy-cluster-default-pool-ad92506d-4zs3  us-east4-a  n1-standard-1               10.150.0.6   XX.XX.XX.XX    RUNNING

從儲存庫複製原始碼

和之前一樣,先將 monolith-to-microservices 專案複製到專案中。NPM 啟動後可以透過 Cloud Shell 的 Preview on port 8080 預覽。

cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
cd ~/monolith-to-microservices
./setup.sh
cd ~/monolith-to-microservices/monolith
npm start

透過 Google Cloud Build 建立 Docker 容器

啟用 Cloud Build 的 API 服務,並透過 gcloud builds submit 提交容器到 gcr.io。

gcloud services enable cloudbuild.googleapis.com
cd ~/monolith-to-microservices/monolith
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 .

## 結果
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ID                                    CREATE_TIME                DURATION  SOURCE                                                                                  IMAGES                              STATUS
1ae295d9-63cb-482c-959b-bc52e9644d53  2019-08-29T01:56:35+00:00  33S       gs://<PROJECT_ID>_cloudbuild/source/1567043793.94-abfd382011724422bf49af1558b894aa.tgz  gcr.io/<PROJECT_ID>/monolith:1.0.0  SUCCESS

接著可以到 Cloud Build > History 中檢視部署的情況。

將容器部署到 GKE

透過 kubectl 進行溝通。

在 K8s 中,最小的部署單位稱作 Pod,每個 Pod 可能包含一個或多個容器。

部署容器前,要透過 kubectl create deployment 來建立部署 (Deployment) 資源。

kubectl create deployment monolith \
	--image=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0

接著可以驗證部署的狀態。

kubectl get all

## 結果
NAME                            READY   STATUS    RESTARTS   AGE
pod/monolith-7d8bc7bf68-htm7z   1/1     Running   0          6m21s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.27.240.1   <none>        443/TCP   24h

NAME                       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/monolith   1         1         1            1           20m

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/monolith-7d8bc7bf68   1         1         1       20m

偵錯用指令

kubectl describe pod monolith

kubectl describe pod/monolith-7d8bc7bf68-2bxts

kubectl describe deployment monolith

kubectl describe deployment.apps/monolith

模擬錯誤

刪除前面部署的 Pod。

kubectl delete pod/<POD_NAME>

此時 ReplicaSet 注意到有個 Pod 被刪除,因此重新建立了一個,以此維持所需的複本 (replica) 數量。

公開 GKE 部署

需要 kubectl expose deployment 取得外部 IP 後,才能從外部存取服務。

kubectl expose deployment monolith --type=LoadBalancer --port 80 --target-port 8080

透過 kubectl get service 檢視外部 IP。

kubectl get service

# 結果
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
kubernetes   ClusterIP      10.39.240.1     <none>           443/TCP        23m
monolith     LoadBalancer   10.39.252.159   xxx.xxx.xxx.xx   80:30657/TCP   60s

縮放 GKE 部署

利用 kubectl scale deployment 來縮放部署。將 --replicas 設為 3,此時所需複本變成 3,因此透過 kubectl get all 檢視時,會看到有三個 Pod 實體。

kubectl scale deployment monolith --replicas=3
kubectl get all

# 結果
NAME                            READY   STATUS              RESTARTS   AGE
pod/monolith-57c866dff8-2qmmw   1/1     Running             0          7s
pod/monolith-57c866dff8-f8cq6   1/1     Running             0          7m16s
pod/monolith-57c866dff8-h6gch   0/1     ContainerCreating   0          7s

NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
service/kubernetes   ClusterIP      10.39.240.1     <none>           443/TCP        26m
service/monolith     LoadBalancer   10.39.252.159   xxx.xxx.xxx.xx   80:30657/TCP   4m6s

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/monolith   2/3     3            2           19m

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/monolith-57c866dff8   3         3         2       19m

更新網頁內容

如同 Hosting a Web App on Google Cloud Using Compute Engine 裡面提到的更新網站內容步驟,將網站內容更新,並重新建立。

cd ~/monolith-to-microservices/react-app/src/pages/Home
mv index.js.new index.js
cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

接著將網站內容更新到 Cloud Build 上。

cd ~/monolith-to-microservices/monolith
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 .

在零停機的情況下完成更新

利用 kubectl set image 告訴 K8s 更新 deployment/monolith 的映像檔。

kubectl set image \ 
	deployment/monolith \
    monolith=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0

驗證部署

使用 kubectl get pods 檢視所有 Pod 的狀態。

kubectl get pods

# 結果
NAME                        READY   STATUS              RESTARTS   AGE
monolith-584fbc994b-4hj68   1/1     Terminating         0          60m
monolith-584fbc994b-fpwdw   1/1     Running             0          60m
monolith-584fbc994b-xsk8s   1/1     Terminating         0          60m
monolith-75f4cf58d5-24cq8   1/1     Running             0          3s
monolith-75f4cf58d5-rfj8r   1/1     Running             0          5s
monolith-75f4cf58d5-xm44v   0/1     ContainerCreating   0          1s

此時可以可以看到舊的 Pod 正在終止,新的 Pod 已經開始運作。

清理程式

部署後要清理 Cloud Shell 裡的檔案。

清除 Git 儲存庫

cd ~
rm -rf monolith-to-microservices

清除 Google Container Registry 上的映像檔

# Delete the container image for version 1.0.0 of the monolith
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 --quiet

# Delete the container image for version 2.0.0 of the monolith
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 --quiet

清除 Cloud Storage 上的 Cloud Build 產物

# The following command will take all source archives from all builds and delete them from cloud storage

# Run this command to print all sources:
# gcloud builds list | awk 'NR > 1 {print $4}'

gcloud builds list | awk 'NR > 1 {print $4}' | while read line; do gsutil rm $line; done

刪除 GKE 服務

kubectl delete service monolith
kubectl delete deployment monolith

刪除 GKE 叢集

gcloud container clusters delete fancy-cluster
Eric Chuang
Eric Chuang

正職是廣告行銷人員,因為 Google Tag Manager 的關係開始踏入網站製作的領域,進一步把 WordPress 當成 PHP + HTML + CSS + JavaScript 的學習教材。此外,因為工作的關係,曾經用 Automattic 的 Underscores (_s) 替客戶與公司官網進行全客製化佈景主題開發。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料