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

Docker容器内NestJS gRPC客户端无法解析gRPC服务DNS问题

gRPC服务与Docker容器内客户端连接失败问题

我有一个gRPC服务和作为gRPC客户端的简易HTTP服务器,本地运行正常,但放入独立Docker容器后无法建立连接。gRPC服务运行并暴露5001端口。

NestJS gRPC客户端注册代码

ClientsModule.register([
  {
    name: "TOKEN_NAME",
    transport: Transport.GRPC,
    options: {
       ...GRPC_OPTIONS,
       url: process.env.GRPC_SERVICE_URL
    },
  },
]),

尝试过的Docker配置

方案1:使用容器名称作为URL

version: '3.9'
services:
  grpc-service:
    restart: always
    build: ./grpc-service
    container_name: grpc-service
  grpc-client:
    restart: always
    build: ./backend
    container_name: grpc-client
#    links:
#      - "grpc-service:service"
    depends_on:
      - grpc-service
    ports:
      - "3000:3000"
    environment:
      - GRPC_SERVICE_URL=http://grpc-service:5001
#     - GRPC_SERVICE_URL=http://service:5001

方案2:自定义网络并分配固定IP

version: '3.9'
networks:
  mynetwork:
    driver: bridge
    ipam:
      config:
        - subnet: 179.20.0.0/24

services:
  grpc-service:
    restart: always
    build: ./grpc-service
    container_name: grpc-service
    networks:
      mynetwork:
        ipv4_address: 179.20.0.5
  grpc-client:
    restart: always
    build: ./backend
    container_name: grpc-client
    networks:
      mynetwork:
        ipv4_address: 179.20.0.6

    depends_on:
      - grpc-service
    ports:
      - "3000:3000"
    environment:
      - GRPC_SERVICE_URL=179.20.0.5:5001

错误信息

使用http://grpc-service:5001时

grpc-client       | [Nest] 1  - 09/20/2022, 12:20:14 PM   ERROR [ExceptionsHandler] 14 UNAVAILABLE: Name resolution failed for target dns:http://grpc-service:5001
grpc-client       | Error: 14 UNAVAILABLE: Name resolution failed for target dns:http://grpc-service:5001
grpc-client       |     at Object.callErrorFromStatus (/node_modules/@grpc/grpc-js/build/src/call.js:31:19)
grpc-client       |     at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client.js:190:52)
grpc-client       |     at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:365:141)
grpc-client       |     at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:328:181)
grpc-client       |     at /node_modules/@grpc/grpc-js/build/src/call-stream.js:188:78
grpc-client       |     at processTicksAndRejections (node:internal/process/task_queues:78:11)
grpc-client       | for call at
grpc-client       |     at ServiceClientImpl.makeUnaryRequest (/node_modules/@grpc/grpc-js/build/src/client.js:160:30)
grpc-client       |     at ServiceClientImpl.<anonymous> (/node_modules/@grpc/grpc-js/build/src/make-client.js:105:19)
grpc-client       |     at Observable._subscribe (/node_modules/nestjs/microservices/client/client-grpc.js:177:35)
grpc-client       |     at Observable._trySubscribe (/node_modules/rxjs/dist/cjs/internal/Observable.js:41:25)
grpc-client       |     at /node_modules/rxjs/dist/cjs/internal/Observable.js:35:31
grpc-client       |     at Object.errorContext (/node_modules/rxjs/dist/cjs/internal/util/errorContext.js:22:9)
grpc-client       |     at Observable.subscribe (/node_modules/rxjs/dist/cjs/internal/Observable.js:26:24)
grpc-client       |     at /node_modules/rxjs/dist/cjs/internal/lastValueFrom.js:10:16
grpc-client       |     at new Promise (<anonymous>)
grpc-client       |     at lastValueFrom (/node_modules/rxjs/dist/cjs/internal/lastValueFrom.js:7:12)

使用179.20.0.5:5001时

grpc-client       | [Nest] 1  - 09/20/2022, 12:22:14 PM   ERROR [ExceptionsHandler] 14 UNAVAILABLE: No connection established
grpc-client       | Error: 14 UNAVAILABLE: No connection established
grpc-client       |     at Object.callErrorFromStatus (/node_modules/@grpc/grpc-js/build/src/call.js:31:19)
grpc-client       |     at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client.js:190:52)
grpc-client       |     at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:365:141)
grpc-client       |     at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:328:181)
grpc-client       |     at /node_modules/@grpc/grpc-js/build/src/call-stream.js:188:78
grpc-client       |     at processTicksAndRejections (node:internal/process/task_queues:78:11)
grpc-client       | for call at
grpc-client       |     at ServiceClientImpl.makeUnaryRequest (/node_modules/@grpc/grpc-js/build/src/client.js:160:30)
grpc-client       |     at ServiceClientImpl.<anonymous> (/node_modules/@grpc/grpc-js/build/src/make-client.js:105:19)
grpc-client       |     at Observable._subscribe (/node_modules/nestjs/microservices/client/client-grpc.js:177:35)
grpc-client       |     at Observable._trySubscribe (/node_modules/rxjs/dist/cjs/internal/Observable.js:41:25)
grpc-client       |     at /node_modules/rxjs/dist/cjs/internal/Observable.js:35:31
grpc-client       |     at Object.errorContext (/node_modules/rxjs/dist/cjs/internal/util/errorContext.js:22:9)
grpc-client       |     at Observable.subscribe (/node_modules/rxjs/dist/cjs/internal/Observable.js:26:24)
grpc-client       |     at /node_modules/rxjs/dist/cjs/internal/lastValueFrom.js:10:16
grpc-client       |     at new Promise (<anonymous>)
grpc-client       |     at lastValueFrom (/node_modules/rxjs/dist/cjs/internal/lastValueFrom.js:7:12)

补充测试

将gRPC服务在Docker中运行并映射端口5001:5001,本地HTTP客户端尝试连接localhost:5001的gRPC服务,出现如下错误:

[Nest] 93680  - 09/24/2022, 2:52:50 PM   ERROR [ExceptionsHandler] 14 UNAVAILABLE: Connection dropped
Error: 14 UNAVAILABLE: Connection dropped
         at Object.callErrorFromStatus (/Users/grpc-docker/backend/node_modules/@grpc/grpc-js/src/call.ts:81:17)
         at Object.onReceiveStatus (/Users/grpc-docker/backend/node_modules/@grpc/grpc-js/src/client.ts:352:36)
         at Object.onReceiveStatus (/Users/grpc-docker/backend/node_modules/@grpc/grpc-js/src/client-interceptors.ts:462:34)
         at Object.onReceiveStatus (/Users/grpc-docker/backend/node_modules/@grpc/grpc-js/src/client-interceptors.ts:424:48)
         at /Users/grpc-docker/backend/node_modules/@grpc/grpc-js/src/call-stream.ts:330:24
         at processTicksAndRejections (node:internal/process/task_queues:78:11)
  for call at
  at ServiceClientImpl.makeUnaryRequest (/Users/grpc-docker/backend/node_modules/@grpc/grpc-js/src/client.ts:324:26)
  at ServiceClientImpl.<anonymous> (/Users/grpc-docker/backend/node_modules/@grpc/grpc-js/src/make-client.ts:189:15)
  at Observable._subscribe (/Users/grpc-docker/backend/node_modules/nestjs/microservices/client/client-grpc.js:177:35)
  at Observable._trySubscribe (/Users/grpc-docker/backend/node_modules/rxjs/src/internal/Observable.ts:245:19)
  at /Users/grpc-docker/backend/node_modules/rxjs/src/internal/Observable.ts:235:18
  at Object.errorContext (/Users/grpc-docker/backend/node_modules/rxjs/src/internal/util/errorContext.ts:29:5)
  at Observable.subscribe (/Users/grpc-docker/backend/node_modules/rxjs/src/internal/Observable.ts:221:5)
  at /Users/grpc-docker/backend/node_modules/rxjs/src/internal/lastValueFrom.ts:59:12
  at new Promise (<anonymous>)
  at lastValueFrom (/Users/grpc-docker/backend/node_modules/rxjs/src/internal/lastValueFrom.ts:56:10)

解决方案

1. 修正gRPC客户端URL格式

gRPC的url配置不需要http://前缀,直接使用容器名:端口或IP:端口即可。修改环境变量:

# 方案1中修改为
GRPC_SERVICE_URL=grpc-service:5001
# 方案2中保持IP格式但确认无协议前缀
GRPC_SERVICE_URL=179.20.0.5:5001

2. 确保gRPC服务绑定正确地址

gRPC服务启动时,不要绑定localhost,而是绑定0.0.0.0,这样容器内的服务才能接受来自其他容器或外部的连接。例如在NestJS的gRPC服务配置中:

// gRPC服务启动代码
app.connectMicroservice({
  transport: Transport.GRPC,
  options: {
    url: '0.0.0.0:5001', // 关键:绑定0.0.0.0而非localhost
    ...其他配置
  },
});

3. 显式声明gRPC服务容器端口

在docker-compose中为gRPC服务添加expose配置,明确暴露容器内的5001端口(容器间通信无需端口映射,但显式声明更清晰):

grpc-service:
  restart: always
  build: ./grpc-service
  container_name: grpc-service
  expose:
    - "5001"

4. 处理容器启动顺序与服务就绪问题

depends_on仅保证容器启动顺序,不保证服务已就绪。添加健康检查,确保gRPC服务启动后客户端再尝试连接:

grpc-service:
  restart: always
  build: ./grpc-service
  container_name: grpc-service
  expose:
    - "5001"
  healthcheck:
    test: ["CMD", "grpc-health-probe", "-addr=:5001"]
    interval: 5s
    timeout: 5s
    retries: 5

grpc-client:
  restart: always
  build: ./backend
  container_name: grpc-client
  depends_on:
    grpc-service:
      condition: service_healthy # 等待服务健康
  ports:
    - "3000:3000"
  environment:
    - GRPC_SERVICE_URL=grpc-service:5001

注意:需要在gRPC服务容器中安装grpc-health-probe工具,可在Dockerfile中添加:

RUN GRPC_HEALTH_PROBE_VERSION=v0.4.19 && \
    wget -qO/bin/grpc-health-probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc-health-probe-linux-amd64 && \
    chmod +x /bin/grpc-health-probe

5. 验证容器间网络连通性

进入客户端容器,尝试ping gRPC服务容器名或IP,确认网络可达:

docker exec -it grpc-client ping grpc-service
# 或测试端口连通性
docker exec -it grpc-client nc -zv grpc-service 5001

如果无法连通,检查自定义网络配置是否正确,或使用Docker默认网络(同一docker-compose下的服务默认加入同一网络,容器名可直接解析)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 20:31:35