无法连接到在本地Docker容器中运行的Go GRPC服务器 [英] Cannot connect to Go GRPC server running in local Docker container

查看:304
本文介绍了无法连接到在本地Docker容器中运行的Go GRPC服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有go grpc服务。我在Mac上开发,塞拉利昂。在本地针对该服务运行grpc客户端时,一切都很好,但是在docker容器中针对同一服务运行相同的客户端时,出现此错误:

I have a go grpc service. I'm developing on a mac, sierra. When running a grpc client against the service locally, all is well, but when running same client against same service in the docker container I get this error:

transport: http2Client.notifyError got notified that the client transport was broken EOF.
FATA[0000] rpc error: code = Internal desc = transport is closing

这是我的docker文件:

this is my docker file:

FROM golang:1.7.5

RUN mkdir -p /go/src/github.com/foo/bar
WORKDIR /go/src/github.com/foo/bar

COPY . /go/src/github.com/foo/bar
# ONBUILD RUN go-wrapper download
RUN go install

ENTRYPOINT /go/bin/bar

EXPOSE 51672

我创建图像的命令:

docker build -t bar .

我用来启动Docker容器的命令:

my command to launch the docker container:

docker run -p 51672:51672 --name bar-container bar



其他信息:




  • 客户端程序在docker容器中运行良好

  • 连接到正常的休息端点可以正常工作(http2,与grpc相关吗?)

  • 在OS X中运行 lsof 命令会产生以下结果结果

    Other info:

    • client program runs fine from within the docker container
    • connecting to a regular rest endpoint works fine (http2, grpc related?)
    • running the lsof command in OS X yields these results

      $lsof -i | grep 51672
      com.docke   984 oldDave   21u  IPv4 0x72779547e3a32c89      0t0  TCP *:51672 (LISTEN)
      com.docke   984 oldDave   22u  IPv6 0x72779547cc0fd161      0t0  TCP localhost:51672 (LISTEN)
      


    • 这是我的服务器代码的片段:

    • here's a snippet of my server code:

      server := &Server{}
      endpoint := "localhost:51672"
      lis, err := net.Listen("tcp", endpoint)
      if err != nil {
          log.Fatalf("failed to listen: %v", err)
      }
      
      s := grpc.NewServer(grpc.Creds(creds))
      
      pb.RegisterExpServiceServer(s, server)
      
      // Register reflection service on gRPC server.
      reflection.Register(s)
      
      log.Info("Starting Exp server: ", endpoint)
      
      if err := s.Serve(lis); err != nil {
          log.Fatalf("failed to serve: %v", err)
      }
      


    • 推荐答案

      当您指定要监听的主机名或IP地址时(在这种情况下,本地主机解析为127.0.0.1),那么您的服务器将仅侦听该IP地址。

      When you specify a hostname or IP address​ to listen on (in this case localhost which resolves to 127.0.0.1), then your server will only listen on that IP address.

      在Docker容器之外时,在localhost上监听不是问题。如果您的服务器仅侦听127.0.0.1:51672,则您的客户端可以轻松连接到该服务器,因为连接也是从127.0.0.1建立的。

      Listening on localhost isn't a problem when you are outside of a Docker container. If your server only listens on 127.0.0.1:51672, then your client can easily connect to it since the connection is also made from 127.0.0.1.

      运行时服务器在Docker容器中,它只会像以前一样监听127.0.0.1:51672。 127.0.0.1是本地环回地址,无法在容器外部访问。

      When you run your server inside a Docker container, it'll only listen on 127.0.0.1:51672 as before. The 127.0.0.1 is a local loopback address and it not accessible outside the container.

      当您使用 -p 51672:51672启动Docker容器时,它将把流量转发到127.0.0.1:51672到该容器的IP地址在我的情况下是172.17.0.2。

      When you fire up the docker container with "-p 51672:51672", it'll forward traffic heading to 127.0.0.1:51672 to the container's IP address, which in my case is 172.17.0.2.

      容器在docker0网络接口内获取IP地址(您可以通过 ip addr ls命令看到该地址)

      The container gets an IP addresses within the docker0 network interface (which you can see with the "ip addr ls" command)

      因此,当您的流量在172.17.0.2:51672上转发到容器时,那里什么也听不到,连接尝试失败。

      So, when your traffic gets forwarded to the container on 172.17.0.2:51672, there's nothing listening there and the connection attempt fails.

      修复:

      问题在于侦听端点:

      endpoint := "localhost:51672"
      

      要解决您的问题,请将其更改为

      To fix your problem, change it to

      endpoint := ":51672"
      

      这将使您的服务器监听其容器的所有IP地址。

      That'll make your server listen on all it container's IP addresses.

      附加信息:

      当您在Docker容器中公开端口时,Docker将创建iptables规则进行实际转发。请参阅。您可以使用以下命令查看这些规则

      When you expose ports in a Docker container, Docker will create iptables rules to do the actual forwarding. See this. You can view these rules with:

      iptables -n -L 
      iptables -t nat -n -L
      

      这篇关于无法连接到在本地Docker容器中运行的Go GRPC服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆