1. 事件概述
- 事件: “资产登记中心”前端项目(registry-ui)在新版本部署后,应用所有页面路径均返回404 Not Found错误。
- 核心结论: 本次故障的根本原因是镜像构建阶段所使用的
Dockerfile配置错误,导致基础镜像与Nginx配置文件路径不匹配,使得为单页面应用(SPA)定制的路由重写规则未能生效。 - 报告目的: 本报告旨在深入复盘404问题的排查过程与根源,并借此机会详细梳理前端项目的完整构建部署流程,以固化标准、避免未来发生同类问题。
2. 404故障深度复盘
2.1. 故障现象与排查
- 现象: 用户访问应用时,浏览器接收到404状态码。
- 排查关键点:
- Pod状态: 通过
kubectl get pods确认容器正在正常运行。 - Nginx日志: 通过
kubectl logs发现错误日志open() "/usr/local/openresty/nginx/html/login" failed。此日志表明,Nginx将前端路由/login误认为是对一个物理文件的请求,这是典型的SPA配置失效表现。
- Pod状态: 通过
2.2. 根本原因分析:Dockerfile的配置错误
问题的根源在于Dockerfile中的两个关键配置项存在不匹配:
-
基础镜像 (
FROM):- 故障版本使用了
openresty作为基础镜像。openresty是Nginx的增强版,其内部文件结构与标准Nginx不同,其主配置文件位于/usr/local/openresty/nginx/conf/nginx.conf。
- 故障版本使用了
-
配置加载方式 (
ADD):- 变更前的错误
Dockerfile:# 使用了错误的组合:openresty镜像 + 一个非其主配置也非其include的路径 FROM docker.1ms.run/openresty/openresty:latest ADD nginx.conf /etc/nginx/nginx.conf - 分析:
openresty服务启动时,并未加载被错误放置在/etc/nginx/nginx.conf的配置文件,导致其以默认配置运行,无法处理SPA的虚拟路由,从而对所有前端路径返回404。
- 变更前的错误
2.3. 解决方案:从临时修复到标准化重构
本次修复分为两个阶段,清晰地展示了从“快速恢复服务”到“根除隐患”的过程。
-
阶段一:中间临时修复 (让
openresty正常工作)- 目标: 尽快恢复线上服务。
- 操作: 运维工程师在保持
openresty基础镜像不变的情况下,将Dockerfile中的ADD指令的目标路径修正为openresty正确的主配置文件路径,以强制覆盖的方式使配置生效。 - 中间修复版的
Dockerfile:# 临时修复版:基础镜像不变,仅修正配置文件路径以匹配openresty FROM docker.1ms.run/openresty/openresty:latest ADD dist /app/dist # 修正:直接覆盖openresty的主配置文件 ADD nginx.conf /usr/local/openresty/nginx/conf/nginx.conf - 结果: 应用恢复正常访问。但此方案仍存在技术选型过度复杂、配置路径非标的问题。
-
阶段二:最终标准化修复 (回归
nginx)- 目标: 采用更标准、更简洁的技术方案,降低维护成本和出错风险。
- 操作: 运维工程师对
Dockerfile进行了彻底的优化。 - 最终修复版的
Dockerfile:# 文件路径: /data/assets/images-selftest/ui/Dockerfile # 最终版:基础镜像和配置路径均回归nginx标准 FROM registry.kubeease.cn/kubeease/nginx:stable ADD dist /app/dist ADD nginx.conf /etc/nginx/nginx.conf - 修复逻辑: 将基础镜像从
openresty更换为轻量、标准的nginx。同时,将配置文件的覆盖路径也修正为nginx公认的标准主配置文件路径。这一修改使得Dockerfile的意图清晰、不易出错。
3. 前端项目构建部署全流程解析
本次故障排查完整地展现了前端项目从代码到线上服务的四个核心阶段。
阶段一:准备 (Preparation)
- 地点: 在主控服务器
master1的指定工作目录,如/data/assets/images-selftest/ui/。 - 核心产物:
dist/目录 (前端代码)、nginx.conf文件 (服务配置)、Dockerfile文件 (打包规范)、make-images.sh脚本 (自动化工具)。
阶段二:构建与推送 (Build & Push)
- 触发: 在
master1服务器的工作目录下,执行sh make-images.sh。 - 脚本内容:
# /data/assets/images-selftest/ui/make-images.sh docker build -f Dockerfile -t dockerhub.kubeyey.local/edata/de_asset_registration_service_ui:v630-xc . docker push dockerhub.kubeyey.local/edata/de_asset_registration_service_ui:v630-xc - 流程:
docker build根据Dockerfile生成本地镜像,docker push将镜像上传至公司内部仓库。
阶段三:声明更新 (Deployment Update)
- 操作: 运维工程师修改Kubernetes的
Deployment资源文件,将其引用的镜像标签更新为新构建的版本(如:v630-xc)。 - 执行:
kubectl apply -f your-deployment.yaml -n asset。 - 意义: 向Kubernetes集群声明一个期望状态:“我希望
registry-ui应用最终都运行这个新版本的镜像”。
阶段四:滚动更新 (Rollout Restart)
- 触发: 执行
/data/assets/kds-deploy/restart-deployment.sh脚本。 - 核心命令: 该脚本最终会调用
kubectl rollout restart deployment registry-ui -n asset。 - 流程: Kubernetes收到命令后,平滑地、逐一地将所有运行着旧镜像的Pod替换为运行新镜像的Pod,使变更最终生效。
4. 总结与建议
- 总结: 本次404故障的本质是一次由于技术栈不匹配(
openresty镜像 vsnginx配置路径)导致的部署配置事故。通过“临时修复”和“最终优化”两步操作,不仅恢复了服务,还完成了技术栈的标准化重构。 - 建议:
- 标准化基础镜像: 前端SPA项目统一使用
registry.kubeease.cn/kubeease/nginx:stable作为基础镜像。 Dockerfile规范化: 将最终修复的Dockerfile作为该项目的标准模板,固化到版本控制中。- 加强Code Review: 将
Dockerfile的变更纳入代码审查范围,确保配置与基础环境的匹配性。
- 标准化基础镜像: 前端SPA项目统一使用