【问题标题】:How to run .net core grpc in docker container?如何在 docker 容器中运行 .net core grpc?
【发布时间】:2021-03-31 22:44:23
【问题描述】:

您好,我使用 .Net 5 创建了 GRPC 项目。下面是我的 Docker 文件。

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

FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY ./*.sln ./
COPY */*.csproj ./
RUN for file in $(ls *.csproj); do mkdir -p ${file%.*} && mv $file ${file%.*}; done
RUN dotnet restore
COPY . .
WORKDIR "/src/Geography"
RUN dotnet build "Geography.csproj" -c Release -o /app/build

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

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

我尝试使用 Docker 在 Visual Studio 中运行解决方案,我看到容器已启动并正在运行。我看到下面暴露的端口。

 0.0.0.0:32775->80/tcp, 0.0.0.0:32774->443/tcp

我创建了客户端应用程序并尝试点击 grpc 端点,如下所示。

using var channel = GrpcChannel.ForAddress("http://localhost:32774");
var client = new Geographys.GeographysClient(channel);

这里出现错误

Status(StatusCode="Internal", Detail="启动 gRPC 调用时出错。 HttpRequestException:发送请求时发生错误。 IOException:无法从传输连接读取数据:一个 现有连接被远程主机强行关闭.. SocketException:一个现有的连接被强制关闭 远程主机。", DebugException="System.Net.Http.HttpRequestException: 发送请求时出错。 ---> System.IO.IOException:无法从传输中读取数据 连接:已存在的连接被远程强行关闭 主持人.. --->

有人可以帮助我了解此问题的根本原因吗?任何帮助将不胜感激。谢谢

【问题讨论】:

    标签: docker asp.net-core grpc


    【解决方案1】:

    您确定您的 .NET 代码在容器端口 80 上公开了一个非 TLS HTTP 端点,在 443 上公开了一个 TLS HTTP 端点吗?

    我怀疑不是,这可以解释为什么当端口绑定到主机时您无法通过端口访问服务(分别在 32775 和 32774 上)。

    注意您的客户端代码尝试访问可能映射到容器的 TLS 端点 (:443) 的 http://localhost:32774,因此您需要使用 https:// 并配置证书。 p>

    如果您在主机上运行 Linux,您可以尝试 telnet 到这些端口以查看是否收到响应:

    telnet localhost 32775
    telnet localhost 32774
    

    如果您有 gRPCurl(并且任何 gRPC 开发人员都应该使用 IMO),您可以尝试列出方法:

    grpcurl \
    -plaintext \
    -proto path/to/your.proto \
    localhost:32775 \
    list
    
    grpcurl \
    -plaintext \
    -proto path/to/your.proto \
    localhost:32774 \
    list
    

    注意我认为对于 TLS 和非 TLS 而言,grpcurl 都是正确的,但无法测试

    【讨论】:

      【解决方案2】:

      添加以下代码

      "Kestrel": {
          "EndpointDefaults": {
            "Protocols": "Http2"
          }
        }
      

      在 gRPC 服务器端的 appsettings.json 文件中并在 gRPC 客户端调用“http”端口而不是“https”应该可以解决问题。在您的示例中,这将是:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-30
        相关资源
        最近更新 更多