简体   繁体   English

无法连接到托管在 Docker 中的网络核心 gRPC 服务

[英]Unable to connect to net core gRPC service hosted in Docker

I am relatively new to gRPC service.我对 gRPC 服务比较陌生。

I am trying to deploy a Net core gRPC service into Linux docker container and accessing it from locally from VS console app .我正在尝试将Net core gRPC 服务部署到 Linux docker 容器中,并从VS 控制台应用程序本地访问它。

I want to keep things as simple as possible thus the docker file is identical to a Net core gRPC docker file in VS where docker compose is pointing to it.我想让事情尽可能简单,因此 docker 文件与 VS 中的 Net core gRPC docker 文件相同,其中 docker compose 指向它。 When running the gRPC service in VS directly, the console app can access the service, just not in docker container.直接在 VS 中运行 gRPC 服务时,控制台应用程序可以访问该服务,只是不能在 docker 容器中访问。

gRPC launch settings gRPC 启动设置

{
  "profiles": {
    "TrafficGrpc": {
      "commandName": "Project",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "https://localhost:5001"
    },
    "Docker": {
      "commandName": "Docker",
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
      "publishAllPorts": true,
      "useSSL": true
    }
  }
}

gRPC app settings gRPC 应用设置

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }
  }
}

Docker file Docker文件

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["gRPC/TrafficGrpc/TrafficGrpc.csproj", "TrafficGrpc/"]
RUN dotnet restore "TrafficGrpc/TrafficGrpc.csproj"
COPY . .
WORKDIR "/src/gRPC/TrafficGrpc"
RUN dotnet build "TrafficGrpc.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "TrafficGrpc.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "TrafficGrpc.dll"]

Docker compose file Docker 编写文件

version: "3.7"
services:

  # Traffic service
  traffic:
    container_name: traffic
    build:
      context: .
      dockerfile: Dockerfile-traffic
    networks:
      grpc_network:
    environment:
      - SERVICE_NAME=1
    expose:
      - "80"
      - "443"
    ports:
      - "0.0.0.0:32773:80"
      - "0.0.0.0:32774:443"
      
networks:
  grpc_network:

Console app, VS控制台应用程序,VS

string trafficUrl = "http://localhost:32773";
//string trafficUrl = "https://localhost:32774";

Traffic traffic = new Traffic
{
    Date = DateTime.Now.AddDays(1),
    Area = Areas[rng.Next(Areas.Length)],
    Condition = Conditions[rng.Next(Conditions.Length)]
};

GrpcChannel tChannel = GrpcChannel.ForAddress(trafficUrl);
TrafficCheckerClient tClient = new TrafficCheckerClient(tChannel);
TrafficConditionResponse tReply = await tClient.CheckTrafficConditionAsync(
    new TrafficConditionRequest { Condition = traffic.Condition }); // <-- ERROR here

After running docker-compose file, the console app is just not able to connect to gRPC.运行 docker-compose 文件后,控制台应用程序无法连接到 gRPC。

Using http, I get this error:使用 http,我收到此错误:

Grpc.Core.RpcException
  HResult=0x80131500
  Message=Status(StatusCode=Internal, Detail="Error starting gRPC call. HttpRequestException: An error occurred while sending the request. IOException: The response ended prematurely.")
  Source=System.Private.CoreLib
  StackTrace:
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at ConsoleTestgRPC.Program.<Main>d__5.MoveNext() in D:\Workspace-GW-EV\CL\ConsoleTestgRPC\Program.cs:line 61

Using https, I get this error:使用 https,我收到此错误:

Grpc.Core.RpcException
  HResult=0x80131500
  Message=Status(StatusCode=Internal, Detail="Error starting gRPC call. HttpRequestException: The SSL connection could not be established, see inner exception. IOException: Authentication failed because the remote party has closed the transport stream.")
  Source=System.Private.CoreLib
  StackTrace:
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at ConsoleTestgRPC.Program.<Main>d__5.MoveNext() in D:\Workspace-GW-EV\CL\ConsoleTestgRPC\Program.cs:line 61

At this point, I do not know whether it is a docker network or a gRPC config issue.此时,我不知道是 docker 网络还是 gRPC 配置问题。

I need help to point me in the right direction.我需要帮助来指引我正确的方向。

THANK YOU谢谢你

I meet familiar problem today.我今天遇到了熟悉的问题。

You set EXPOSE 80 in the dockerfile, so you need to make grpc to listen the port which bind to it.你在 dockerfile 中设置了 EXPOSE 80,所以你需要让 grpc 监听绑定到它的端口。

So in my case, the grpc listen to the 8099, and expose it to host port: 32812, then client creat channel to it.所以在我的例子中,grpc 监听 8099,并将其暴露给主机端口:32812,然后客户端创建通道给它。 And it work.它工作。

In dockerfile:在 dockerfile 中:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 8099
EXPOSE 443

In server to listen port:在服务器监听端口:

public static IWebHostBuilder CreateHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureKestrel(options =>
                {
                    options.ListenAnyIP(
                        8099,
                        listenOptions => { listenOptions.Protocols = HttpProtocols.Http2; }
                    );
                })
                .UseStartup<Startup>();

In client to create channel:在客户端创建通道:

GrpcClientFactory.AllowUnencryptedHttp2 = true;

using var http = GrpcChannel.ForAddress("http://localhost:32812");

Binding port绑定端口

May this will help you, good luck~希望对你有帮助,祝你好运~

I Had some problems to run the image on kubernetes.我在 kubernetes 上运行图像时遇到了一些问题。 To Fix:修理:

1 - To expose port i had to change on image and appliation and expose the Enviroment var(but only EXPOSE works too). 1 - 要公开端口,我必须更改图像和应用程序并公开环境变量(但也只有 EXPOSE 有效)。

在此处输入图像描述

Force the port强制端口在此处输入图像描述

2 - My issue was the certificate on TLS protocol (i did't had). 2 - 我的问题是 TLS 协议上的证书(我没有)。 I has publicated on my github how i fixed it without certificate.我已经在我的 github 上发布了我如何在没有证书的情况下修复它。 But take atention on the enviroment.但是要注意环境。 This exemple can be applied only on internal comunication with ClusterIp.此示例只能应用于与 ClusterIp 的内部通信。 It's a insecure implementation mode to public exposition.公开展示是一种不安全的实施方式。

link fix(example) https://github.com/davidsonsilvadev/grpc-core3.1-docker-kubernetes-without-certificate链接修复(示例) https://github.com/davidsonsilvadev/grpc-core3.1-docker-kubernetes-without-certificate

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM