使用 Minikube 运行 Spring Boot 应用程序

更新于 2025-12-30

Markus Gulden 2024-01-08

使用 Minikube 运行 Spring Boot 应用程序

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 服务,分别命名为 frontendbackend

  • backend 在端口 8080 上提供一个 REST 接口,返回包含其主机名的字符串。
  • frontend 在端口 8081 上可用,它会调用 backend 的接口并返回其响应。

接下来,我们需要为每个应用构建 Docker 镜像。所有相关文件也可在 GitHub 上找到。

有关如何构建 Docker 镜像的详细说明,请参阅《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 虚拟机。后续所有操作都将在本地主机上通过 kubectlminikube 命令行工具执行。


5. 使用命令式命令进行简单部署

首先,我们将为 demo-backend 应用创建一个 Deployment(仅包含一个 Pod)。在此基础上,我们将介绍一些命令,用于验证部署、查看日志,并在最后清理资源。

5.1 创建 Deployment

我们将使用 kubectl,并通过参数传递所有必要信息:

$> kubectl run demo-backend --image=demo-backend:latest \
  --port=8080 --image-pull-policy Never

如上所示:

  • 我们创建了一个名为 demo-backend 的 Deployment;
  • 使用的镜像也叫 demo-backend,版本为 latest
  • 通过 --port 指定 Pod 监听 8080 端口(因为我们的 backend 应用监听该端口);
  • --image-pull-policy Never 确保 Minikube 不尝试从远程仓库拉取镜像,而是直接使用本地 Docker 主机上的镜像。

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

为了让 backend 的 REST 接口对外可用,我们需要创建一个 Service:

$> kubectl expose deployment demo-backend --type=NodePort
  • --type=NodePort 表示该 Service 可从集群外部访问;
  • 它将以 <NodeIP>:<NodePort> 的形式暴露服务,即将所有发往 <NodePort> 的请求转发到 Pod 的 8080 端口。

使用 expose 命令时,NodePort 由集群自动分配(这是技术限制),默认范围是 30000–32767。若要指定特定端口,需使用配置文件(见下一节)。

验证 Service 是否创建成功:

$> kubectl get services

输出如下:

NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
demo-backend   NodePort    10.106.11.133   <none>        8080:30117/TCP   11m

可以看到:

  • Service 名为 demo-backend,类型为 NodePort
  • 集群内部 IP 为 10.106.11.133
  • PORT(S) 列显示:外部可通过端口 30117 访问,该端口映射到 Pod 的 8080 端口。

5.4 调用 Service

现在可以首次调用 backend 服务:

$> minikube service demo-backend

该命令会自动在默认浏览器中打开 <NodeIP>:<NodePort>,例如:http://192.168.99.100:30117

5.5 清理 Service 和 Deployment

完成后,可删除 Service 和 Deployment:

$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend

6. 使用配置文件进行复杂部署

对于更复杂的部署场景,使用配置文件比通过命令行参数传递所有选项更为合适。

配置文件便于记录部署细节,并可纳入版本控制系统。

6.1 Backend 应用的 Service 定义

我们使用配置文件重新定义 backend 的 Service:

kind: Service
apiVersion: v1
metadata:
  name: demo-backend
spec:
  selector:
    app: demo-backend
  ports:
  - protocol: TCP
    port: 8080
  type: ClusterIP

说明:

  • 创建名为 demo-backend 的 Service;
  • 选择带有标签 app: demo-backend 的 Pod;
  • 监听 TCP 8080 端口;
  • 类型为 ClusterIP,表示仅在集群内部可访问(因为 frontend 会调用它,无需从浏览器直接访问)。

6.2 Backend 应用的 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

说明:

  • Deployment 名为 demo-backend
  • 通过 selector.matchLabels 匹配带有 app: demo-backend 标签的 Pod;
  • 启动 3 个副本(replicas: 3);
  • 每个 Pod 运行一个名为 demo-backend 的容器,使用本地镜像,监听 8080 端口。

6.3 部署 Backend 应用

执行部署:

$> kubectl create -f backend-deployment.yaml

验证部署:

$> kubectl get deployments

输出:

NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
demo-backend   3         3         3            3           25s

检查 Service:

$> kubectl get services

输出:

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
demo-backend    ClusterIP   10.102.17.114   <none>        8080/TCP         30s

注意:此次 Service 类型为 ClusterIP,没有分配 30000–32767 范围内的外部端口。

6.4 Frontend 应用的 Service 与 Deployment 定义

接着为 frontend 定义 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

主要区别:

  • frontend 的 Service 类型为 NodePort(需对外暴露);
  • 显式指定了 nodePort: 30001,以便从外部访问。

6.5 部署 Frontend 应用

执行部署:

$> kubectl create -f frontend-deployment.yaml

快速验证:

$> kubectl get deployments
$> kubectl get services

最后,调用 frontend 的 REST 接口:

$> minikube service demo-frontend

该命令将在浏览器中打开 http://192.168.99.100:30001

6.6 清理 Services 和 Deployments

完成测试后,清理资源:

$> kubectl delete service demo-frontend
$> kubectl delete deployment demo-frontend
$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend

7. 结论

在本文中,我们快速了解了如何在本地 Kubernetes 集群(Minikube)上部署一个 Spring Boot “Hello world” 应用。

我们详细讨论了以下内容:

  • 如何在本地机器上安装 Minikube;
  • 如何开发并构建包含两个 Spring Boot 应用的示例项目;
  • 如何在单节点集群中部署服务,既使用了 kubectl 的命令式操作,也使用了 YAML 配置文件进行声明式部署。

通过这种方式,开发者可以在本地高效地测试和调试基于 Kubernetes 的微服务架构。