从 Docker Compose 到 Kubernetes:物联网管理系统迁移实战(续1)

续:排错记

上篇文章记录了从零搭建集群、解决镜像拉取失败(ImagePullBackOff)和存储卷绑定(PVC Pending)的过程。

🔥 挑战 5(延续):数据库表不存在

现象

后端接口返回 500 错误


排错思路

第一步:确认数据库 Pod 状态

复制代码
kubectl get pods -l app=iot-database

Pod 是 Running,说明数据库容器本身正常。

第二步:确认数据库和表是否存在

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

输出显示 iot 数据库存在。

复制代码
kubectl exec -it ... -- mysql -uroot -pjjsg_2yj -e "USE iot; SHOW TABLES;"

输出为空,说明 device 表不存在。

第三步:确认 SQL 文件是否被自动执行

检查数据库初始化日志:

复制代码
kubectl logs -l app=iot-database | grep -i "iot.sql\|device"

没有相关输出,说明 MySQL 容器启动时跳过了初始化脚本(因为 PVC 已有数据,不是第一次启动)。

第四步:手动建表

iot.sql 文件中提取 CREATE TABLE 语句,手动执行:

bash

复制代码
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;
"

第五步:验证

复制代码
kubectl exec -it ... -- mysql -uroot -pjjsg_2yj -e "USE iot; SHOW TABLES;"

输出 device,表创建成功

复制代码
curl http://10.109.210.199:8080/device/list

返回 {"data":{"records":[],"total":0,...},"success":true},不再是 500 错误。


核心结论

MySQL 容器只在第一次启动时执行 /docker-entrypoint-initdb.d/ 下的 SQL 文件。如果 PVC 已有数据,会跳过初始化。此时手动建表是最快的恢复方式。

🔥 挑战 6:浏览器缓存导致前端无法加载最新配置

现象

修改了 config.js 中的后端地址,重新构建镜像并部署后,浏览器仍然请求旧的 localhost:8080,前端无法调用 API。

排错思路

  1. 确认服务端是否正确 :进入 Pod 查看 config.js 内容,确认文件已更新
  1. 确认网络层是否正确 :用 curl 直接请求 JS 文件,确认 Nginx 返回的是新内容
  1. 定位问题层级 :服务端正确,但浏览器控制台显示旧值 → 问题出在浏览器缓存

  2. 尝试常规清除:清空缓存、无痕模式、硬刷新 → 无效无痕模式下仍显示 localhost

  3. 绕过缓存:修改 Service NodePort,让浏览器访问新地址

结果

访问新端口,控制台显示正确的 BASE_URL,前端正常调用后端 API。

核心结论

浏览器强缓存无法通过常规手段清除时,最快的验证方法是换一个从未访问过的端口或地址。生产环境应通过 Cache-Control 响应头或静态资源版本号来规避此类问题。

一点感悟

这次实验从零开始,CentOS 7.9,内网环境。磕磕绊绊走下来,踩过的坑比想象的多:

版本不兼容(K8S 1.22 + Docker 20.10 就是不行)

网络不通(镜像拉不下来,离线导入折腾半天)

配置细节(cgroup 驱动不一致、PVC 忘记建、SQL 脚本没自动执行)

浏览器缓存(改完代码不生效,最后换端口解决)

每一个问题单独看都不大,但串在一起,每一步都可能卡住。

下一步

如果还有时间,可能会继续折腾:

用 Ingress 代替 NodePort,通过域名访问

配置健康检查和资源限制

试试滚动更新和回滚

这篇博客记录的不是标准答案,而是一个普通开发者在真实环境里手搓的过程。有不对的地方,欢迎指正

相关推荐
曲幽1 小时前
别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了
python·docker·web·pot·translate·libretranslate·arogstranslate
武子康2 天前
调查研究-183 Apple container:Mac 上用轻量 VM 跑 Linux 容器,Swift 会改写本地容器体验吗?
docker·容器·apple
Inhand陈工5 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
Alsn865 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
大鱼>5 天前
大语言模型+物联网:LLM理解物理世界
物联网·struts·语言模型·多模态·aiot
果丁智能5 天前
物联网智能锁赋能集中式住宿:身份核验与远程权限管控的全链路技术实践
大数据·人工智能·物联网·智能家居
国产化创客5 天前
ESP32 CameraWebServer 原生摄像头项目全解析
物联网·开源·嵌入式·实时音视频·智能硬件
谁似人间西林客5 天前
数据智能怎么赋能工业制造?物联网场景落地方法解析
物联网·制造
InHand云飞小白5 天前
无人值守站点网络困境?工业级路由器IR315破解连接难题
网络·物联网·4g·工业路由器·4g路由器·iiot·蜂窝路由器
2601_961875245 天前
决战申论100题2026|最新|范文
linux·容器·centos·debian·ssh·fabric·vagrant