从 Docker Compose 到 Kubernetes:物联网管理系统迁移实战(3)—— 两个运维坑

一、项目背景

物联网管理系统最初采用 Docker Compose 部署,结构简单:前端 Nginx + 后端 Spring Boot + MySQL。随着业务发展,单机部署的问题逐渐显现:单点故障、无法扩缩容、发布需停服。

本次实验的目标是将这套系统迁移到 Kubernetes 集群,体验从"单机编排"到"集群调度"的转变。

前四篇文章记录了集群搭建、镜像构建、应用部署、健康检查配置的过程。系统终于跑起来了,但在后续运维中又遇到了两个典型问题:

  1. 虚拟机重启后 kubectl 证书失效

  2. 数据库迁移后表不存在导致 500 错误

这两个问题在实际工作中非常常见,记录如下:

问题1:虚拟机重启后 kubectl 证书失效

现象:

每次重启虚拟机后,执行 kubectl 命令都会报错:

复制代码
kubectl get pods
# Unable to connect to the server: x509: certificate signed by unknown authority

原因:

kubectl 需要读取集群证书才能与 API Server 通信。证书配置存储在 $HOME/.kube/config 文件中,但每次重启后环境变量丢失或配置文件路径不正确,导致 kubectl 找不到正确的证书。

export KUBECONFIG=/etc/kubernetes/admin.conf 能临时解决,但重启后环境变量会丢失。

解决方案:

将配置写入 ~/.bashrc,让每次登录时自动设置环境变量。

复制代码
echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> ~/.bashrc
source ~/.bashrc

验证:

复制代码
# 重新登录或执行 source ~/.bashrc 后测试
kubectl get nodes

复盘:

kubectl 默认读取 $HOME/.kube/config,如果该文件不存在或内容不正确,就需要通过 KUBECONFIG 环境变量指定配置文件路径。将环境变量写入 ~/.bashrc 可以保证每次登录都自动生效,避免重复配置。

问题二:数据库迁移后表不存在导致 500 错误

背景:

因实验需要,想把数据库从 node2 迁移到 node1(后来改用 node2 的 /root/k8s-zabbix/ 目录)。迁移后,前端页面无法加载设备列表,后端接口返回 500 错误。

现象:

复制代码
curl http://192.168.116.168:30786/device/list
# 返回 500 Internal Server Error

排查过程:

1. 查看后端日志

复制代码
kubectl logs -l app=iot-backend --tail=200 | grep -E "ERROR|Exception" -A5 -B5

发现关键错误:

复制代码
java.sql.SQLSyntaxErrorException: Table 'iot.device' doesn't exist

2. 进入数据库确认表是否存在

复制代码
kubectl exec -it $(kubectl get pod -l app=iot-database -o jsonpath='{.items[0].metadata.name}') -- mysql -uroot -pjjsg_2yj -e "USE iot; SHOW TABLES;"

输出为空,确认 device 表不存在。

原因:

迁移数据库到新节点后,新创建的 MySQL Pod 是全新的,没有执行 iot.sql 初始化脚本,导致 device 表未创建。

解决方案:

手动创建 device 表:

复制代码
kubectl exec -it $(kubectl get pod -l app=iot-database -o jsonpath='{.items[0].metadata.name}') -- mysql -uroot -pjjsg_2yj iot -e "
CREATE TABLE device (
    device_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '设备主键',
    device_name VARCHAR(100) NOT NULL COMMENT '设备名称',
    device_type VARCHAR(50) NOT NULL COMMENT '设备类型',
    serial_number VARCHAR(64) NOT NULL COMMENT '序列号',
    status ENUM('online','offline','error','maintenance') NOT NULL DEFAULT 'offline',
    last_heartbeat DATETIME DEFAULT NULL,
    location VARCHAR(255) DEFAULT NULL,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (device_id),
    UNIQUE KEY ux_devices_serial (serial_number)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
"

验证:

bash

复制代码
# 确认表已创建
kubectl exec -it $(kubectl get pod -l app=iot-database -o jsonpath='{.items[0].metadata.name}') -- mysql -uroot -pjjsg_2yj -e "USE iot; SHOW TABLES;"

# 测试后端接口
curl http://192.168.116.168:30786/device/list

最终验证:

浏览器访问 http://192.168.116.168:30081,设备管理功能恢复正常。

复盘:

迁移数据库时,新 Pod 不会自动执行初始化 SQL 脚本。需要手动建表或从备份恢复数据。建议在迁移前先导出数据,迁移后再导入,避免数据丢失。


五、总结

两个问题的核心都是"配置丢失":

问题 原因 解决方案
kubectl 证书失效 环境变量丢失 写入 ~/.bashrc
数据库表不存在 初始化脚本未执行 手动建表或导入备份

Kubernetes 提供了强大的自动化能力,但某些细节(如环境变量持久化、数据迁移)仍需人工介入。记录这些"坑",能帮助自己和他人少走弯路。

相关推荐
杨云龙UP20 分钟前
TDengine 3.4.2.8 Community 三节点三副本生产集群部署实战(DNode/MNode/taosAdapter/Explorer)
大数据·linux·运维·数据库·tdengine·时序库
梦帮科技42 分钟前
领域认知知识库图谱注入:从双式记账图网络到高质量问答对自动化合成流水线
运维·网络·数据库·人工智能·矩阵·架构·自动化
逐流人1 小时前
Ceph分布式存储集群配置与池管理:从配置优先级到PG、复本池与纠删码池
运维·分布式·ceph·云原生·云计算·rados
海宇服务1 小时前
零信任架构实战:基于海宇车型识别精准构建自动化定损网关
运维·人工智能·架构·自动化
Fcy6482 小时前
Linux下 进程间关系与守护进程
linux·运维·服务器·守护进程
g10565591392 小时前
公有云_云运维服务
java·运维·服务器
well06122 小时前
Linux粘滞位与Makefile机制深度解析
linux·运维·服务器
hzxpaipai2 小时前
杭州企业官网怎么建设?从策划到上线的5步建站方法
运维·服务器·前端·网络
哲霖软件3 小时前
非标机械设备公司怎么做信息化?破解通用ERP水土不服难题
大数据·运维
子木HAPPY阳VIP3 小时前
Ubuntu 关闭防火墙操作步骤
linux·运维·ubuntu