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

8 浏览
0 Comments

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

我有一个go grpc服务。我在mac上开发,版本是sierra。当在本地运行grpc客户端与服务进行通信时,一切都正常,但是当在docker容器中运行相同的客户端与相同的服务进行通信时,我会得到以下错误:

transport: http2Client.notifyError被通知客户端传输已被中断EOF。

FATA[0000] rpc错误: code = Internal desc = 传输正在关闭

这是我的docker文件:

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容器的命令是:

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

其他信息:

  • 从docker容器内部运行的客户端程序正常
  • 连接到常规的rest端点正常工作(http2,grpc相关?)
  • 在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)
    

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

    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)

    // 在gRPC服务器上注册反射服务。

    reflection.Register(s)

    log.Info("Starting Exp server: ", endpoint)

    if err := s.Serve(lis); err != nil {

    log.Fatalf("failed to serve: %v", err)

    }

0
0 Comments

无法连接到在本地Docker容器中运行的Go GRPC服务器的问题出现的原因是服务器只监听了localhost地址(127.0.0.1),而在Docker容器中,127.0.0.1是容器内部的回环地址,无法从容器外部访问。当通过"-p 51672:51672"参数启动Docker容器时,流向127.0.0.1:51672的流量会被转发到容器的IP地址(例如172.17.0.2),但由于容器内没有在172.17.0.2:51672上监听,连接尝试会失败。为了解决这个问题,需要将服务器的监听地址修改为":51672",这样服务器就会监听容器内的所有IP地址。另外,如果使用Docker Compose运行容器,可以使用在yaml文件中指定的容器名称作为主机名,它会自动映射到正确的IP地址。

补充信息:当在Docker容器中暴露端口时,Docker会创建iptables规则来进行实际的转发。可以使用命令"iptables -n -L"和"iptables -t nat -n -L"查看这些规则。另外,将监听地址设置为":[端口号]"在nodejs的grpc实现中不起作用,会出现错误"getaddrinfo failed"。

感谢以上回答的提供者,他们的解答帮助了许多人解决了类似的问题。

0
0 Comments

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

问题原因:Docker容器中的网络配置不正确。

解决方法:在Docker容器中定义网络,并将该网络的IP地址分配给你的IP地址(例如:178.20.0.5)。

具体步骤如下:

1. 在Docker容器中定义网络。可以使用以下命令创建一个新的网络:

docker network create mynetwork

2. 运行Go GRPC服务器的Docker容器时,将该容器连接到刚刚创建的网络。可以使用以下命令启动容器:

docker run --network=mynetwork mygrpcserver

请注意,将"mynetwork"替换为你所创建的网络的名称,"mygrpcserver"替换为你的Go GRPC服务器的Docker镜像名称。

3. 确定Go GRPC服务器容器的IP地址。可以使用以下命令查看容器的IP地址:

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 

请将""替换为你的Go GRPC服务器容器的ID。

4. 将Go GRPC服务器容器的IP地址分配给你的IP地址。可以在代码中使用以下方法分配IP地址:

import (

"net"

"os"

)

func main() {

conn, err := net.Dial("tcp", ":")

if err != nil {

fmt.Println("Failed to connect:", err)

os.Exit(1)

}

// 继续处理连接

}

请将""替换为步骤3中获取到的Go GRPC服务器容器的IP地址,""替换为你的Go GRPC服务器的端口号。

通过按照上述步骤进行操作,你应该能够成功连接到在本地Docker容器中运行的Go GRPC服务器。

0