简体   繁体   English

无法连接到在本地 Docker 容器中运行的 Go GRPC 服务器

[英]Cannot connect to Go GRPC server running in local Docker container

I have a go grpc service.我有一个 go grpc 服务。 I'm developing on a mac, sierra.我正在Mac上开发,山脉。 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:在本地针对服务运行 grpc 客户端时,一切都很好,但是当针对 docker 容器中的相同服务运行相同的客户端时,我收到此错误:

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

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

my command to build the image:我构建图像的命令:

docker build -t bar .

my command to launch the docker container:我启动 docker 容器的命令:

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

Other info:其他信息:

  • client program runs fine from within the docker container客户端程序在 docker 容器中运行良好
  • connecting to a regular rest endpoint works fine (http2, grpc related?)连接到常规休息端点工作正常(http2,grpc 相关?)
  • running the lsof command in OS X yields these results在 OS X 中运行lsof命令会产生这些结果

    $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) }

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.当您指定要侦听的主机名或 IP 地址(在本例中为解析为 127.0.0.1 的 localhost)时,您的服务器将仅侦听该 IP 地址。

Listening on localhost isn't a problem when you are outside of a Docker container.当您在 Docker 容器之外时,在 localhost 上侦听不是问题。 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.如果您的服务器仅侦听 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.当您在 Docker 容器中运行服务器时,它只会像以前一样侦听 127.0.0.1:51672。 The 127.0.0.1 is a local loopback address and it not accessible outside the container. 127.0.0.1 是本地环回地址,无法在容器外访问。

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.当您使用“-p 51672:51672”启动 docker 容器时,它会将前往 127.0.0.1:51672 的流量转发到容器的 IP 地址,在我的例子中是 172.17.0.2。

The container gets an IP addresses within the docker0 network interface (which you can see with the "ip addr ls" command)容器在 docker0 网络接口中获取 IP 地址(您可以使用“ip addr ls”命令查看)

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.因此,当您的流量被转发到 172.17.0.2:51672 上的容器时,那里没有任何监听并且连接尝试失败。

The fix:修复:

The problem is with the listen endpoint:问题在于监听端点:

endpoint := "localhost:51672"

To fix your problem, change it to要解决您的问题,请将其更改为

endpoint := ":51672"

That'll make your server listen on all it container's IP addresses.这将使您的服务器侦听所有容器的 IP 地址。

Additional info:附加信息:

When you expose ports in a Docker container, Docker will create iptables rules to do the actual forwarding.当您在 Docker 容器中公开端口时,Docker 将创建 iptables 规则来进行实际转发。 See this .看到这个 You can view these rules with:您可以通过以下方式查看这些规则:

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

如果你使用 docker 容器运行 grpc 服务,你应该确保grpc servicegrpc client在同一个网桥上

如果您使用的是 docker 容器,您可以通过 IP 定义网络并将此 IP 提供给您的 IP 地址(例如:178.20.0.5)。

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

相关问题 无法连接到在本地 Docker 容器中运行的 gRPC 服务 - Cannot connect to a gRPC service running in local Docker container 无法连接到在本地Docker容器中运行的MongoDB - Cannot connect to MongoDB running in local Docker container 无法连接到运行Kestrel服务器的本地Docker - Cannot connect to local Docker running Kestrel server 在本地计算机上运行的Django无法连接到运行MYSQL的Docker容器 - django running on local machine cannot connect to docker container running MYSQL Docker - Web 浏览器无法连接到服务器上正在运行的 web 应用程序容器 - Docker - Web browser cannot connect to a running web app container on server 无法从外部连接到运行CherryPy服务器的docker容器 - Cannot connect externally to a docker container running CherryPy server 无法连接到 Docker 容器中的 Go 服务器 - Can't connect to Go Server in Docker container Docker 网络无法连接到容器中的本地 IP - Docker networking cannot connect to local IP in Container 无法连接到在 Docker 容器中运行的 Cassandra - Cannot connect to Cassandra running in a Docker container 在本地 Docker 容器(Windows,wsl-2)下运行用 go 编写的服务器时出现问题 - Issue during running server written in go under the local Docker container (Windows, wsl-2)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM