为何K8s Nginx Ingress仅返回部分网页内容?
问题原因及解决方案
核心原因
- 错误的Ingress重写配置:你添加的
nginx.ingress.kubernetes.io/rewrite-target: /$1注解完全多余且会破坏请求路径。因为你的Ingress路径是/,没有定义任何捕获组(()包裹的内容),$1会是空值,导致所有请求被重写到//,静态资源的请求路径被篡改,无法匹配Pod内的实际资源位置。 - 静态资源路径匹配问题:如果容器内的Nginx没有正确配置静态资源的路由规则,或者React打包后的资源路径与Ingress转发的路径不匹配,浏览器请求的静态资源会返回404,最终导致页面空白。
分步解决方案
1. 修正Ingress配置
移除错误的rewrite-target注解,确保所有请求原封不动转发到后端服务:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: kubernetes.io/ingress.class: "nginx" # 删除原有的rewrite-target注解 spec: rules: - host: my-site.info http: paths: - path: / pathType: Prefix backend: service: name: frontend-service port: number: 3000
执行更新命令:
kubectl apply -f ingress.yaml
2. 确保Docker容器内的Nginx配置正确
React项目打包后需要Nginx正确指向build目录,同时处理单页应用的路由和静态资源请求。参考以下Docker配置:
Dockerfile
# 构建阶段 FROM node:18-alpine as builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # 部署阶段 FROM nginx:alpine # 将构建产物复制到Nginx的默认静态目录 COPY --from=builder /app/build /usr/share/nginx/html # 替换默认Nginx配置,适配React单页应用 COPY nginx.conf /etc/nginx/conf.d/default.conf
nginx.conf(放在项目根目录)
server { listen 80; root /usr/share/nginx/html; index index.html; # 静态资源缓存优化,确保资源请求正确匹配 location /static/ { expires 1y; add_header Cache-Control "public, immutable"; } # 处理React单页应用路由,刷新页面时返回index.html location / { try_files $uri $uri/ /index.html; } }
3. 验证React打包配置
如果你的Ingress是根路径访问,确保package.json中没有错误的homepage配置,默认即可,或者显式设置:
{ "homepage": "/" }
重新构建镜像并部署Pod:
docker build -t frontend-image:latest . # 推送镜像到你的镜像仓库(如果需要) kubectl rollout restart deployment/frontend-deployment
4. 排查验证
- 查看Ingress Controller日志,确认请求转发情况:
kubectl logs -n ingress-nginx $(kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -o name) - 查看前端Pod的Nginx日志,确认是否收到静态资源请求:
kubectl logs $(kubectl get pods -l app=frontend -o name) - 清空浏览器缓存,访问
http://my-site.info,打开开发者工具的网络标签,检查所有静态资源(static/js/*、static/css/*、manifest.json等)是否返回200状态码。
内容的提问来源于stack exchange,提问作者systems_n_systems
相关产品推荐
相关产品推荐

