java - 如何在从其他 pod 创建 grpc 客户端时解析 kubernetes pod 的主机名?
问题描述
问题:
如何解析 kubernetes pod 的主机名?
我有以下要求,我们将 grpc 与 java 一起使用,我们有一个应用程序,我们正在用完 grpc 服务器另一个应用程序,我们正在创建 grpc 客户端并连接到 grpc 服务器(在另一个 pod 上运行)。
我们在运行 grpc 服务器的地方运行了三个 kubernetes pod。
可以说:my-service-0,my-service-1,my-service-2
my-service 的集群 IP 为:10.44.5.11
我们在运行 gprc 客户端的地方运行了另外三个 kubernetes pod。
可以说:我的客户 0,我的客户 1,我的客户 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
是在所有集群服务中使用的可配置集群域后缀。
值得知道的是,svc.cluster.local
如果 pod 在同一个命名空间中,您可以跳过后缀甚至命名空间。因此,您只需将服务称为my-service
.
有关更多信息,您可以查看有关 DNS 的K8s文档。
推荐阅读
- javascript - 在名称空间内定义映射
- javascript - 从 JSON 对象中添加和删除的函数
- jenkins - 如果我的构建阶段在詹金斯管道中失败,如何跳过该阶段?
- javascript - 如何防止浏览器调用 Digest auth 弹出窗口并使用 Jquery 处理 401 错误?
- c++ - “无效比较器”:重载“<”运算符时出错
- javascript - Javascript:创建具有多个循环的对象
- excel - 如何在单个单元格中找到最高值和最低值
- java - 如何解析未声明为双倍的 XML 函数日期?
- java - Java反射,从不同的包创建私有类的对象
- php - PHP合并和分组数组并总结它们