如何用 k3s 部署一个带 IoT 模块的 Spring Boot 项目
本文从通用部署视角出发,梳理如何用 k3s + Helm 部署一个带 IoT 模块的 Spring Boot 项目。重点不在某个具体项目,而在于把 MySQL、Redis、backend、frontend、iot 这些角色按清晰结构拆开,并讲清楚 values.yaml、时区、存储、端口和验证链路这些关键点。
很多 Spring Boot 项目在本地开发阶段,用 docker compose 就能跑起来。
但如果项目本身不只是一个后端服务,而是同时包含:
- 后端接口
- 前端页面
- 数据库
- 缓存
- IoT 模块
那部署方式就不能只停留在“能跑”。
真正需要考虑的是:这套服务怎么拆、怎么配、怎么重复交付、怎么在不同环境里稳定落地。
这也是为什么 k3s + Helm 很适合这类项目。
它不只是把服务跑起来,而是把部署过程收敛成一套结构化、可维护的方式。
1. 部署前要准备什么
在开始之前,至少要把下面这些东西准备好:
- 一套可用的
k3s集群 - 本地可用的
kubectl - 本地可用的
helm - 镜像仓库或可拉取镜像的环境
- 域名、NodePort 或 Ingress 访问方案
- 持久化存储能力
- 项目运行所需的基础配置
如果这些前置条件没准备好,后面部署过程通常会反复卡在环境问题上,而不是项目本身。
对这类项目来说,我更建议先把“环境准备”看成部署的一部分,而不是部署之前的额外动作。
2. 先部署基础设施:MySQL、Redis
这类项目部署时,最好不要一开始就直接上业务服务。
更合理的顺序是先把基础设施落下来,至少包括:
MySQLRedis
原因很简单。
业务服务启动时往往会直接依赖数据库和缓存。
如果基础设施没准备好,后面的 backend 和 iot 很可能刚启动就报连接错误,最后你很难分清楚到底是服务有问题,还是环境没准备好。
在 k3s 里,我更建议把基础设施单独作为一层处理,而不是和业务服务混在一起。
这样做有几个好处:
- 依赖关系更清楚
- 持久化更容易单独管理
- 密码、存储、时区配置更容易统一
- 后续升级业务服务时,不容易误动基础设施
这一层部署完成后,先做最基本的检查:
- Pod 是否正常 Running
- Service 是否创建成功
- 数据卷是否绑定成功
- MySQL 和 Redis 是否能正常对外提供连接
只有这一步确认没问题,后面的应用服务才值得继续往下走。
3. 再部署业务服务:backend、frontend、iot
基础设施准备好之后,再部署应用层服务。
对一个带 IoT 模块的 Spring Boot 项目来说,通常至少会有这几类服务:
backendfrontendiot
它们虽然属于同一个系统,但职责并不一样。
backend
backend 负责业务接口、账户体系、订单处理、计费逻辑、系统配置这些核心业务能力。
frontend
frontend 负责页面访问和交互,是整个系统的可视化入口。
iot
iot 负责设备接入、协议处理、命令下发和设备侧联动。
这也是为什么部署时不应该把它们简单看成“同一个应用的不同进程”,而应该明确分成独立服务。
因为它们的运行特点、网络暴露方式、依赖关系和后续扩展方式都不一样。
尤其是 iot,它和普通业务服务最大的不同在于,它通常还需要考虑:
- 独立端口暴露
- 协议链路
- 网络连接方式
- 设备侧接入行为
所以在 k3s 里把它单独编排,是很自然的事。
4. values.yaml 里哪些配置最关键
很多人第一次用 Helm 时,容易把重点放在模板文件上。
但真正决定部署能不能顺利落地的,往往是 values.yaml。
对这类项目来说,最关键的配置通常有下面几类。
4.1 镜像配置
包括:
- 镜像地址
- 镜像 tag
- 镜像拉取策略
这决定了你实际部署的是哪一版服务。
4.2 服务端口
包括:
- backend 暴露端口
- frontend 暴露端口
- iot 监听端口
如果这一层没配清楚,服务启动了也不一定能访问。
4.3 数据库和缓存连接
这是最基础的一层:
- MySQL 地址、端口、库名、账号密码
- Redis 地址、端口、密码
这些配置通常也是服务最先报错的地方。
4.4 时区配置
这点很容易被忽略,但实际很重要。
如果数据库、应用容器、IoT 服务时区不一致,很容易出现:
- 时间显示不一致
- 数据时间错位
- 日志排查困难
- 定时任务和上报时间异常
所以时区配置最好统一处理,而不是各服务自己随便配。
4.5 存储配置
对 MySQL 这类有状态服务来说,PVC 是否正确绑定,直接决定数据是否可靠。
如果这一层没配好,服务表面上能启动,但重建后数据可能直接丢失。
4.6 iot 相关配置
这一层一定要单独看:
- iot 服务是否启用
- 对外暴露方式
- 协议监听端口
- 接入相关配置
因为 iot 模块和普通 web 服务不同,它的配置项往往更偏运行环境,而不是单纯的 HTTP 接口行为。
5. 部署完成后怎么验证服务是否正常
部署完成后,不建议只看一句“release installed successfully”。
更稳的做法是按顺序验证。
5.1 先看资源状态
先看:
kubectl get podskubectl get svc
确认所有关键 Pod 都正常 Running,Service 也已经创建出来。
5.2 再看 backend
确认:
- 容器是否正常启动
- 日志里有没有数据库或 Redis 连接失败
- HTTP 接口是否能访问
5.3 再看 frontend
确认:
- 页面是否能打开
- 前端是否能正常请求后端
- 是否存在接口代理或跨域问题
5.4 再看 iot
这一层不能漏。
至少要确认:
- 端口是否已经监听
- 服务是否成功启动
- 配置是否已经正确注入
- 日志里有没有协议模块初始化异常
如果这是一个真实带设备接入的系统,这一步尤其重要。
5.5 最后确认依赖链路
再回头确认:
- backend 能正常连 MySQL
- backend 能正常连 Redis
- iot 服务也能正常使用自己的依赖配置
只有依赖链路也都通了,部署才算真正完成。
6. 部署这类项目时最容易遇到的几个问题
这类项目在 k3s 里部署时,最常见的问题通常不是模板语法,而是下面这些。
6.1 Pod 启动了,但服务不可用
这往往说明:
- 容器活了
- 但配置不对
- 或依赖没连上
- 或端口暴露方式有问题
6.2 数据库或 Redis 连不上
这种问题很常见,通常要看:
- Service 名称是否对
- 端口是否对
- 账号密码是否对
- 配置是否正确注入环境变量
6.3 时区不一致
如果日志时间、数据库时间、页面时间对不上,排查会非常痛苦。
所以时区统一一定要尽早处理。
6.4 PVC 没绑上
有状态服务最怕这个。
MySQL 启动了不代表真的能长期运行,数据卷状态必须单独确认。
6.5 iot 端口不通
这一层很容易被忽略。
因为很多人会优先验证前端和后端,却忘了 iot 其实还依赖独立端口和网络配置。
6.6 values 写了,但容器里没生效
这类问题通常出在:
- 模板引用不对
- key 名不一致
- configmap / secret 没正确挂载
- 环境变量没真正传进去
所以不要只看 values 文件本身,要看最终 Pod 里的实际运行结果。
7. 为什么我更推荐这种部署方式
我更推荐 k3s + Helm,不是因为它“更高级”,而是因为这类项目本来就不适合长期停留在手工部署状态。
一个带 IoT 模块的 Spring Boot 项目,通常天然就是多服务、多依赖的结构。
这种情况下,更重要的不是“把服务拉起来一次”,而是:
- 怎么让部署结构清楚
- 怎么让环境配置可维护
- 怎么让不同模块独立编排
- 怎么让部署过程可以重复执行
从这个角度看,k3s + Helm 的价值很实际。
它不是为了炫技术,而是为了把一套复杂一点的系统,变成可交付、可复用、可维护的部署方式。
8. 最后
如果你只是本地调试,一个 docker compose 当然足够。
但如果项目本身已经包含:
- 后端
- 前端
- MySQL
- Redis
- IoT 模块
那部署方式就值得认真设计了。
对这类项目来说,k3s + Helm 的意义不是“上云”这么简单,而是把多模块、多依赖、多运行角色的系统,整理成一套更稳定的交付结构。
如果你想看一个实际样例,也可以看看我的开源项目 ems4j。
ems4j 覆盖后台管理、计费结算、IoT 接入和相关部署能力,适合拿来参考这类项目在工程和部署层面的完整做法。欢迎 Star 和交流。
更多推荐
所有评论(0)