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

相关推荐
雨田大大1 小时前
Windows11下IDEA运行后端时,端口被占用的解决方法
linux·运维·服务器
smileNicky1 小时前
CentOS 8 安装 Docker 超详细教程
docker·eureka·centos
IKun-bug1 小时前
CentOS 7 安装 Claude Code 指南
linux·运维·centos
上海云盾-小余1 小时前
服务器入侵应急处置:痕迹清理、漏洞封堵与事后加固全流程
运维·服务器
风曦Kisaki1 小时前
# Linux运维Day02:LNMP架构部署、动静分离原理、Nginx地址重写、systemd服务管理
linux·运维·架构
Shadow(⊙o⊙)1 小时前
Linux进程地址空间——钻入Linux内核架构性剖析 硬核手搓!
java·linux·运维·服务器·开发语言·c++
大明者省1 小时前
乌邦托服务器系统www不同文件夹bird、infra建立隔离的虚拟环境
linux·运维·服务器
MXsoft6181 小时前
**降本增效两不误:精细化运维助力业务持续增长**
运维
团象科技1 小时前
跨境业务运维压力攀升,云原生运维补齐 AI 出海底层支撑短板
运维·人工智能·云原生