Go语言 发送gRPC请求时查找端点(服务器)地址

zu0ti5jz  于 2023-04-03  发布在  Go
关注(0)|答案(1)|浏览(179)

是否有任何方法可以获得端点在客户端发送gRPC请求时的(服务器)地址?我有一个客户端部署通过gRPC与kubernetes集群中的服务器部署进行对话。服务器部署位于clusterIP之后。我使用clusterIP的名称和端口在我的客户端和服务器之间建立连接。如果我使用多个服务器(将副本设置为1个以上),在客户端发送gRPC请求时,有没有办法获得目标服务器地址?我想选择一个特定的服务器,我需要它的IP地址。我如何在客户端找到它?
我认为grpc/xds以某种方式自己做到了这一点。然而,似乎这些信息是隐藏的,没有API可以访问它。
我用的是Golang。

iezvtpos

iezvtpos1#

import (
    "context"
    "fmt"
    "google.golang.org/grpc"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/retry"
    "k8s.io/apimachinery/pkg/api/errors"
    "k8s.io/apimachinery/pkg/api/resource"
    "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var kubeClient kubernetes.Interface
var kubeConfig *rest.Config

func init() {
    var err error

    kubeConfig, err = clientcmd.BuildConfigFromFlags("", "/path/to/kubeconfig")
    if err != nil {
        // handle error
    }

    kubeClient, err = kubernetes.NewForConfig(kubeConfig)
    if err != nil {
        // handle error
    }
}

func main() {
    r := manual.NewBuilderWithScheme("grpc")

    // get the IP and port of the pod for the gRPC service
    address, port, err := GetPodIPAndPort("grpc-service")
    if err != nil {
        // handle error
    }

    // add the server address to the resolver
    r.InitialState(resolver.State{Addresses: []resolver.Address{
        {Addr: fmt.Sprintf("%s:%d", address, port)},
    }})

    dialer := grpc.WithResolver(r).DialContext

    // use the dialer to create a connection to the server
    conn, err := grpc.DialContext(ctx, "grpc://service-name", dialer)
    if err != nil {
        // handle error
    }

    // do gRPC 
}

func GetPodIPAndPort(serviceName string) (string, int32, error) {
    // get the endpoints for the service
    endpoints, err := kubeClient.CoreV1().Endpoints("default").Get(context.TODO(), serviceName, v1.GetOptions{})
    if err != nil {
        if errors.IsNotFound(err) {
            return "", 0, fmt.Errorf("service not found: %s", serviceName)
        } else {
            return "", 0, err
        }
    }

    // get the IP and port of the first pod in the endpoints list
    if len(endpoints.Subsets) == 0 {
        return "", 0, fmt.Errorf("no pods found for service: %s", serviceName)
    }
    address := endpoints.Subsets[0].Addresses[0].IP
    port := endpoints.Subsets[0].Ports[0].Port

    return address, port, nil
}

为了获取特定的pod细节,我们需要使用kubernetes api。

相关问题