You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes服务认知误区:React与Rust后端通信故障排查

问题分析

你遇到的核心问题是浏览器无法解析Kubernetes集群内部的Service DNS名称。backend是集群内ClusterIP服务的域名,只有集群里的Pod能通过K8s DNS服务解析,而你的前端请求在用户浏览器中发起(浏览器处于集群外部),自然无法识别这个域名,导致ERR_NAME_NOT_RESOLVED错误。

下面是几种可行的解决方案,按生产实用性排序:


方案一:Nginx反向代理(生产首选)

把React应用打包后部署在Nginx容器中,通过Nginx配置反向代理,将前端的API/WebSocket请求转发到集群内的backend服务。Nginx运行在K8s Pod里,属于集群内部,能正常解析backend域名。

1. 修改前端请求路径

将前端代码中的绝对地址改为相对路径:

  • 把http://backend:8080/test改为/api/test
  • 把ws://<minikube-ip>/ws改为/ws

2. 编写Nginx配置文件(nginx.conf)

server {
  listen 80;
  server_name localhost;

  # 托管React静态文件
  root /usr/share/nginx/html;
  index index.html;

  # 处理React路由刷新404问题
  location / {
    try_files $uri $uri/ /index.html;
  }

  # 反向代理API请求到后端服务
  location /api/ {
    proxy_pass http://backend:8080/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }

  # 反向代理WebSocket请求
  location /ws {
    proxy_pass http://backend:8080/ws;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
  }
}

3. 构建包含Nginx的前端镜像

创建Dockerfile:

# 阶段1:构建React应用
FROM node:18-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 阶段2:部署到Nginx
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

重新构建并推送镜像:

docker build -t quan1um/react-test:nginx .
docker push quan1um/react-test:nginx

4. 更新前端Deployment配置

修改前端Deployment的容器镜像和端口:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: client-deployment
  labels:
    app: client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: client
  template:
    metadata:
      labels:
        app: client
        tier: frontend
    spec:
      containers:
      - name: client
        image: quan1um/react-test:nginx
        imagePullPolicy: Always
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: client-service
spec:
  selector:
    app: client
    tier: frontend
  ports:
    - protocol: "TCP"
      port: 80
      targetPort: 80
  type: LoadBalancer

部署更新后的配置:

kubectl apply -f client-deployment.yaml

现在通过minikube service client-service访问前端,所有/api和/ws请求会自动被Nginx转发到backend:8080,解决域名解析问题。


方案二:暴露后端服务+前端环境变量注入

如果不想用Nginx,可以把后端服务暴露为NodePort/LoadBalancer,然后在前端代码中通过环境变量注入后端的外部访问地址。

1. 修改后端Service为NodePort

apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
    app: backend
  ports:
    - protocol: TCP
      port: 8080
      targetPort: http
      nodePort: 30080 # 可选,指定固定端口
  type: NodePort

获取后端外部访问地址:

minikube service backend --url

2. 给前端Deployment添加环境变量

spec:
  containers:
  - name: client
    image: quan1um/react-test:latest
    imagePullPolicy: Always
    ports:
    - containerPort: 3000
    env:
    - name: REACT_APP_API_URL
      value: "http://<minikube-ip>:30080" # 替换为上面获取的地址
    - name: REACT_APP_WS_URL
      value: "ws://<minikube-ip>:30080"

3. 前端代码使用环境变量

// API请求
fetch(`${process.env.REACT_APP_API_URL}/test`)
  .then(res => res.json())
  .then(data => console.log(data));

// WebSocket连接
const ws = new WebSocket(`${process.env.REACT_APP_WS_URL}/ws`);

重新构建前端镜像并部署即可。


方案三:Ingress统一路由

通过Kubernetes Ingress资源,将同一个域名下的不同路径映射到前端和后端服务,既解决域名解析问题,又避免跨域。

1. 启用minikube Ingress插件

minikube addons enable ingress

2. 创建Ingress配置文件(ingress.yaml)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - host: app.local
    http:
      paths:
      - path: /(.*)
        pathType: Prefix
        backend:
          service:
            name: client-service
            port:
              number: 3000
      - path: /api/(.*)
        pathType: Prefix
        backend:
          service:
            name: backend
            port:
              number: 8080
      - path: /ws
        pathType: Exact
        backend:
          service:
            name: backend
            port:
              number: 8080

3. 修改本地hosts文件

在/etc/hosts(Linux/macOS)或C:\Windows\System32\drivers\etc\hosts(Windows)中添加:

<minikube-ip> app.local

4. 前端代码改为相对路径

和方案一一致,将API请求改为/api/test,WebSocket改为/ws。

部署Ingress:

kubectl apply -f ingress.yaml

现在访问http://app.local即可打开前端,请求会自动通过Ingress路由到对应服务。


关于Nginx配置的疑问解答

你看到的Nginx配置中使用K8s服务名称,就是方案一中的思路:Nginx运行在集群内部Pod,能解析K8s DNS服务的域名,所以可以直接用http://backend:8080作为代理目标,而浏览器只需要访问前端的地址,无需知道后端的存在。

内容的提问来源于stack exchange,提问作者quantum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:22:04