同一节点Kubernetes Pod间通信问题:前端无法请求后端服务
我尝试从前端(Angular)向后端(Spring Boot)发起HTTP请求,实现Kubernetes同一节点内Pod间通信,已创建如下Deployment和Service:
后端(Spring Boot)YAML配置
apiVersion: apps/v1 kind: Deployment metadata: name: tool-be spec: replicas: 1 # imposta il numero desiderato di repliche selector: matchLabels: app: tool-be template: metadata: labels: app: tool-be tier: tool-be spec: containers: - name: tool-be image: localhost:5000/tool-be:latest imagePullPolicy: Always ports: - containerPort: 8080 env: - name: db-pass value: "#####" - name: db-username value: "#####" - name: spring.profiles.active value: "kube" --- apiVersion: v1 kind: Service metadata: name: tool-be-service spec: selector: app: tool-be ports: - protocol: TCP port: 8080 targetPort: 8080
前端(Angular)YAML配置
apiVersion: apps/v1 kind: Deployment metadata: name: tool-fe spec: replicas: 1 # imposta il numero desiderato di repliche selector: matchLabels: app: tool-fe template: metadata: labels: app: tool-fe tier: tool-fe spec: containers: - name: tool-fe image: localhost:5000/tool-fe:latest ports: - containerPort: 4200 --- apiVersion: v1 kind: Service metadata: name: tool-fe-service spec: selector: app: tool-fe ports: - protocol: TCP port: 4200 targetPort: 4200 type: LoadBalancer
Pod已正常运行,但前端发起请求时用服务名http://tool-be-service:8080/....出现net::ERR_NAME_NOT_RESOLVED地址解析错误。不过进入前端Pod终端执行wget http://tool-be-service:8080/...能成功访问后端(返回未授权,但日志有请求记录)。
请问问题出在哪里?为什么前端无法向后端发起HTTP请求?
核心原因
你的前端请求不是从前端Pod内部发起的,而是从用户本地浏览器发起的!
浏览器运行在你的本地机器上,它的DNS解析能力无法识别Kubernetes集群内部的Service域名(tool-be-service)——这个域名只有Kubernetes集群内部的DNS服务(比如CoreDNS)才能解析。而你用kubectl exec进入前端Pod执行请求时,是在Pod内部发起的,所以能正常解析Service地址。
解决方法
方案1:后端Service暴露为NodePort/LoadBalancer
将后端的tool-be-service类型改为NodePort或LoadBalancer,获取集群外部可访问的地址,前端请求使用这个外部地址。
- 修改后端Service的YAML:
apiVersion: v1 kind: Service metadata: name: tool-be-service spec: selector: app: tool-be ports: - protocol: TCP port: 8080 targetPort: 8080 type: NodePort # 或 LoadBalancer - 执行
kubectl get service tool-be-service查看外部访问端口,前端请求地址改为http://<集群节点IP>:<NodePort>/...(或LoadBalancer分配的外部IP)。
方案2:使用Angular代理配置
在Angular项目中配置代理,将前端的API请求转发到后端Service,适合开发环境使用:
- 在Angular项目根目录创建
proxy.conf.json:{ "/api/*": { "target": "http://tool-be-service:8080", "secure": false, "changeOrigin": true } } - 修改
angular.json中的启动配置,添加代理:"serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "your-app:build", "proxyConfig": "proxy.conf.json" } } - 前端请求时使用相对路径(比如
/api/xxx),代理会自动转发到后端Service。
方案3:使用Ingress统一路由(生产环境推荐)
部署Ingress Controller,创建Ingress资源,将前端和后端的请求通过同一个域名的不同路径区分,比如http://your-domain/指向前端,http://your-domain/api/指向后端。这种方式能统一管理集群内服务的外部访问,更适合生产环境。
内容的提问来源于stack exchange,提问作者Alex

