一、项目背景
物联网管理系统最初采用 Docker Compose 部署,结构简单:前端 Nginx + 后端 Spring Boot + MySQL。随着业务发展,单机部署的问题逐渐显现:单点故障、无法扩缩容、发布需停服。
本次实验的目标是将这套系统迁移到 Kubernetes 集群,体验从"单机编排"到"集群调度"的转变。
前四篇文章记录了集群搭建、镜像构建、应用部署、健康检查配置的过程。系统终于跑起来了,但在后续运维中又遇到了两个典型问题:
-
虚拟机重启后 kubectl 证书失效
-
数据库迁移后表不存在导致 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 提供了强大的自动化能力,但某些细节(如环境变量持久化、数据迁移)仍需人工介入。记录这些"坑",能帮助自己和他人少走弯路。





