GKE集群前端无法与后端通信,寻求动态通信解决方案
我在GKE集群部署了React前端和Node.js后端服务,Docker镜像已推送到Google Artifact Registry。前端通过Ingress外部IP可正常访问,但前端无法与后端通信——进入Kubernetes Pod执行curl http://my-node-server-service.default.svc.cluster.local/api/hello可正常请求后端,但外部访问前端时出现域名解析失败错误。
现有配置文件
Node.js后端配置(Node Service.yaml)
apiVersion: apps/v1 kind: Deployment metadata: name: my-node-server spec: replicas: 1 selector: matchLabels: app: my-node-server template: metadata: labels: app: my-node-server spec: containers: - name: my-node-server image: us-central1-docker.pkg.dev/ycxz-426410/ycxz/backend:latest ports: - containerPort: 5000 --- apiVersion: v1 kind: Service metadata: name: my-node-server-service spec: selector: app: my-node-server ports: - protocol: TCP port: 80 targetPort: 5000 type: ClusterIP
React前端配置(Frontend.yaml)
apiVersion: apps/v1 kind: Deployment metadata: name: my-react-server spec: replicas: 1 selector: matchLabels: app: my-react-server template: metadata: labels: app: my-react-server spec: containers: - name: my-react-server image: us-central1-docker.pkg.dev/ycxz-426410/ycxz/frontend:latest ports: - containerPort: 3000 env: - name: REACT_APP_URL value: "http://my-node-server-service.default.svc.cluster.local" --- apiVersion: v1 kind: Service metadata: name: my-react-server-service spec: selector: app: my-react-server ports: - protocol: TCP port: 80 targetPort: 3000 type: ClusterIP
Ingress配置(Ingress.yaml)
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress spec: rules: - http: paths: - path: / pathType: Prefix backend: service: name: my-react-server-service port: number: 80 ingressClassName: nginx
报错信息
Backend URL: http://my-node-server-service.default.svc.cluster.local App.js:23 Backend URL: http://my-node-server-service.default.svc.cluster.local App.js:15 Fetching message... App.js:15 Fetching message... App.js:20 Error fetching message: AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …} fetchMessage @ App.js:20 await in fetchMessage (async) (anonymous) @ App.js:10 commitHookEffectListMount @ react-dom.development.js:23189 commitPassiveMountOnFiber @ react-dom.development.js:24965 commitPassiveMountEffects_complete @ react-dom.development.js:24930 commitPassiveMountEffects_begin @ react-dom.development.js:24917 commitPassiveMountEffects @ react-dom.development.js:24905 flushPassiveEffectsImpl @ react-dom.development.js:27078 flushPassiveEffects @ react-dom.development.js:27023 (anonymous) @ react-dom.development.js:26808 workLoop @ scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 Show 11 more frames Show lessUnderstand this error App.js:16 GET http://my-node-server-service.default.svc.cluster.local/api/hello net::ERR_NAME_NOT_RESOLVED
问题原因
前端代码在用户浏览器中运行,浏览器处于集群外部网络,无法解析Kubernetes内部的ClusterIP服务域名(my-node-server-service.default.svc.cluster.local是集群内部DNS系统才能识别的地址),因此出现域名解析失败。
解决方案
方案1:通过Ingress路径转发(生产环境推荐)
修改Ingress配置,增加后端服务的路径规则,让前端通过同域名的子路径访问后端,避免跨集群域名解析问题:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress spec: rules: - http: paths: - path: / pathType: Prefix backend: service: name: my-react-server-service port: number: 80 # 新增后端服务路径转发 - path: /api pathType: Prefix backend: service: name: my-node-server-service port: number: 80 ingressClassName: nginx
然后修改前端的环境变量,将REACT_APP_URL设置为相对路径:
# 修改Frontend.yaml中的env部分 env: - name: REACT_APP_URL value: "/api"
前端请求时直接使用相对路径/api/hello,Ingress会自动转发到后端服务。
方案2:将后端服务改为NodePort或LoadBalancer(测试环境可用,不推荐生产)
将后端服务的type改为NodePort或LoadBalancer,获取外部可访问的IP/端口,然后修改前端的REACT_APP_URL为该外部地址:
# 修改Node Service.yaml中的Service部分 apiVersion: v1 kind: Service metadata: name: my-node-server-service spec: selector: app: my-node-server ports: - protocol: TCP port: 80 targetPort: 5000 type: LoadBalancer # 或NodePort
这种方法会直接暴露后端到公网,存在安全风险,生产环境不建议使用。
方案3:前端构建时注入外部可访问的后端地址
如果后端已有公网域名或IP,在构建前端镜像时将REACT_APP_URL设置为该外部地址,确保浏览器能正常解析。但这种方式灵活性差,后端地址变更时需要重新构建镜像。
内容的提问来源于stack exchange,提问作者Amllan Bhukta

