1. 概述
在上一篇文章中,我們對 Kubernetes 進行了理論介紹。
在本教程中,我們將討論如何在本地 Kubernetes 環境(也稱為 Minikube)上部署 Spring Boot 應用程序。
作為本文的一部分,我們將:
- 在我們的本地機器上安裝 Minikube
- 開發一個由兩個 Spring Boot 服務組成的示例應用程序
- 使用 Minikube 在一個單節點集羣上設置應用程序
- 使用配置文件部署應用程序
2. 安裝 Minikube
Minikube 的安裝基本上包括三個步驟:安裝一個 Hypervisor(如 VirtualBox)、CLI kubectl,以及 Minikube 本身。官方文檔提供了每個步驟的詳細説明,並針對所有流行的操作系統。
完成安裝後,我們可以啓動 Minikube,將 VirtualBox 設置為 Hypervisor,並配置 kubectl 以與名為 minikube 的集羣進行通信。
$> minikube start
$> minikube config set vm-driver virtualbox
$> kubectl config use-context minikube之後,我們可以驗證 kubectl 與我們的集羣正確通信:
$> kubectl cluster-info輸出應該如下所示:
Kubernetes master is running at https://192.168.99.100:8443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.目前階段,我們將保持響應中的 IP 地址不變(在本例中為 192.168.99.100)。稍後我們會將其稱為 NodeIP,以便從集羣外部調用資源,例如從我們的瀏覽器中調用。
最後,我們可以檢查集羣的狀態。
$> minikube dashboard此命令會在我們的默認瀏覽器中打開站點,從而提供有關集羣狀態的全面概述。
4. 演示應用程序
由於我們的集羣已運行並準備好部署,因此我們需要一個演示應用程序。
為此,我們將創建一個簡單的“Hello world”應用程序,該應用程序由兩個 Spring Boot 服務組成,我們將其分別稱為 frontend 和 backend。
後端提供了一個 REST 端點,位於 8080 端口,返回一個 String,其中包含其主機名。前端位於 8081 端口,它將簡單地調用後端端點並返回其響應。
之後,我們需要為每個應用程序構建 Docker 鏡像。所有用於構建所需的必要文件也已提供 在 GitHub 上。
有關如何構建 Docker 鏡像的詳細説明,請參閲 Dockerizing a Spring Boot Application。
我們必須確保在此過程中,在 Minikube 集羣的 Docker 主機上觸發構建過程,否則 Minikube 將無法在部署期間找到這些鏡像。 此外,主機上的工作空間必須掛載到 Minikube VM 中:
$> minikube ssh
$> cd /c/workspace/tutorials/spring-cloud/spring-cloud-kubernetes/demo-backend
$> docker build --file=Dockerfile \
--tag=demo-backend:latest --rm=true .之後,我們可以註銷 Minikube VM,後續所有步驟將在我們的主機上使用 kubectl 和 minikube 命令行工具執行。
5. 使用命令式方式進行簡單的部署
第一步,我們將為我們的 demo-backend 應用創建一個部署,該部署只包含一個 Pod。基於此,我們將討論一些命令,以便驗證部署,檢查日誌並最終清理它。
5.1. 創建部署
我們將使用 kubectl,並將所有必需的命令作為參數傳遞:
$> kubectl run demo-backend --image=demo-backend:latest \
--port=8080 --image-pull-policy Never如我們所見,我們創建了一個名為 demo-backend 的 Deployment,該 Deployment 是從另一個名為 demo-backend 的鏡像創建的,版本為 latest。
通過使用 –port 標誌,我們指定 Deployment 為其 Pods(因為我們的 demo-backend 應用監聽端口 8080)打開端口 8080。
標誌 –image-pull-policy Never 確保 Minikube 不會嘗試從鏡像註冊表中拉取鏡像,而是從本地 Docker 主機上獲取鏡像。
5.2. 驗證部署
現在,我們可以檢查部署是否成功:
$> kubectl get deployments輸出結果如下:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
demo-backend 1 1 1 1 19s要查看應用程序日誌,我們首先需要 Pod ID:
$> kubectl get pods
$> kubectl logs <pod id>5.3. 創建部署服務
為了使我們後端應用程序的 REST 端點可用,我們需要創建一個服務:
$> kubectl expose deployment demo-backend --type=NodePort–type=NodePort 使服務對外暴露,可通過<NodeIP>[:<NodePort>] 訪問,即服務會將接收到的所有請求(在<NodePort> 端口上)映射到其分配的 Pod 的 8080 端口。
我們使用 expose 命令,因此NodePort 將由集羣自動設置(這是一種技術限制),默認範圍為 30000-32767。要獲取我們選擇的端口,我們可以使用配置文件,如在下一部分所述。
我們可以驗證服務是否已成功創建:
$> kubectl get services輸出結果如下:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-backend NodePort 10.106.11.133 <none> 8080:30117/TCP 11m如我們所見,我們有一個名為 demo-backend 的服務,類型為 NodePort,其 IP 地址為集羣內部 IP 地址 10.106.11.133。
我們需要仔細查看 PORT(S) 列:因為部署中定義了端口 8080,該服務會將流量轉發到該端口。但是,如果我們想從瀏覽器中調用 demo-backend,則必須使用端口 30117,該端口可從集羣外部訪問。
5.4. 調用服務
現在,我們可以首次調用我們的後端服務:
$> minikube service demo-backend此命令將啓動我們的默認瀏覽器,並打開
隨後,我們可以刪除服務和部署: 對於更復雜的設置,使用配置文件的選擇優於通過命令行參數傳遞所有參數。 配置文件的使用是記錄部署過程的有效方式,並且可以進行版本控制。 讓我們使用配置文件來重新定義我們的服務: 我們創建了一個名為 demo-backend 的 Service,通過 metadata: name 字段進行標識。 它監聽 TCP 端口 8080,在任何帶有 app=demo-backend 標籤的 Pod 上。 最後,type: ClusterIP 表明它僅在集羣內部可用(因為我們這次想從我們的 demo-frontend 應用調用端點,而不是像之前的示例那樣直接從瀏覽器訪問)。 接下來,我們可以定義實際的部署: 我們創建了一個名為 demo-backend 的部署,通過 metadata: name 字段進行標識。 spec: selector 字段定義了 Deployment 如何找到要管理的 Pod。 在本例中,我們僅通過 Pod 模板中定義的標籤進行選擇 (app: demo-backend)。 我們希望有三個副本 Pod,並通過 replicas 字段進行指示。 模板字段定義了實際的 Pod:5.5. 清理服務和部署
$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend6. 使用配置文件的複雜部署
6.1. 後端應用服務定義
kind: Service
apiVersion: v1
metadata:
name: demo-backend
spec:
selector:
app: demo-backend
ports:
- protocol: TCP
port: 8080
type: ClusterIP6.2 後端應用程序部署定義
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-backend
spec:
selector:
matchLabels:
app: demo-backend
replicas: 3
template:
metadata:
labels:
app: demo-backend
spec:
containers:
- name: demo-backend
image: demo-backend:latest
imagePullPolicy: Never
ports:
- containerPort: 8080
field indicates that each Pod replication runs one container, demo-backend, with version latest">。
6.3 後端應用程序部署
現在我們可以觸發部署:
$> kubectl create -f backend-deployment.yaml讓我們驗證部署是否成功:
$> kubectl get deployments輸出結果如下所示:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
demo-backend 3 3 3 3 25s我們還可以檢查該服務是否可用:
$> kubectl get services輸出結果如下:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-backend ClusterIP 10.102.17.114 <none> 8080/TCP 30s如我們所見,該服務類型為 ClusterIP,它不提供 30000-32767 範圍內的任何外部端口,與我們在第 5 節之前的示例不同。
6.4 前端應用部署與服務定義
隨後,我們可以定義前端的服務和部署:
kind: Service
apiVersion: v1
metadata:
name: demo-frontend
spec:
selector:
app: demo-frontend
ports:
- protocol: TCP
port: 8081
nodePort: 30001
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-frontend
spec:
selector:
matchLabels:
app: demo-frontend
replicas: 3
template:
metadata:
labels:
app: demo-frontend
spec:
containers:
- name: demo-frontend
image: demo-frontend:latest
imagePullPolicy: Never
ports:
- containerPort: 8081前端和後端幾乎完全相同,唯一的區別在於服務規範。
對於前端,我們定義類型為NodePort(因為我們希望使前端對外暴露,不受集羣影響)。後端只需要在集羣內部可訪問,因此類型為ClusterIP。
正如之前所説,我們還手動指定NodePort,使用nodePort字段。
6.5 前端應用部署
我們可以以同樣的方式觸發本次部署:
$> kubectl create -f frontend-deployment.yaml讓我們快速驗證部署是否成功以及服務是否可用:
$> kubectl get deployments
$> kubectl get services<p>在那之後,我們終於可以調用前端應用程序的 REST 端點:</p>
$> minikube service demo-frontend此命令將再次啓動我們的默認瀏覽器,打開
在完成所有操作後,可以通過刪除服務和部署來清理: 在本文中,我們快速介紹瞭如何使用 Minikube 將 Spring Boot “Hello world” 應用部署到本地 Kubernetes 集羣。 我們詳細討論了以下內容:6.6. 清理服務和部署
$> kubectl delete service demo-frontend
$> kubectl delete deployment demo-frontend
$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend7. 結論