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 服务:frontendbackend

  • 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 虚拟机后,后续步骤将在主机上通过 kubectlminikube 命令执行。

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 的 Pod
  • ports:映射到 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 选择 Pod
  • replicas: 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(外部可访问) vs ClusterIP(仅内部)
  • **手动指定 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 获取。


原始标题:Running Spring Boot Applications With Minikube