从其他Pod创建grpc客户端时,如何解析kubernetes Pod的主机名?

问题描述

问题:

如何解析kubernetes pod的主机名?

我有以下要求,我们将grpc与java一起使用,其中我们有一个应用程序正在运行grpc服务器,另一个应用程序正在创建grpc客户端并连接到grpc服务器(在另一个容器上运行)。


我们在运行grpc服务器的地方运行着三个kubernetes pod。

让我们说: my-service-0,my-service-1,my-service-2

my-service的群集IP为:10.44.5.11


在运行gprc客户端的地方还有另外三个kubernetes pod。

让我们说: my-client-0,my-client-1,my-client-2


没有安全性:

我尝试将grpc服务器pod与grpc客户端pod连接起来,并且工作正常。

grpc client (POD -> my-client) ----------------> groc server(POD -> my-service)

因此,在没有安全性的情况下,我将主机名作为我的服务使用,并且可以正常工作,没有任何问题。.

ManagedChannel channel = ManagedChannelBuilder.forAddress("my-service",50052)
                .usePlaintext()
                .build();

具有SSL安全性:

如果我尝试连接grpc服务器,它将抛出不匹配的主机名。 我们使用通配符* .default.pod.cluster.local

创建了一个证书

它将引发以下错误

java.security.cert.CertificateException: No name matching my-service found
    at java.base/sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:225) ~[na:na]
    at java.base/sun.security.util.HostnameChecker.match(HostnameChecker.java:98) ~[na:na]
    at java.base/sun.security.ssl.x509trustmanagerImpl.checkIdentity(x509trustmanagerImpl.java:455) ~[na:na]

Not Working Code:
     ManagedChannel channel = NettyChannelBuilder.forAddress("my-service",50052)
                    .sslContext(GrpcSslContexts.forClient().trustManager(new File(System.getenv("GRPC_CLIENT_CA_CERT_LOCATION"))).build())
                    .build();

但是如果我给主机名这样的话==> 10-44-5-11.default.pod.cluster.local ,它将正常工作。

Working Code
      ManagedChannel channel = NettyChannelBuilder.forAddress("10-44-5-11.default.pod.cluster.local",50052)
                        .sslContext(GrpcSslContexts.forClient().trustManager(new File(System.getenv("GRPC_CLIENT_CA_CERT_LOCATION"))).build())
                        .build();

现在,我的问题是pod的群集ip是动态的,并且在应用程序部署期间每次都会更改。解析此主机名的正确方法是什么?

是否可以提供主机名并返回IP地址,然后将default.pod.cluster.local附加到主机名并尝试连接到grpc服务器?

解决方法

直接寻址Pod并不是一个好的解决方案,因为Kubernetes可能需要在集群中移动Pod。例如,可能由于节点故障而发生这种情况。

要让您的客户/流量轻松找到所需的容器,可以将它们放在具有单个静态IP地址的服务后面。可以通过DNS查找服务IP。

这是您可以通过其FQDN连接到该服务的方式:

my-service.default.svc.cluster.local 

其中my-service是您的服务名称,default是您的名称空间,svc.cluster.local是所有群集服务中使用的可配置群集域后缀。

值得一提的是,如果Pod在同一个命名空间中,则可以跳过svc.cluster.local后缀,甚至跳过命名空间。因此,您仅将服务称为my-service

有关更多信息,您可以检查有关DNS的K8 documents