如何修复“14不可用:目标DNS的名称解析失败:http://sample-service:40000”GRPC + Docker错误

kt06eoxx  于 2023-03-17  发布在  Docker
关注(0)|答案(2)|浏览(177)

我在Docker容器中部署了一个nest. jsgRPC服务器和一个客户机,其中包含以下Docker命令:
客户端(api网关):

docker run -dit -p 3000:3000 --hostname ${{ env.IMAGE_NAME }} --name ${{ env.IMAGE_NAME }} --network web_server ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{env.TAG}}

客户端的env

IMAGE_NAME=api-gateway

服务器(问题服务):

docker run -dit -p 40000:40000 --hostname ${{ env.IMAGE_NAME }} --name ${{ env.IMAGE_NAME }} --network web_server ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{env.TAG}}

服务器的环境

IMAGE_NAME=question-service

服务器(question-service)的Main.ts是这样的,

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Transport } from '@nestjs/microservices';
import { join } from 'path';

const microserviceOptions = {
  transport: Transport.GRPC,
  options: {
    package: 'questionPackage',
    protoPath: join(__dirname, '../src/question/question.proto'),
    url: '0.0.0.0:40000',
  },
};

async function bootstrap() {
  const app = await NestFactory.createMicroservice(
    AppModule,
    microserviceOptions,
  );
  app.listen();
}
bootstrap();

客户端集成是这样的grpc.option.ts:

import { ClientOptions, Transport } from '@nestjs/microservices';
import { join } from 'path';

export const microserviceOptions: ClientOptions = {
  transport: Transport.GRPC,
  options: {
    package: 'questionPackage',
    protoPath: join(__dirname, '../question/question.proto'),
    url: 'question-service:40000',
  },
};

question.service.ts:

import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { Client, ClientGrpc } from '@nestjs/microservices';
import { CreateQuestionInput } from './dto/create-question.input';
import { QuestionGrpcService } from './grpc.interface';
import { microserviceOptions } from './grpc.option';
import { Question } from './entities/question.entity';
import { firstValueFrom } from 'rxjs';

@Injectable()
export class QuestionService implements OnModuleInit {
  private logger = new Logger('QuestionService');
  @Client(microserviceOptions)
  private client: ClientGrpc;

  private questionGrpcService: QuestionGrpcService;

  onModuleInit() {
    this.questionGrpcService =
      this.client.getService<QuestionGrpcService>('QuestionService');
  }

  createQuestion(createQuestionInput: CreateQuestionInput) {
    return this.questionGrpcService.createQuestion(createQuestionInput);
  }

  async getQuestions(): Promise<Question[]> {
    let questions = [];
    const res = await firstValueFrom(this.questionGrpcService.getQuestions({}));
    questions = res.questionsResposes;
    return questions;
  }
}

但是当我调用api-gateway的graphql端点来获取所有问题时,它返回以下错误:

{
  "errors": [
    {
      "message": "14 UNAVAILABLE: Name resolution failed for target dns:http://question-service:40000",
      "locations": [
        {
          "line": 16,
          "column": 3
        }
      ],
      "path": [
        "question"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "code": 14,
          "details": "Name resolution failed for target dns:http://question-service:40000",
          "metadata": {},
          "stacktrace": [
            "Error: 14 UNAVAILABLE: Name resolution failed for target dns:http://question-service:40000",
            "    at Object.callErrorFromStatus (/node_modules/@grpc/grpc-js/build/src/call.js:31:19)",
            "    at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client.js:190:52)",
            "    at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:365:141)",
            "    at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:328:181)",
            "    at /node_modules/@grpc/grpc-js/build/src/call-stream.js:188:78",
            "    at processTicksAndRejections (internal/process/task_queues.js:79:11)",
            "for call at",
            "    at ServiceClientImpl.makeUnaryRequest (/node_modules/@grpc/grpc-js/build/src/client.js:160:30)",
            "    at ServiceClientImpl.getQuestions (/node_modules/@grpc/grpc-js/build/src/make-client.js:105:19)",
            "    at Observable._subscribe (/node_modules/@nestjs/microservices/client/client-grpc.js:177:39)",
            "    at Observable._trySubscribe (/node_modules/rxjs/dist/cjs/internal/Observable.js:41:25)",
            "    at /node_modules/rxjs/dist/cjs/internal/Observable.js:35:31",
            "    at Object.errorContext (/node_modules/rxjs/dist/cjs/internal/util/errorContext.js:22:9)",
            "    at Observable.subscribe (/node_modules/rxjs/dist/cjs/internal/Observable.js:26:24)",
            "    at /node_modules/rxjs/dist/cjs/internal/firstValueFrom.js:24:16",
            "    at new Promise (<anonymous>)",
            "    at firstValueFrom (/node_modules/rxjs/dist/cjs/internal/firstValueFrom.js:8:12)"
          ]
        }
      }
    }
  ],
  "data": null
}

在命令返回之下,

sudo docker inspect web_server 

[
    {
        "Name": "web_server",
        "Id": "23b4a40928a88861f7a063db4dac5c491db5384181d28ee5563db52f96c22e55",
        "Created": "2022-09-06T17:55:54.611611429Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "181868f91a188056e5f21de4bb6ca16b92f36befcd832386206256701b7be16a": {
                "Name": "question-service",
                "EndpointID": "01a4c375b95be1eb9be58993abcb8bf15fe2a8d91ac2635c4a3746036fc51747",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "828c06298e42184665507f3c6bd73a54feb36e3da3214360a015ba67104f1fdd": {
                "Name": "api-gateway",
                "EndpointID": "2ca0ba9b3f6664095e8146b5d6243362fc0a5188a73c80b7afd47207a5c62e1e",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
icnyk63a

icnyk63a1#

我可以通过更改客户端和服务器配置中的URL来解决这个问题,如下所示。

export const microserviceOptions: ClientOptions = {
  transport: Transport.GRPC,
  options: {
    package: 'questionPackage',
    protoPath: join(__dirname, '../question/question.proto'),
    url: 'dns:///question-service:40000',
  },
};

有关详细信息,请参考this anwer。您也可以参考此blog post

zf9nrax1

zf9nrax12#

我在运行一个入口点为dumb-init的容器时得到了这个错误。我还尝试了tini,也得到了同样的错误。
这导致了错误
ENTRYPOINT ["dumb-init", "node", "./dist/index.js"]
这也
ENTRYPOINT ["/sbin/tini","--", "node", "./dist/index.js"]
但这个管用
ENTRYPOINT ["node", "./dist/index.js"]

相关问题