將 Spring Boot Java Java 應用程式部署至 Google Kubernetes Engine 上的 Kubernetes

在 Google Kubernetes Engine 上將 Spring Boot Java 應用程式部署至 Kubernetes

程式碼研究室簡介

subject上次更新時間:4月 22, 2020
account_circle作者:Google 員工

1. 事前準備

Kubernetes 是一項開放原始碼專案,可在多種不同的環境中執行,無論是筆記型電腦、高可用性多節點叢集、從公用雲端到內部部署,還是從虛擬機器 (VM) 執行個體到裸機,都能執行。

在本程式碼研究室中,您會將 Spring 上的簡易 Spring Boot Java 網路應用程式部署至 Kubernetes,目的是將網路應用程式做為 Kubernetes 中的複製應用程式執行。您擷取機器上開發的程式碼,並將其轉換為 Docker 容器映像檔,然後在 GKE 上執行該映像檔。

您將使用 GKE 這個 Google Cloud 全代管的 Kubernetes 服務,讓您能專心體驗 Kubernetes,而不用設定基礎基礎架構。

如果您有興趣在本機電腦 (例如開發筆電) 上執行 Kubernetes,建議您查看 Minikube,它提供簡單的單一節點 Kubernetes 叢集設定,可用於開發和測試。如有需要,您可以使用 Minikube 執行程式碼研究室。

程式碼研究室將使用建立春季啟動應用程式指南中的範例程式碼。

事前準備

  • 熟悉 Java 程式語言和工具
  • 熟悉標準 Linux 文字編輯器,例如 Vim、Emacs 和 Nano

要執行的步驟

  • 將簡易的 Java 應用程式封裝為 Docker 容器。
  • 在 GKE 中建立 Kubernetes 叢集。
  • 將您的 Java 應用程式部署至 GKE 上的 Kubernetes。
  • 擴充服務並推出升級作業。
  • 存取資訊主頁 (網頁式 Kubernetes 使用者介面)。

軟硬體需求

2. 設定和相關規定

自行調整環境設定

  1. 登入 Cloud Console,建立新專案或重複使用現有專案。(如果您還沒有 Gmail 或 G Suite 帳戶,請先建立帳戶)。

提醒您,專案編號是所有 Google Cloud 專案的不重複名稱 (使用上述名稱後就無法使用,敬請見諒!)此程式碼研究室稍後將稱為 PROJECT_ID

  1. 接著,您必須在 Cloud Console 中啟用計費功能,才能使用 Google Cloud 資源。

完成這個程式碼研究室的成本應該不會超過新臺幣 $300 元,但如果您決定用到更多資源,或讓資源繼續運作,則可能需花費更多費用。

Google Cloud 新使用者可享有 $300 美元的免費試用期

啟動 Cloud Shell

  1. 在 Cloud Console 中按一下 [啟用 Cloud Shell]

如果您之前從未啟動 Cloud Shell,系統會提供一個中繼畫面 (需捲動位置),說明其是什麼。如果是這種情況,請按一下繼續 (這樣就永遠不會再看到這個畫面)。這個一次性畫面的外觀如下:

佈建和連線至 Cloud Shell 只需要幾分鐘的時間。

這部虛擬機器已載入所有您需要的開發工具。這項服務提供永久性的 5GB 主目錄,可在 Google Cloud 中執行,大幅提升網路效能和驗證效能。透過這個程式碼研究室的大部分作業,只要用瀏覽器或 Chromebook 就能完成。

連線至 Cloud Shell 之後,您應該已經看到已通過驗證,且專案已設為專案 ID。

  1. 在 Cloud Shell 中執行下列指令,確認您的身分已通過驗證:
gcloud auth list

指令輸出

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

指令輸出

[core]
project = <PROJECT_ID>

如果沒有,則可使用下列指令設定:

gcloud config set project <PROJECT_ID>

指令輸出

Updated property [core/project].

3. 取得原始碼

Cloud Shell 啟動後,您可以使用指令列複製主目錄中的原始碼範例。

$ git clone https://github.com/spring-guides/gs-spring-boot.git
$ cd gs-spring-boot/complete

4. 在本機執行應用程式

  1. 你可以透過「Spring Boot」外掛程式正常啟動 Spring Boot 應用程式。
$ ./mvnw -DskipTests spring-boot:run
  1. 應用程式啟動後,按一下 Cloud Shell 工具列中的 [Web Preview] (網頁預覽),然後選取 [透過以下埠預覽:8080]

在瀏覽器中開啟一個分頁,並連結至您剛啟動的伺服器。

5. 將 Java 應用程式封裝為 Docker 容器

接下來,您必須準備應用程式,以便在 Kubernetes 中執行。第一個步驟是定義容器及其內容。

  1. 建立可用於應用程式的 JAR。
$ ./mvnw -DskipTests package
  1. 啟用 Container Registry 以儲存您要建立的容器映像檔。
$ gcloud services enable containerregistry.googleapis.com
  1. 使用 Jib 建立容器映像檔並推送至 Container Registry。
$ ./mvnw -DskipTests com.google.cloud.tools:jib-maven-plugin:build \
  -Dimage=gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v1
  1. 如果一切順利,應該就會顯示在主控台中,只要前往 Container Registry > [Images],即可查看容器映像檔。現在,您可以使用全專案適用的 Docker 映像檔,Kubernetes 可以存取幾分鐘內的資料,並進行自動化調度管理。
  1. 完成上述作業後 (請花一點時間下載和擷取所有內容),您可以使用下列指令在本機測試映像檔,因為該指令會在 Docker 容器中以新建的映像檔,以 Docker 容器的形式為通訊埠 8080:
$ docker run -ti --rm -p 8080:8080 \
  gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v1
  1. 同樣地,您也可以利用 Cloud Shell 的網頁預覽功能。

  1. 您應該會在新分頁中開啟新分頁。確認應用程式在本機 Docker 容器中執行後,您可以按下 Control+C 來停止執行中的容器。

6. 建立叢集

您現在可以建立 GKE 叢集了。叢集是由 Google 代管的 Kubernetes API 伺服器和一組工作站節點組成。工作站節點是 Compute Engine VM。

  1. 首先,請確認相關的 API 功能已啟用。
$ gcloud services enable compute.googleapis.com container.googleapis.com
Operation "operations/..." finished successfully
  1. 建立具有兩個 n1-standard-1 節點的叢集 (可能需要幾分鐘才能完成)。
$ gcloud container clusters create hello-java-cluster \
  --num-nodes 2 \
  --machine-type n1-standard-1 \
  --zone us-central1-c

最後,您應該會看到已建立的叢集。

Creating cluster hello-java-cluster...done.
Created [https://container.googleapis.com/v1/projects/...].
kubeconfig entry generated for hello-dotnet-cluster.
NAME                  ZONE            MASTER_VERSION  
hello-java-cluster  us-central1-c  ...

現在,您的 GKE 叢集應已具備完整運作的 GKE 叢集。

現在可以將容器化應用程式部署至 Kubernetes 叢集了!從現在起,您將使用 kubectl 指令列 (已在 Cloud Shell 環境中進行設定)。其餘程式碼研究室需要 Kubernetes 用戶端和伺服器版本為 1.2 以上版本。kubectl version 會顯示目前的指令版本。

7. 將應用程式部署至 Kubernetes

  1. Kubernetes 部署作業可使用您建立的容器映像檔來建立、管理及調整應用程式的多個執行個體。使用 kubectl run 指令,將應用程式其中一個執行個體部署至 Kubernetes。
$ kubectl create deployment hello-java \
  --image=gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v1
  1. 如要查看您建立的部署作業,請執行下列指令:
$ kubectl get deployments
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   1         1         1            1           37s
  1. 如要查看部署作業建立的應用程式執行個體,請執行下列指令:
$ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
hello-java-714049816-ztzrb   1/1       Running   0          57s

在這個階段,您的容器應該會在 Kubernetes 控管下執行,但您還是需要將容器提供給外部全世界使用。

8. 允許外部流量

根據預設,pod 只能透過叢集內的內部 IP 存取。若要從 Kubernetes 虛擬網路外存取 hello-java 容器,您必須以 Pod 的形式公開 Pod。

  1. 在 Cloud Shell 中,您可以使用 kubectl expose 指令並搭配 --type=LoadBalancer 標記,將 Pod 公開至公開網際網路。如要建立可外部存取的 IP,您必須提供此標記。
$ kubectl create service loadbalancer hello-java --tcp=8080:8080

指令中使用的標記,表示您將使用基礎基礎架構提供的負載平衡器。請注意,您直接公開部署,而不是 Pod。這會導致產生的服務針對部署作業所管理的所有 Pod 進行負載平衡 (在這個案例中,只有一個 Pod,但您稍後會新增更多備用資源)。

Kubernetes Master 會建立負載平衡器和相關 Compute Engine 轉送規則、目標集區和防火牆規則,讓服務能夠從 Google Cloud 外部存取。

  1. 如要尋找服務的公開 IP 位址,只要要求 kubectl 列出所有叢集服務即可。
$ kubectl get services
NAME         CLUSTER-IP     EXTERNAL-IP      PORT(S)    AGE
Hello-java   10.3.253.62    aaa.bbb.ccc.ddd  8080/TCP    1m
kubernetes   10.3.240.1     <none>           443/TCP    5m
  1. 請注意,您的服務中有兩個 IP 位址,而且兩個都是通訊埠 8080。一個是內部 IP 位址,只能在虛擬私人雲端內查看。一個是外部負載平衡 IP 位址。在這個範例中,外部 IP 位址為 aaa.bbb.ccc.ddd。現在,您應該將瀏覽器指向 http://<EXTERNAL_IP>:8080 以使用本服務。

9. 擴充服務

Kubernetes 提供的多項強大功能之一就是讓您輕鬆擴充應用程式。假設突然需要為應用程式增加容量,您可以指示複製控制器來管理應用程式執行個體的新備用資源數量。

$ kubectl scale deployment hello-java --replicas=3
deployment "hello-java" scaled

$ kubectl get deployment
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   3         3         3            3           22m

請注意聲明式做法。您不需要啟動或停止新的執行個體,而是宣告隨時應該執行的執行個體數量。Kubernetes 對帳循環功能可確保實際內容符合您的要求,並在必要時採取行動。

10. 推出服務升級

在某些階段,您部署至正式版的應用程式需要修正錯誤或其他功能。Kubernetes 可協助您將新版本部署至實際工作環境,而且不會影響您的使用者。

  1. 按一下 Cloud Shell 選單中的 [Launch Editor],開啟程式碼編輯器。
  2. 瀏覽至 src/main/java/hello/HelloController.java 並更新回應值。
package hello;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
public class HelloController {    
   
@RequestMapping("/")
   
public String index() {
       
return "Greetings from Google Kubernetes Engine!";
   
}
}
  1. 使用 Jib 來建構及推送新版本的容器映像檔。
$ ./mvnw -DskipTests package \
  com.google.cloud.tools:jib-maven-plugin:build \
  -Dimage=gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v2

您已準備好讓 Kubernetes 順利地將複製控制器更新為新版應用程式!

  1. 如要變更執行中容器的圖片標籤,您必須編輯現有的 hello-java 部署作業,並將映像檔從 gcr.io/PROJECT_ID/hello-java:v1 變更為 gcr.io/PROJECT_ID/hello-java:v2
  1. 您可以使用 kubectl set image 指令,要求 Kubernetes 透過滾動式更新,將整個應用程式的新版本部署到整個叢集中,並一次部署一個執行個體。
$ kubectl set image deployment/hello-java \
  hello-java=gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v2

deployment "hello-java" image updated
  1. 請再次檢查 http://EXTERNAL_IP:8080,看看系統是否傳回新的回應。

11. 復原

糟糕!使用新版本的應用程式是否發生錯誤?新版本可能有錯誤,而您需要快速復原。有了 Kubernetes,您就能輕鬆地將其復原成先前的狀態。執行下列指令來復原應用程式:

$ kubectl rollout undo deployment/hello-java

12. 恭喜

您已經瞭解如何在 GKE 中建構新的 Java 網路應用程式,並部署至 Kubernetes。

瞭解詳情