从 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,通过域名访问

配置健康检查和资源限制

试试滚动更新和回滚

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

相关推荐
maomao大哥闯天下1 小时前
K8s如何实现滚动更新、健康检查与探测机制
docker·容器·kubernetes
kaisun641 小时前
Docker 构建网络问题排查
网络·docker·eureka
楼田莉子1 小时前
Docker学习:Docker介绍及其架构介绍
运维·后端·学习·docker·容器·架构
SpikeKing2 小时前
LLM - 集成 Hermes Agent 与 WebUI 至同一个 Docker 镜像配置
docker·webui·vibecoding·hermes agent
Geometry Fu2 小时前
《物联网安全》第3.2章 无线传感器网络安全
物联网·安全·物联网安全·无线传感器网络·wsn
杨浦老苏3 小时前
网络连接实时可视化利器TapMap
网络·docker·可视化·监控·群晖
张忠琳3 小时前
【kubernetes v1.21】(一)Kubernetes 总览架构深度分析
云原生·架构·kubernetes
香气袭人知骤暖3 小时前
PG数据库 Docker 容器自动备份方案
数据库·docker·容器
AI服务老曹4 小时前
解耦异构算力:基于 Docker 与 GB28181/RTSP 的边缘计算 AI 视频管理平台架构设计与源码交付实践
人工智能·docker·边缘计算
weixin_468466854 小时前
Prometheus监控服务部署与实战指南
服务器·后端·python·docker·自动化·prometheus