c# - 调用在docker中运行的不安全的GRPC服务

标签 c# .net docker .net-core docker-compose

我尝试从控制台应用程序调用不安全的 (http) GRPC 服务(GRPC 服务和控制台客户端都在 docker 中运行),但出现以下异常:

Grpc.Core.RpcException: 'Status(StatusCode="Unavailable", Detail="Error connecting to subchannel.", DebugException="System.Net.Sockets.SocketException (111): Connection refused
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
   at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|281_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken)
   at Grpc.Net.Client.Balancer.Internal.SocketConnectivitySubchannelTransport.TryConnectAsync(ConnectContext context)")'

尽管 StatusCode="Unavailable" 我可以确认该服务正在响应请求,因为我可以毫无问题地从 Postman 调用该服务。

我的docker-compose.override.yml文件如下:

version: '3.4'

services:
  grpcservice:
    container_name: grpcservice
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "8000:80" 
      #- "8001:443"
    networks:
      - grpc-network
  
  grpcclient:
    container_name: grpcclient
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - "GrpcServiceUrl=http://grpcservice:8000"
    networks:
      - grpc-network
    depends_on:
      - grpcservice

networks:
  grpc-network:
    external: false

我的 GRPC 客户端的代码(控制台应用程序中的 Program.cs)如下:

public static void CallGrpcService()
{
    string serviceUrl = System.Environment.GetEnvironmentVariable("GrpcServiceUrl");
    AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
    var channel = GrpcChannel.ForAddress(serviceUrl);
    var client = new Greeter.GreeterClient(channel);
    var reply = client.SayHello(new HelloRequest { Name = "GreeterClient" });
    Console.WriteLine("Greeting: " + reply.Message);
    Console.WriteLine("Press any key to exit...");
    Console.ReadKey();
}

完整的解决方案以及 docker 和 compose 文件 are in this repo in my github

有人可以帮我解决这个问题吗?

最佳答案

我已经成功执行了问题的 git 存储库中提供的代码,但只是在应用了以下修改之后:

  • 将 Kestrel 配置为监听任何 IP 以及 80 以外的端口:

     builder.WebHost.ConfigureKestrel(options =>
     {
         // Setup a HTTP/2 endpoint without TLS.
         options.ListenAnyIP(8000, o => o.Protocols = HttpProtocols.Http2);
     });
    
  • docker-compose.override.yml中,grpcservice应该有端口映射:

     ports:
       - "8000:8000"
    
  • 为了更轻松地设置,我删除了卷定义,因为安全传输不是讨论的主题。

  • 从客户端删除了 Http2UnencryptedSupport 开关,因为 .net 5 或更高版本中不再需要它。更多详情可查看here .

这是 docker compose 的输出:

Creating grpcservice ... done
Creating grpcclient  ... done
Attaching to grpcservice, grpcclient
grpcservice    | warn: Microsoft.AspNetCore.Server.Kestrel[0]
grpcservice    |       Overriding address(es) 'https://+:443, http://+:80'. Binding to endpoints defined via IConfiguration and/or UseKestrel() instead.
grpcservice    | info: Microsoft.Hosting.Lifetime[14]
grpcservice    |       Now listening on: http://[::]:8000
grpcservice    | info: Microsoft.Hosting.Lifetime[0]
grpcservice    |       Application started. Press Ctrl+C to shut down.
grpcservice    | info: Microsoft.Hosting.Lifetime[0]
grpcservice    |       Hosting environment: Development
grpcservice    | info: Microsoft.Hosting.Lifetime[0]
grpcservice    |       Content root path: /app
grpcclient     | Greeting: Hello GreeterClient
grpcclient exited with code 0

关于c# - 调用在docker中运行的不安全的GRPC服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74296197/

相关文章:

c# - 将 varchar 数据类型转换为 datetime 数据类型导致值超出范围

c# - 字符串连接和复杂性?

c# - 用于替换除数字之外的所有字符的正则表达式

dockerize 提示输入密码的 CLI

c# - 限制某些用户的服务的最佳方式是什么

.net - 如何在 C++ 中创建不规则形状的按钮?

c# - RegexOptions.IgnorePatternWhitespace 和组命名,括号后不允许有空格?

docker - Dockerfile无法运行可执行文件

docker : "Error response from daemon: missing signature key"

c# - Ninject 和 ASP.NET Web API