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

配置健康检查和资源限制

试试滚动更新和回滚

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

相关推荐
数字新视界4 小时前
动环监控系统为机房管理者带来了哪些好处?
物联网·数据中心·机房·动环监控系统·动力与环境监控系统·机房动环监控
卷无止境5 小时前
Windows 上丝滑开发 Python,并稳定构建 Docker 镜像
后端·python·docker
一只鹿鹿鹿7 小时前
大数据中心安全系统解决方案(Word文件)
大数据·运维·物联网·安全·政务
万里侯8 小时前
GitOps 2026年演进趋势:从配置管理到环境即代码的范式转移及Pull vs Push模型的再思考
微服务·容器·k8s
acd120098 小时前
一次线上OOM排查实录:从jmap到代码重构,我踩过的坑全在这了
容器·重构·kubernetes
吕海洋10 小时前
目前可用的docker源2026.08
运维·docker·容器
gsls20080812 小时前
Penpot Docker 部署与 MCP 服务配置文档
运维·docker·容器·原型·penpot
天蓝不会忘记0212 小时前
k8s集群部署的方法原理
云原生·容器·kubernetes
xrlfreedom13 小时前
大厂 MCP 面试实录:本地 Server 远程化改造中的技术选型与落地实践
docker·json schema·mcp
红球yyds13 小时前
用anisble搭建k8s集群及原理
云原生·容器·kubernetes