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

Kubernetes 是開放原始碼專案,可在許多不同環境中運作,包括筆記型電腦、高可用性的多節點叢集、公有雲、地端部署、虛擬機器 (VM) 執行個體和裸機環境。

在本程式碼研究室中,您將簡單的 Spring Boot Java 網頁應用程式部署至 GKE 上的 Kubernetes,目標是在 Kubernetes 上以複製應用程式的形式執行網頁應用程式。您將使用在本機開發的程式碼,將其轉換為 Docker 容器映像檔,並在 GKE 上執行該映像檔。

您將使用 Google Cloud 的全代管 Kubernetes 服務 GKE,專心體驗 Kubernetes,不必費心設定基礎架構。

如果您想在本機 (例如開發筆電) 上執行 Kubernetes,請考慮使用 Minikube,這項工具可輕鬆設定單一節點的 Kubernetes 叢集,用於開發和測試。如要使用 Minikube 完成本程式碼研究室,請按照下列步驟操作。

本程式碼研究室會使用「使用 Spring Boot 建構應用程式」指南中的範例程式碼。

必要條件

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

執行步驟

  • 將簡單的 Java 應用程式封裝為 Docker 容器。
  • 在 GKE 上建立 Kubernetes 叢集。
  • 將 Java 應用程式部署至 GKE 上的 Kubernetes。
  • 擴充服務並推出升級版本。
  • 存取資訊主頁,這是網頁式 Kubernetes 使用者介面。

軟硬體需求

自行設定環境

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

請記住專案 ID,這是所有 Google Cloud 專案中不重複的名稱 (上述名稱已遭占用,因此不適用於您,抱歉!)。本程式碼研究室稍後會將其稱為 PROJECT_ID

  1. 接著,您必須在 Cloud 控制台中啟用帳單,才能使用 Google Cloud 資源。

完成這項程式碼研究室的費用不應超過數美元,但如果您決定使用更多資源,或是將資源繼續執行,則可能會增加費用。

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

啟用 Cloud Shell

  1. 在 Cloud Shell 中,按一下「啟用 Cloud Shell」圖示

如果您從未啟動過 Cloud Shell,系統會顯示中間畫面 (摺疊式螢幕下方),說明 Cloud Shell 的用途。如果發生這種情況,請按一下「繼續」,之後就不會再看到這個畫面。一次性畫面如下所示:

佈建並連線至 Cloud Shell 的作業只需幾分鐘即可完成。

這部虛擬機器搭載各種您需要的開發工具,提供永久的 5 GB 主目錄,而且在 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].

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

$ git clone https://github.com/spring-guides/gs-spring-boot.git
$ cd gs-spring-boot/complete
  1. 您可以使用 Spring Boot 外掛程式正常啟動 Spring Boot 應用程式。
$ ./mvnw -DskipTests spring-boot:run
  1. 應用程式啟動後,請按一下 Cloud Shell 工具列中的「網頁預覽」,然後選取「透過以下通訊埠預覽:8080」

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

接下來,您需要準備應用程式,以便在 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. 完成後 (下載及解壓縮所有內容需要一些時間),您可以使用下列指令在本機測試映像檔,這會從新建立的容器映像檔,在 8080 連接埠以 Daemon 形式執行 Docker 容器:
$ docker run -ti --rm -p 8080:8080 \
  gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v1
  1. 再次善用 Cloud Shell 的網頁預覽功能。

  1. 新分頁中應會顯示預設頁面。確認應用程式在本機的 Docker 容器中執行後,請按下 Control+C 停止執行中的容器。

您現在可以建立 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 支援的 Kubernetes 叢集,且可正常運作。

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

  1. Kubernetes Deployment 可使用您建立的容器映像檔,建立、管理及擴充應用程式的多個執行個體。使用 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 的控管下執行,但您仍須讓外部世界能夠存取該容器。

根據預設,Pod 只能透過叢集內的內部 IP 存取。如要從 Kubernetes 虛擬網路外部存取 hello-java 容器,必須將 Pod 公開為 Kubernetes 服務。

  1. 在 Cloud Shell 中,您可以結合 kubectl expose 指令和 --type=LoadBalancer 旗標,將 Pod 公開至網際網路。建立可從外部存取的 IP 時,必須使用這個旗標。
$ kubectl create service loadbalancer hello-java --tcp=8080:8080

指令中使用的旗標會指定您將使用基礎架構提供的負載平衡器。請注意,您直接公開的是部署作業,而非 Pod。這會導致產生的服務在 Deployment 管理的所有 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,即可連上服務。

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 調解迴圈只會確保實際情況符合您的要求,並視需要採取行動。

您部署至實際工作環境的應用程式,在某個時間點會需要修正錯誤或新增功能。Kubernetes 可協助您將新版本部署至正式環境,且不會影響使用者。

  1. 按一下 Cloud Shell 選單中的「啟動編輯器」 ,開啟程式碼編輯器。
  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,確認傳回的是新回應。

糟糕!您是否不小心發布了新版應用程式?或許新版本含有錯誤,需要快速復原。有了 Kubernetes,您就能輕鬆復原到先前的狀態。執行下列指令來復原應用程式:

$ kubectl rollout undo deployment/hello-java

您已學會如何建構新的 Java 網頁應用程式,並部署至 GKE 上的 Kubernetes。

瞭解詳情