Kubernetes同节点Pod连接失败:getaddrinfo ENOTFOUND问题排查
问题描述
我有一个基于Node.js的微服务程序:posts服务负责创建帖子,并通过axios的POST请求将对应事件发送至event bus;event bus启动时会通过axios的GET请求与posts建立连接。目前event bus到posts的GET请求可成功执行,但posts到event bus的POST请求失败,报错getaddrinfo ENOTFOUND event-bus-srv。posts与event bus均运行在Kubernetes管理的同一节点Pod中,仅posts可通过URL http://localhost:31218/被用户访问。使用Postman向http://localhost:31218/posts发送请求时,可成功收到201响应,但事件从未转发至event bus。请问:导致getaddrinfo ENOTFOUND event-bus-srv的原因是什么?如何解决?
相关代码
1. posts index.js
const express = require('express'); const { randomBytes } = require('crypto'); const bodyParser = require('body-parser'); const cors = require('cors'); const axios = require('axios'); const app = express(); app.use(cors()); app.use(bodyParser.json()); const posts = {}; app.get('/posts', (req, res) => { res.send(posts); }); app.post('/posts', async(req, res) => { const id = randomBytes(4).toString('hex'); const { title } = req.body; posts[id] = { id, title }; await axios.post('http://event-bus-srv:4005/events', { type: 'PostCreated', data: { id, title } }).catch((err) => { console.log("сбой такой: " + err.message); }); res.status(201).send(posts[id]); }); app.post('/events', (req, res) => { res.status(200); }) app.listen(4000, () => { console.log('Listening to port ' + 4000); });
2. event bus index.js
const express = require('express'); const bodyParser = require('body-parser'); const axios = require('axios'); const app = express(); app.use(bodyParser.json()); const events = []; app.get('/events', (req, res) => { res.send(events); }); app.post('/events', (req, res) => { const event = req.body; events.push(event); axios.post('http://posts-clusterip-svr:4000/events', event).catch((err) => { console.log(err.message); }); res.send({status: 'OK'}); }); app.listen(4005, async() => { console.log("listening to " + 4005); const res = await axios.get('http://posts-clusterip-svr:4000/posts').catch((err) => { console.log("сбой такой: " + err.message); }); });
3. EVENT BUS KUBERNETES DEPLOYMENT/SERVICE FILE
apiVersion: apps/v1 kind: Deployment metadata: name: event-bus-depl spec: replicas: 1 selector: matchLabels: app: event-bus template: metadata: labels: app: event-bus spec: containers: - name: event-bus image: wliamwhite/event-bus:latest --- apiVersion: v1 kind: Service metadata: name: event-bus-svr spec: selector: app: event-bus type: ClusterIP ports: - name: event-bus protocol: TCP port: 4005 targetPort: 4005
4. POSTS KUBERNETES DEPLOYMENT/SERVICE FILE
apiVersion: apps/v1 kind: Deployment metadata: name: posts-depl spec: replicas: 1 selector: matchLabels: app: posts template: metadata: labels: app: posts spec: containers: - name: posts image: wliamwhite/posts:latest --- apiVersion: v1 kind: Service metadata: name: posts-clusterip-svr spec: type: ClusterIP selector: app: posts ports: - name: posts protocol: TCP port: 4000 targetPort: 4000
5. POSTS KUBERNETES NODEPORT FILE
apiVersion: v1 kind: Service metadata: name: posts-svr spec: type: NodePort selector: app: posts ports: - name: posts protocol: TCP port: 4000 targetPort: 4000
问题分析与解决
错误原因
报错getaddrinfo ENOTFOUND event-bus-srv的核心原因是Kubernetes Service名称拼写不匹配:
- 在
posts服务的代码中,调用event bus时使用的地址是http://event-bus-srv:4005/events,其中Service名称为event-bus-srv - 但实际Kubernetes中为event bus创建的ClusterIP Service名称是
event-bus-svr(末尾多了一个字母r)
Kubernetes内部通过DNS服务解析Service名称,拼写错误会导致posts Pod无法找到对应的Service地址,从而触发DNS解析失败。
解决步骤
- 修正
posts服务中的请求地址
修改posts/index.js中的axios POST请求地址,将event-bus-srv改为event-bus-svr,修正后的代码片段如下:await axios.post('http://event-bus-svr:4005/events', { type: 'PostCreated', data: { id, title } }).catch((err) => { console.log("错误信息: " + err.message); }); - 重新构建并部署
posts服务- 重新构建Docker镜像:
docker build -t wliamwhite/posts:latest .(根据你的项目路径调整命令) - 将新镜像推送到你的容器仓库
- 重新部署Kubernetes资源:
kubectl apply -f <posts-deployment-file-path>(替换为你的posts部署文件路径)
- 重新构建Docker镜像:
- 验证修复效果
使用Postman再次发送请求到http://localhost:31218/posts,然后查看event bus的Pod日志:
确认日志中已接收到kubectl logs <event-bus-pod-name>PostCreated事件,且posts服务不再出现DNS解析错误。
额外检查项
- 确认两个服务都部署在同一Kubernetes命名空间下(默认命名空间无需额外配置;若使用自定义命名空间,需在地址中添加命名空间后缀,格式为
service-name.namespace.svc.cluster.local) - 检查
event-bus-svrService状态是否正常:
确认其状态为kubectl get service event-bus-svrRunning且已分配ClusterIP。
内容的提问来源于stack exchange,提问作者Liam White
相关产品推荐
相关产品推荐

