此教學帶你手把手從打包 Docker 映像檔、部署 Google Kubernetes Engine 叢集以及搭建 load balancer。在實作這篇的教學前,建議您先閱讀以下兩篇對於 Kubernetes 的基本介紹:
GKE 系列文章(一) – 為什麼使用 Kubernetes
GKE 系列教學 (二) – 簡介Pod的網路機制
事先準備
建議您使用 GCP console 預設的 Cloud Shell,因為預設就已經裝好 gcloud command、kubectl、docker、git。如果您想要在本機端操作,則需要確保您的本機端已經安裝以下工具,並設定預設的 project ID。此教學是在本機端進行操作。
- Google Cloud SDK
- kubectl → 使用 gcloud command 安裝
gcloud components install kubectl
[PROJECT_ID] 填入您所要使用的 GCP 專案,預設的 zone 為 us-central1-b 或是改成您想要部署的 zone。
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone us-central1-b
步驟一:打包 Docker 映像檔
GKE 支援的應用程式部署格式為 Docker,此步驟帶您打包一個簡易的網頁應用程式 hello-app。首先,下載 hello-app 的原始碼。
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/hello-app
export PROJECT_ID="$(gcloud config get-value project -q)"
下面的指令會在目前的路徑下使用 Dockerfile 建置一個映像檔並貼上標籤。gcr.io 代表著 Google Container Registry,類似 Dock Hub 的映像檔儲存空間。但相較於 Docker Hub,Google Container Registry 是非公開的 registry。[確保您本機的 Docker 有在運行]
docker build -t gcr.io/${PROJECT_ID}/hello-app:v1 .
執行 docker images 指令來確認剛剛的 build 是否成功。
步驟二:在本地端執行容器
在本地端測試剛剛建立的映像檔。
docker run --rm -p 8080:8080 gcr.io/${PROJECT_ID}/hello-app:v1
使用本機端的終端機:
打開新的瀏覽器分頁,輸入 http://localhost:8080 測試剛剛運轉起來的應用程式。
使用 Cloud Shell:
docker run --rm -p 8080:8080 gcr.io/${PROJECT_ID}/hello-app:v1
點選 Add Cloud Shell Session,新增一頁 Cloud Shell 的分頁。
curl http://localhost:8080
收到頁面成功的回傳訊息後,在執行 docker run 的終端機或是 Cloud Shell 按下 Ctrl+C 停止容器的運行。
步驟三:上傳 Docker 映像檔至 GCR
接著,我們要把剛剛 build 好的映像檔上傳至 GCR,GKE 才能夠使用這個映像檔來運行叢集。在上傳映像檔前需要先驗證 Docker command-line,小編已經驗證過了所以才會出現 already registered correctly。
gcloud auth configure-docker
驗證完之後就可以上傳至 GCR。
步驟四:創建 GKE 叢集
創建一個名為 loadbalancedcluster 的 GKE 叢集,在預設的情況下 GKE 會自動幫您創建三個 node,在這邊我們設定兩個 node。
gcloud container clusters create loadbalancedcluster --num-nodes=2
創建 GKE 叢集需要等待數分鐘不等,創建完之後可以列出 GKE 叢集內的所有 node,也就是 VM instances。
gcloud compute instances list | grep gke
步驟五:部署應用程式至 GKE 叢集
部署應用程式需要使用到 kubectl 這個指令工具來與叢集溝通。Pods 是 Kubernetes 管理系統裡面所代表的應用程式也是可以部署的最小單位,一個 Pod 裡面可以有一個或是多個容器。
kubectl run 這個指令會讓 Kubernetes 創建一個名為 web 的 Deployment。Deployment 管理著應用程式的 replicas 也就是多個應用程式的複製品,並把這些 replicas 安排到各個 nodes 上面去執行。
kubectl run web --image=gcr.io/${PROJECT_ID}/hello-app:v1 --port 8080
kubectl get pods
步驟六:創建 Service 並開啟 NodePort
Service 可以讓 web 這個應用程式對外開放,但是目前我們只對內開放,且 Service 類型為 NodePort,也就是 GKE 會在所有有執行 web 應用程式的 node 上面開通一個隨機的 port。讓之後創建的 Load Balancer 可以透過 NodePort 來分流。
kubectl expose deployment web --target-port=8080 --type=NodePort
kubectl get service web
這邊 Service web 所開啟的 nodePort 為 30079。且尚未開放 Service 的 external IP。
步驟七:創建 Ingress 資源
Ingress 是管理所有外部流量路由至內部設定的 Kubernetes 資源。當使用者創建一個 Ingress,GKE 會創建一個 HTTP(S) load balancer 並導流至應用程式所在的端口。
創建一個名為 basic-ingress.yaml 的檔案,並貼入以下的內容
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: basic-ingress
spec:
backend:
serviceName: web
servicePort: 8080
部署 Ingress 至 GKE。
kubectl apply -f basic-ingress.yaml
需要等待數分鐘讓 Ingress controller 創建一個 HTTP(S) load balancer。
步驟八:測試應用程式
取得 load balancer 的 external IP,這邊有額外的教學教您如何設定固定的 external IP。
kubectl get ingress basic-ingress
呼叫 curl 指令測試應用程式。
curl http://[IP_ADDRESS]:80
步驟九:(Option) 部署多個應用程式至叢集
可以運行多個服務在同一個 load balancer 以及外部 IP,使用者只需要設定好 Ingress 的路由規則。
首先,先建立另一個名為 web2 的應用程式。
kubectl run web2 --image=gcr.io/google-samples/hello-app:2.0 --port=8080
對內開放 web2 Deployment。
kubectl expose deployment web2 --target-port=8080 --type=NodePort
創建一個名為 fanout-ingress.yaml 的檔案,並貼入以下內容:
可以看到這個 manifest 有設定 http 的路徑,/* 的會導至 web 這個應用程式、/v2/* 會導至 web2 這個應用程式。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: fanout-ingress
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: web
servicePort: 8080
- path: /v2/*
backend:
serviceName: web2
servicePort: 8080
部署這個設定檔,並等待數分鐘。
kubectl create -f fanout-ingress.yaml
透過 kubectl get ingress fanout-ingress 取得 load balancer 的外部 IP。
過一段時間後,使用 curl 去測試各個應用程式:
以上就是這次的教學,從最一開始的建置與上傳 Docker 映像檔、創建 GKE 叢集、部署應用程式以及部署 load balancer。