【问题标题】:How to connect to the gRPC service inside k8s cluster from outside gRPC client如何从外部 gRPC 客户端连接到 k8s 集群内的 gRPC 服务
【发布时间】:2021-06-14 23:18:37
【问题描述】:

我有一个 gRPC server 在端口 9000 上运行,gRPC-gateway 在端口 9080 上运行。 我可以使用以下链接向邮递员请求我的服务:```http://cluster1.example.com/api/v1/namespaces/default/services/my-service :9080/代理

如何使用grpc.Dial()gRPC client(在我的本地计算机上,位于集群外部)连接到我的服务?

例子:

conn, err := grpc.Dial(...?, grpc.WithInsecure())
if err != nil {
    panic(err)
}

【问题讨论】:

  • 你试过“cluster1.example.com:9000”吗? (go gRPC 客户端将直接与 gRPC 服务器通信)。有关支持的格式,请参阅 naming doc。如果你想要一个测试这个的工具,那么试试bloomRPC
  • @Brits 我试过cluster1.example.com:9000,但得到i/o timeout 错误。我认为这是预期的行为。怎么知道grpc服务连接的是什么(k8s集群里面服务量很大)?
  • @Brits 这是a way to connect to k8s service。我在该文档的帮助下创建了我的网址。但我不明白如何从 grpc 客户端连接到集群内的特定服务...

标签: go grpc grpc-go


【解决方案1】:

您应该能够通过端口转发从本地连接到 k8s 集群中的服务:

kubectl port-forward --context <mycontext> -n <mynamespace> svc/my-service 9000:9000

然后你只需将 gRPC 目标传递给 Dial 使用 localhost 并且没有方案:

conn, err := grpc.Dial("localhost:9000", grpc.WithInsecure())
if err != nil {
    panic(err)
}

我可能会说很明显,但当然服务器也必须以不安全模式启动(无凭据),否则您可能会收到 Unavailable 响应代码。

【讨论】:

    【解决方案2】:

    简答:

    这主要不是 Golang 问题,而是 Kubernetes 问题。您必须设置 Kubernetes 部分并像以前在 Golang 中一样使用它。

    你可以参考@blackgreen's answer一个简单的临时方法。

    详情

    Kubernetes使用overlay网络,Flannel大部分情况下,集群内部的通信默认设置,与外部隔离。

    当然有一些像Calico这样的项目可以连接内外网,但那是另外一回事了。

    如果我们想从外部访问 Pod,有几种解决方案。

    kubectl

    https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/

    Kubectl 使用socat 创建隧道并将一个或多个本地端口转发到一个 pod。

    当你停止命令时端口转发将结束,但如果你想暂时访问 Pod 进行调试,这是一个不错的选择。

    kubectl port-forward redis-master-765d459796-258hz 7000:6379
    

    服务

    https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

    Service 是一种将在一组 Pod 上运行的应用程序公开为网络服务的抽象方式。

    从外部访问时,有多种Service可以使用,NodePort在大多数情况下可能是一个不错的选择。

    它使用iptablesipvs在所有节点转发网络中创建一个Port Forward到目标端口。

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      type: NodePort
      selector:
        app: MyApp
      ports:
          # By default and for convenience, the `targetPort` is set to the same value as the `port` field.
        - port: 80
          targetPort: 80
          # Optional field
          # By default and for convenience, the Kubernetes control plane will allocate a port from a range (default: 30000-32767)
          nodePort: 30007
    

    入口

    https://kubernetes.io/docs/concepts/services-networking/ingress/

    Ingress 是一个第 7 层代理,管理对Service 的外部网络访问,因为gRPC 也是建立在HTTP/2Ingress work perfectly 之上的。

    如果您要公开生产应用程序,则应该选择 Ingress。

    【讨论】:

    • 感谢您的详细解答!我会尝试使用 Ingress 来实现。
    猜你喜欢
    • 1970-01-01
    • 2020-07-20
    • 2019-12-05
    • 2021-05-20
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    相关资源
    最近更新 更多