Google 雲平台部署腳本

近半年在做一組工作,概要是把 Java 開發的商務服務部署到 Google 雲平台。

工作的一段成果,放置在 https://raw.githubusercontent.com/YauHsien/gcp-gke-deployment/master/Makefile ,這是一段抽離主題的腳本,重點在於呈現一組以 Google Kubernetes Engine (簡寫 GKE) 為主的部署架構,供自己回顧,或者供他人參考學習。

要介紹一套雲平台部署架構,想起來是龐大、累人的。本文只簡要列出部署系統的範圍與步驟,至於其餘的雲平台規模與細節,之後等有機會再寫文章探討。而上述的例子只提出 Makefile 的編排,至於所牽涉到 gcloud 指令、 kubectl 指令、以及 YAML 設定檔,請自行想像或補充銜接。

部署範圍

我的部署主體為二個或更多 docker containers 形式的系統程式,也許一個是 Java 主應用程式,另一個是 Python 製作的輔助系統。這二個 container 部署到 GKE ,由 Java 程式放出 ReSTful API 介面,供遠端存取。

ReSTful 介面要有 HTTPS ,於是需要實現 TLS 簽章。並且為了稍微限制 API 的使用率,需要用到 API Key 作為存取憑證。

部署架構

由內往外,架構區分為下列層次:

  1. GKE :即 containers 的運行環境; YAML 設定檔類型為 Deployment。
  2. Google Cloud Endpoint :規定 ReSTful API 路徑;並由此模組可產生網址。 YAML 設定檔為 Open API 規格。
  3. Load Balancer :為 Java container 擋在前面,做為銜接外部介面的中介; YAML 設定檔類型為 Service 。
  4. Ingress :銜接 Load Balancer 與 Endpoint ,藉由規範而構成 ReSTful 的大門口; YAML 設定檔類型為 Ingress 。

部署腳本

腳本以 Makefile 撰寫,分類並記錄各種手續的指令。

以下,依部署的執行步驟,說明 Makefile 的每一道 recipe 。

安裝基本工具,並且登入:

首先要有 Google 雲平台帳號:一開始使用雲平台,會獲贈有大約 300 美元等值的額度,可以折抵雲平台資源的費用。用完額度之後,要簽信用卡來付費,才可以讓已設定在雲平台的服務繼續運作。

並且要安裝 Google Cloud SDK ,安裝在開發用的電腦之後,會得到 gcloud 指令。然後要學會以下幾種指令:

  • 要先進去 console.cloud.google.com 去開專案。
  • gcloud init 執行帳號登入,指定要使用的專案,並且設定預設地理區位 (zone) 。
  • gcloud components install kubectl 安裝 GKE 操作軟體。
  • gcloud components install docker-credential-gcr 安裝 docker 授權軟體。安裝完之後,要執行 docker-credential-gcr configure-docker 打通 docker 的登入及授權。
  • gcloud services enable container.googleapis.com
  • gcloud services enable containerregistry.googleapis.com

另外要安裝 skaffold 軟體,可以幫助整頓主服務眾多 containers 。

建立 container cluster / 或刪除: create-cluster drop-cluster

建立運算群集的時候,需要提供本群集的命名 (CLUSTER) 、群集放置在雲平台的地理區位 (ZONE) 、自動擴展參數 (MIN_NODE, MAX_NODE) 。而刪除運算群及時,要提供群集名稱與地理區位。

基本運算群集是一個主控站 (master) 管理至少三個基站 (nodes) 的概念。基站的數量可以自動擴充,而自動擴充基站的數量,主要是由於運算的需求:例如,當你部署 containers 第二次的時候,既有的一控三點的資源量不夠了,可能是 vCPU 不夠,或者 Memory 不夠,就會自動擴展,也許擴展為四個基站,或者擴展為二倍、六個基站,等到新部署完成之後,舊部署會撤掉,於是運算群集又縮減為一控三點。

有人說, kubernetes nodes 的自動擴充是用來省錢用的,而若真有大規模運算的需求(例如提供秒殺搶票服務)則需要預先把足夠量的機器開好。我的感覺是, nodes 的自動擴充是隨時都會發生,例如如上述,部署的時候就會自動擴充。

也可以先了解, gcloud compute machine-types list 之類的指令,能看到 Google 雲平台設定的各種 xCPU x Memory 的配置類型。

製作自行簽章: x509-cert container-secret ingress-secret

我的服務,接下來有二處會使用到 X509 的簽章,提供二種類型的密碼:一種是 generic 類型的密碼,用在在主程式多放的一個 Extensible Service Proxy container 裏頭有 nginx SSL 會用到,另一種是 TLS 類型的密碼,用在 ingress 大門。所以,這一段腳本的用法是簽一組 (.crt, .key) 檔案,然後分別用二種 gcloud 指令產出二種雲端密碼。

建立端點: endpoint

端點 YAML 設定檔可以加一段 x-google-endpoints 段落,指定 IP address 。而此時因為要先產出一個端點,所以先不設定 x-google-endpoints 而產出端點。而因為所用的是 GKE ,所用的是 Google Compute Engine 服務,所以端點的名稱直接寫 "服務名稱".endpoints."專案名稱".cloud.goog  ,例如我的端點名稱為 api.endpoints.tripbay.cloud.goog

部署服務: deployment

make deployment 是將主程式 containers 部署到 GKE 的動作,內容為藉由 skaffold 把程式專案編譯、 image 打包、 image 上傳、 Deployment 類型的 YAML 設定檔上傳等整套動作做完。

部署負載平衡設備: load-balancer

make load-balancer 是套用 Service 類型、 spec.type 為 LoadBalancer 的 YAML 設定檔,幫 containers 做出一個對外的存取點。

設定大門: ingress

make ingress 是套用 Ingress 類型的 YAML 設定檔,作為服務的大門,一方面銜接 Service 與 Endpoint (由 Endpoint 得知端點名稱即網址,並由 Service 得知對口的服務),另一方面對於我所實作的 API 服務, API 路徑的定義,甚至 Swagger / Open API 的規格,都可以附掛在 ingress 大門上。

重刷一次端點的 IP Address : endpoint

一路做到此處,還需要再刷一次 make endpoint 指令,這次要加上 IP_ADDRESS=999.999.999.999 的 make 參數,這個參數是對應到 YAML 設定檔裏頭 x-google-endpoints 段落所指定的 IP address 。

重刷一次端點,是由於上述在設定 Service / Load Balancer 與 Ingress 之後,雖然會讓服務套用端點名稱,卻還缺乏 IP address 而無法連線。重刷一次端點來指定 IP address 之後, DNS 就會更新,於是可以讓部署及服務設定裏頭的 TCP ports 或 HTTP ports 有用。

除錯

觀看部署的情況,需要使用以下幾種指令:

  • gcloud containter clusters list 用來看 GKE container 群集的
  • kubectl get nodes 用來看 container 群集的基站的 vCPU 與 Memory
  • kubectl get pods 用來看 container 的部署單位,可看到用比值如 1/2 表示這個部署單位裏頭有二個 containers ,其中一個已經上線,但是狀態是 LoopBackCrashOff 表示總歸來講它是掛掉的。
  • kubectl describe pod "部署名稱" 用來將 container 部署的細節展開,可以看到例如這個部署裏頭有二個 containers ,一個是 Extensible Service Proxy ,另一個主程式,並且後者有在跑,但是前者的 Readiness Probe 沒有通過,所以整體是掛掉的,並且一直自行重新啟動。然後在尾端有簡要的 logs 。
  • kubectl logs "部署名稱" -c esp 用來找 container 部署的記錄檔。如果只有部署一個 container 則只要提供部署名稱即可。而如果這個部署包含了二個 containers ,例如多塞一個 Extensible Service Proxy 名叫 esp ,則需要加上參數 -c esp 表示挑選哪一個 container ,來看它的紀錄檔。

About yauhsien

A Prolog & Erlang lover.
本篇發表於 Platform 並標籤為 , , , , , 。將永久鏈結加入書籤。