从 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 小时前
物联网 MQTT订阅性能优势
网络·物联网
AOwhisky1 小时前
Docker 学习笔记:从生态系统到镜像构建
linux·运维·笔记·学习·docker·容器
鉴生Eric1 小时前
FOR硬件通讯算法在应对复杂电磁环境时的具体技术优势
物联网·分布式mesh网络架构
Elastic 中国社区官方博客1 小时前
使用 Elasticsearch 与 Kibana 中的 PromQL 调查 Kubernetes 基础设施问题
大数据·数据库·elasticsearch·搜索引擎·信息可视化·kubernetes·全文检索
江湖有缘1 小时前
Docker部署PortNote端口自动检测工具
运维·docker·容器
馨谙1 小时前
云原生 Kubernetes 核心概念与组件详解
云原生·容器·kubernetes
砍材农夫1 小时前
物联网 MQTT简易版Broker,基于spring-boot socket
物联网
云达闲人2 小时前
搭建DevOps企业级仿真实验环境:011Kubernetes 核心架构与组件
运维·kubernetes·devops·k8s 核心架构·k8s 组件解析·devops 实验环境·proxmox 虚拟化
苍煜2 小时前
Kubernetes 核心认知与集群架构(从Docker过渡到K8s)
docker·架构·kubernetes