Kubernetes仅启动后端服务,前端报Nginx 502错误求助
React+Node.js K8s部署前端无法显示问题排查与修复
问题描述
React前端+Node.js后端应用,Kubernetes部署后后端可正常访问,但前端无法显示,怀疑端口配置问题,对Docker和K8s不熟悉,无法定位根源。
现有配置文件
前端Dockerfile
FROM node:14.14.0-alpine as builder WORKDIR /app COPY ./package.json ./ RUN npm i COPY . . RUN npm run build FROM nginx COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf COPY --from=builder /app/build /usr/share/nginx/html COPY sw_PublicKey.crt /etc/ssl/sw_certificatePKCS7.crt COPY private_key.pem /etc/ssl/private_key.pem EXPOSE 443
后端Dockerfile
FROM node:14.14.0-alpine WORKDIR /app COPY ./package.json ./ RUN npm i COPY . . EXPOSE 4000 CMD ["npm", "run", "start"]
NGINX主配置文件
server{ listen 443 ssl; #listen 10.10.100.66:3000; #Type your domain name below server_name spesen.sxdes.de; ssl_certificate /etc/ssl/sw_certificatePKCS7.crt; ssl_certificate_key /etc/ssl/private_key.pem; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_protocols TLSv1.2; # Only use ciphersuites that are considered modern and secure by Mozilla ssl_ciphers 'ECDHE-ECDSA...'; ssl_prefer_server_ciphers on; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } }
NGINX Default.conf
upstream client { server client:3000; } upstream api { server api:4000; } server { listen 443; location / { proxy_pass http://client; } location /sockjs-node { proxy_pass http://client; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } location /api { rewrite /api/(.*) /$1 break; proxy_pass http://api; } }
Client ClusterIP Service
apiVersion: v1 kind: Service metadata: name: client-cluster-ip-service spec: type: ClusterIP selector: component: web ports: - port: 3000 targetPort: 3000
Client Deployment
apiVersion: apps/v1 kind: Deployment metadata: name: client-deployment spec: replicas: 1 selector: matchLabels: component: web template: metadata: labels: component: web spec: containers: - name: client image: ss/spesen-c:latest ports: - containerPort: 3000 env: - name: REACT_APP_GOOGLE_MAPS_API_KEY value: "..." imagePullSecrets: - name: secret/...
Ingress Service
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-service annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/use-regex: "true" nginx.ingress.kubernetes.io/rewrite-target: /$1 spec: rules: - http: paths: - path: /?(.*) pathType: Prefix backend: service: name: client-cluster-ip-service port: number: 3000 - path: /api/?(.*) pathType: Prefix backend: service: name: server-cluster-ip-service port: number: 4000
Server ClusterIP Service
apiVersion: v1 kind: Service metadata: name: server-cluster-ip-service spec: type: ClusterIP selector: component: web ports: - port: 4000 targetPort: 4000
Server Deployment
apiVersion: apps/v1 kind: Deployment metadata: name: server-deployment spec: replicas: 1 selector: matchLabels: component: web template: metadata: labels: component: web spec: containers: - name: server image: schorerwolfae/spesen-server ports: - containerPort: 4000 env: - name: ACCESS_TOKEN_SECRET value: "..." - name: REFRESH_TOKEN_SECRET value: "..." - name: DATABASE_URI value: "..." - name: AD_PASSWORD value: "..." imagePullSecrets: - name: secret/...
核心问题修复方案
1. 端口配置不匹配
前端Dockerfile暴露443端口,但Deployment和Service配置的是3000端口,完全不匹配。修改如下:
- 调整client-deployment的containerPort为443:
ports: - containerPort: 443 - 调整client-cluster-ip-service的targetPort为443:
ports: - port: 3000 targetPort: 443
2. NGINX配置冲突与冗余
前端容器内同时加载两个NGINX配置,且配置了反向代理,这在K8s环境中完全多余。简化配置:
- 修改前端Dockerfile,去掉SSL配置,让NGINX监听80端口:
FROM node:14.14.0-alpine as builder WORKDIR /app COPY ./package.json ./ RUN npm i COPY . . RUN npm run build FROM nginx:alpine COPY --from=builder /app/build /usr/share/nginx/html COPY ./nginx/spa.conf /etc/nginx/conf.d/default.conf EXPOSE 80 - 新建spa.conf,仅负责静态文件服务:
server { listen 80; root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } - 同步调整Deployment和Service的端口为80(可选,更符合常规配置)。
3. Service选择器冲突
Server和Client的Pod标签都是component: web,导致Server Service会把流量转发到Client Pod,修改如下:
- 调整server-deployment的Pod标签:
template: metadata: labels: component: api - 调整server-cluster-ip-service的选择器:
selector: component: api
4. Ingress路由优化
针对React单页应用调整Ingress规则,避免路由异常:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-service annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/use-regex: "true" nginx.ingress.kubernetes.io/rewrite-target: /$1 # 适配SPA路由的额外配置 nginx.ingress.kubernetes.io/configuration-snippet: | rewrite ^(/api)$ $1/ permanent; spec: rules: - http: paths: - path: /(.*) pathType: Prefix backend: service: name: client-cluster-ip-service port: number: 3000 - path: /api/(.*) pathType: Prefix backend: service: name: server-cluster-ip-service port: number: 4000
(若需要SSL,建议在Ingress层配置证书,而非前端容器内)
验证步骤
- 应用修改后的配置:
kubectl apply -f <配置文件路径> - 检查Client Pod状态:
kubectl get pods - 查看Client容器日志:
kubectl logs <client-pod-name> - 本地端口转发测试:
kubectl port-forward service/client-cluster-ip-service 3000:3000,访问localhost:3000验证前端是否正常显示
内容的提问来源于stack exchange,提问作者Luke_KS
相关产品推荐
相关产品推荐

