如何解决elastic-apm-node的APM Server传输错误(ENOTFOUND)
Docker环境下Node.js微服务集成Elastic APM出现DNS解析错误
问题详情
- 部署架构:APM Server(
apm-server)和Node.js微服务(test-service)均运行在Docker容器中,已通过elastic-apm-node配置APM Agent - 异常现象:
apm.start()初始化成功后,很快抛出getaddrinfo ENOTFOUND错误,无法连接到APM Server - 错误日志:
2024-07-18 15:13:20 {"log.level":"error","@timestamp":"2024-07-18T19:13:20.963Z","log.logger":"elastic-apm-node","ecs.version":"8.10.0","message":"APM Server transport error (ENOTFOUND): getaddrinfo ENOTFOUND apm-server"}
- Agent代码:
const apm = require('elastic-apm-node').start({ serviceName: 'test-service', serverUrl: "http://apm-server:8200", secretToken: process.env.ELASTIC_APM_SECRET_TOKEN }); const app = require('express')() app.get('/', function (req, res) { res.send('Hello World!') }) app.listen(5001)
- docker-compose.yml关键片段:
apm-server: image: docker.elastic.co/apm/apm-server:8.14.2 container_name: apm-server restart: always command: > apm-server -e -E apm-server.rum.enabled=true -E setup.kibana.host=kibana:5601 -E setup.template.settings.index.number_of_replicas=0 -E apm-server.kibana.enabled=true -E apm-server.kibana.host=kibana:5601 -E apm-server.kibana.username:kibana_system -E apm-server.kibana.password:xxxxxx -E apm-server.kibana.protocol=http -E apm-server.secret_token= -E strict.perms=false -E apm-server.auth.anonymous.enabled=true ports: - "8200:8200" volumes: - ./apm-server.yml:/usr/share/apm-server/apm-server.yml:ro networks: - elastic depends_on: - elasticsearch test-service: build: context: ../test-service container_name: test-service environment: - RABBITMQ_URL=amqp://rabbitmq - ELASTICSEARCH_NODE=http://elasticsearch:9200 - ELASTIC_APM_SERVER_URL=http://apm-server:8200 - ELASTIC_APM_SECRET_TOKEN=secrettoken - PORT=5001 ports: - "5001:5001" depends_on: - elasticsearch - rabbitmq - apm-server
- 已尝试操作:切换ESM/CommonJS方式加载Agent,问题未解决
解决方案
错误原因
test-service容器和apm-server容器不在同一个Docker网络中。Docker自定义网络(如配置中的elastic)支持容器名自动DNS解析,但test-service未加入该网络,导致无法通过apm-server这个容器名找到对应的服务。
修复步骤
- 修改docker-compose.yml,在
test-service配置块中添加networks配置,加入elastic网络:
test-service: build: context: ../test-service container_name: test-service environment: - RABBITMQ_URL=amqp://rabbitmq - ELASTICSEARCH_NODE=http://elasticsearch:9200 - ELASTIC_APM_SERVER_URL=http://apm-server:8200 - ELASTIC_APM_SECRET_TOKEN=secrettoken - PORT=5001 ports: - "5001:5001" depends_on: - elasticsearch - rabbitmq - apm-server # 添加网络配置 networks: - elastic
- 重新构建并启动
test-service容器:
docker compose up -d --build test-service
补充说明
depends_on仅控制容器的启动顺序,不保证网络连通性,即使test-service在apm-server之后启动,不在同一网络依然无法通信- 默认的Docker bridge网络不支持容器名的自动DNS解析,必须使用自定义网络才能实现容器间通过名称访问
内容的提问来源于stack exchange,提问作者matt606
相关产品推荐
相关产品推荐

