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

配置健康检查和资源限制

试试滚动更新和回滚

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

相关推荐
石小千14 分钟前
修改Docker Engine 存储路径
运维·docker·容器
xinyu3912 小时前
旧版Ubuntu Docker镜像 apt 失败
linux·ubuntu·docker
bin91533 小时前
使用Docker安装github项目 源码中含有 docker-compose.yml
docker·eureka·github
weixin_307779133 小时前
Linux下Docker Compose里运行Milvus向量数据库故障诊断Shell脚本
linux·运维·数据库·docker·milvus
Zhu7583 小时前
在k8s环境部署ApacheGuacamole,分别对接MySQL和PG数据库
数据库·mysql·kubernetes
小鱼儿电子3 小时前
58-基于物联网的老年人医嘱联动健康监测装置
stm32·物联网·腾讯云·健康手环
SuperherRo3 小时前
云上攻防-云原生篇&Docker安全&Dockfile文件构建制作&不安全的镜像&不安全第三方组件
docker·dockerfile·不安全镜像·第三方组件
Zhu7584 小时前
在Docker环境部署ApacheGuacamole,对接MySQL数据库
运维·docker·容器
慧一居士6 小时前
K3s和K8s的区别
容器