簡體   English   中英

無法連接到托管在 Docker 中的網絡核心 gRPC 服務

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

我對 gRPC 服務比較陌生。

我正在嘗試將Net core gRPC 服務部署到 Linux docker 容器中,並從VS 控制台應用程序本地訪問它。

我想讓事情盡可能簡單,因此 docker 文件與 VS 中的 Net core gRPC docker 文件相同,其中 docker compose 指向它。 直接在 VS 中運行 gRPC 服務時,控制台應用程序可以訪問該服務,只是不能在 docker 容器中訪問。

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 應用設置

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

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 編寫文件

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:

控制台應用程序,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

運行 docker-compose 文件后,控制台應用程序無法連接到 gRPC。

使用 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

使用 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

此時,我不知道是 docker 網絡還是 gRPC 配置問題。

我需要幫助來指引我正確的方向。

謝謝你

我今天遇到了熟悉的問題。

你在 dockerfile 中設置了 EXPOSE 80,所以你需要讓 grpc 監聽綁定到它的端口。

所以在我的例子中,grpc 監聽 8099,並將其暴露給主機端口:32812,然后客戶端創建通道給它。 它工作。

在 dockerfile 中:

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

在服務器監聽端口:

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

在客戶端創建通道:

GrpcClientFactory.AllowUnencryptedHttp2 = true;

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

綁定端口

希望對你有幫助,祝你好運~

我在 kubernetes 上運行圖像時遇到了一些問題。 修理:

1 - 要公開端口,我必須更改圖像和應用程序並公開環境變量(但也只有 EXPOSE 有效)。

在此處輸入圖像描述

強制端口在此處輸入圖像描述

2 - 我的問題是 TLS 協議上的證書(我沒有)。 我已經在我的 github 上發布了我如何在沒有證書的情況下修復它。 但是要注意環境。 此示例只能應用於與 ClusterIp 的內部通信。 公開展示是一種不安全的實施方式。

鏈接修復(示例) 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