1. 概述
在上一篇文章中,我们介绍了 Kubernetes 的理论基础。本教程将演示如何在本地 Kubernetes 环境(即 Minikube)中部署 Spring Boot 应用。
本文将涵盖:
- 在本地安装 Minikube
- 开发包含两个 Spring Boot 服务的示例应用
- 使用 Minikube 在单节点集群上部署应用
- 通过配置文件部署应用
2. 安装 Minikube
Minikube 安装包含三个步骤:安装虚拟机管理程序(如 VirtualBox)、kubectl 命令行工具以及 Minikube 本身。官方文档提供了所有主流操作系统的详细说明。
安装完成后,启动 Minikube,设置 VirtualBox 为虚拟机管理程序,并配置 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
。
backend
:在 8080 端口提供 REST 接口,返回包含主机名的字符串frontend
:在 8081 端口可用,调用backend
接口并返回其响应
需要为每个应用构建 Docker 镜像。所有必要文件可在 GitHub 获取。构建步骤参考 Dockerizing a Spring Boot Application。
关键点:必须在 Minikube 集群的 Docker 主机上执行构建,否则部署时 Minikube 将找不到镜像。此外,需将主机工作目录挂载到 Minikube 虚拟机:
$> minikube ssh
$> cd /c/workspace/tutorials/spring-cloud/spring-cloud-kubernetes/demo-backend
$> docker build --file=Dockerfile \
--tag=demo-backend:latest --rm=true .
退出 Minikube 虚拟机后,后续步骤将在主机上通过 kubectl
和 minikube
命令执行。
5. 使用命令式命令简单部署
5.1. 创建 Deployment
使用 kubectl
创建 demo-backend
的 Deployment(仅包含一个 Pod):
$> kubectl run demo-backend --image=demo-backend:latest \
--port=8080 --image-pull-policy Never
参数说明:
--image
:指定镜像demo-backend:latest
--port
:声明 Pod 开放 8080 端口(应用监听端口)--image-pull-policy Never
:禁止从远程仓库拉取镜像,强制使用本地镜像
5.2. 验证 Deployment
检查部署状态:
$> 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. 为 Deployment 创建 Service
使后端应用的 REST 接口可访问需创建 Service:
$> kubectl expose deployment demo-backend --type=NodePort
--type=NodePort
使服务可从集群外部访问,通过 <NodeIP>:<NodePort>
映射到 Pod 的 8080 端口。
⚠️ 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
PORT(S)
列显示:
- 内部端口 8080(Pod 监听端口)
- 外部端口 30117(浏览器访问端口)
5.4. 调用 Service
首次调用后端服务:
$> minikube service demo-backend
此命令自动打开浏览器访问 <NodeIP>:<NodePort>
(如 http://192.168.99.100:30117
)。
5.5. 清理 Service 和 Deployment
删除资源:
$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend
6. 使用配置文件复杂部署
对于复杂场景,配置文件比命令行参数更合适。配置文件可版本化且便于文档化。
6.1. 后端应用的 Service 定义
使用配置文件重新定义后端服务:
kind: Service
apiVersion: v1
metadata:
name: demo-backend
spec:
selector:
app: demo-backend
ports:
- protocol: TCP
port: 8080
type: ClusterIP
关键点:
metadata.name
:服务名demo-backend
selector
:选择标签为app=demo-backend
的 Podports
:映射到 Pod 的 8080 端口type: ClusterIP
:仅集群内部可访问(供frontend
调用)
6.2. 后端应用的 Deployment 定义
定义实际 Deployment:
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
关键点:
spec.selector
:通过标签app=demo-backend
选择 Podreplicas: 3
:创建 3 个副本template
:定义 Pod 模板labels
:Pod 标签app=demo-backend
containers
:使用demo-backend:latest
镜像,开放 8080 端口
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
,无外部端口(与第 5 节不同)。
6.4. 前端应用的 Service 和 Deployment 定义
定义前端服务与部署:
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
与后端的关键差异:
- Service 类型:
NodePort
(外部可访问) vsClusterIP
(仅内部) - **手动指定
nodePort
**:通过nodePort: 30001
固定端口
6.5. 部署前端应用
执行部署:
$> kubectl create -f frontend-deployment.yaml
快速验证:
$> kubectl get deployments
$> kubectl get services
调用前端接口:
$> minikube service demo-frontend
浏览器将打开 <NodeIP>:<NodePort>
(如 http://192.168.99.100:30001
)。
6.6. 清理所有资源
删除服务和部署:
$> kubectl delete service demo-frontend
$> kubectl delete deployment demo-frontend
$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend
7. 总结
本文演示了如何使用 Minikube 在本地 Kubernetes 集群部署 Spring Boot "Hello world" 应用。详细介绍了:
- 本地安装 Minikube
- 开发和构建双 Spring Boot 应用示例
- 通过
kubectl
命令和配置文件在单节点集群部署服务
完整示例代码可在 GitHub 获取。