Kubernetes Pod解析Coredns中的外部Kafka主机名,而不是Pod内部的Hostaliases

时间:2020-05-13 12:03:38

标签: docker kubernetes apache-kafka kube-dns coredns

我有一个Spring Boot应用程序,其中我们在application.property中指定以下属性。 kafka已安装在具有自签名证书的远程计算机上(在kubernete群集之外)。

camel.component.kafka.configuration.brokers=kafka-worker1.abc.com:9092,kafka-worker2.abc.com:9092,kafka-worker3.abc.com:9092

在应用程序启动时,它将尝试寻找kafka经纪人。 现在,如果我将hostaliases添加到部署中,它将像下面一样正常工作

  hostAliases:
  - ip: 10.76.XX.XX
    hostnames:
    - kafka-worker1.abc.com
  - ip: 10.76.XX.XX
    hostnames:
    - kafka-worker2.abc.com
  - ip: 10.76.XX.XX
    hostnames:
    - kafka-worker3.abc.com

它可以正常工作,但是我不希望这样有hostalias,因为如果IP更改,我们可能需要重启pod。 我们希望该主机名解析发生在coredns上,或者解决该问题而不将ip添加到pod的主机文件中。

如何实现这一目标。 遵循此Cannot connecto to external database from inside kubernetes pod服务端点,如下所示,分别为kafka-worker2和kafka-worker3创建了IP地址

    kind: Service
    apiVersion: v1
    metadata:
     name: kafka-worker1
    spec:
     clusterIP: None
     ports:
     - port: 9092
       targetPort: 9092
     externalIPs:
       - 10.76.XX.XX

并将其添加到属性文件

camel.component.kafka.configuration.brokers=kafka-worker1.default:9092,kafka-worker2.default:9092,kafka-worker3.default:9092

仍然得到相同的警告

2020-05-13T11:57:12.004+0000 Etc/UTC docker-desktop WARN  [main] org.apache.kafka.clients.ClientUtils(:74) - Couldn't resolve server hal18-coworker2.default:9092 from bootstrap.servers as DNS resolution failed for kafka-worker1.default
2020-05-13T11:57:12.318+0000 Etc/UTC docker-desktop WARN  [main] org.apache.kafka.clients.ClientUtils(:74) - Couldn't resolve server hal18-coworker1.default:9092 from bootstrap.servers as DNS resolution failed for kafka-worker2.default
2020-05-13T11:57:12.567+0000 Etc/UTC docker-desktop WARN  [main] org.apache.kafka.clients.ClientUtils(:74) - Couldn't resolve server hal18-coworker3.default:9092 from bootstrap.servers as DNS resolution failed for kafka-worker3.default

更新部分

以下使用“没有选择器的服务”仍然出现相同的错误

2020-05-18T14:47:10.865+0000 Etc/UTC docker-desktop WARN  [Camel (SMP-Proactive-Camel) thread #1 - KafkaConsumer[recommendations-topic]] org.apache.kafka.clients.NetworkClient(:750) - [Consumer clientId=consumer-hal-tr69-streaming-1, groupId=hal-tr69-streaming] Connection to node -1 (kafka-worker.default.svc.cluster.local/10.100.153.152:9092) could not be established. Broker may not be available.
2020-05-18T14:47:12.271+0000 Etc/UTC docker-desktop WARN  [Camel (SMP-Proactive-Camel) thread #1 - KafkaConsumer[recommendations-topic]] org.apache.kafka.clients.NetworkClient(:750) - [Consumer clientId=consumer-hal-tr69-streaming-1, groupId=hal-tr69-streaming] Connection to node -1 (kafka-worker.default.svc.cluster.local/10.100.153.152:9092) could not be established. Broker may not be available.
2020-05-18T14:47:14.191+0000 Etc/UTC docker-desktop WARN  [Camel (SMP-Proactive-Camel) thread #1 - KafkaConsumer[recommendations-topic]] org.apache.kafka.clients.NetworkClient(:750) - [Consumer clientId=consumer-hal-tr69-streaming-1, groupId=hal-tr69-streaming] Connection to node -1 (kafka-worker.default.svc.cluster.local/10.100.153.152:9092) could not be established. Broker may not be available.

服务和端点Yaml

apiVersion: v1
kind: Service
metadata:
 name: kafka-worker
spec:
 type: ClusterIP
 ports:
 - port: 9092
   targetPort: 9092
---
apiVersion: v1
kind: Endpoints
metadata:
 name: kafka-worker
subsets:
 - addresses:
   - ip: 10.76.XX.XX # kafka worker 1
   - ip: 10.76.XX.XX # kafka worker 2
   - ip: 10.76.XX.XX # kafka worker 3
   ports:
   - port: 9092
     name: kafka-worker

kubectl.exe get svc,ep
NAME                                         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             LoadBalancer   10.99.101.185    localhost     80:31247/TCP,443:31340/TCP   11d
service/ingress-nginx-controller-admission   ClusterIP      10.103.212.117   <none>        443/TCP                      11d
service/kafka-worker                         ClusterIP      10.100.153.152   <none>        9092/TCP                     97s
service/kubernetes                           ClusterIP      10.96.0.1        <none>        443/TCP                      17d

NAME                                           ENDPOINTS                                            AGE
endpoints/ingress-nginx-controller             10.1.0.XX:80,10.1.0.XX:443                           11d
endpoints/ingress-nginx-controller-admission   10.1.0.xx:8443                                       11d
endpoints/kafka-worker                         10.76.xx.xx:9092,10.76.xx.xx:9092,10.76.xx.xx:9092   97s
endpoints/kubernetes                           192.168.XX.XX:6443                                   17d

1 个答案:

答案 0 :(得分:6)

感谢您提出问题,并表示您将努力解决问题。

添加hostAliases是不对的,这不是一个好习惯,因为一旦您的kafka托管IP更改,那么您将必须将新IP应用于部署,这将触发Pod重新加载。

由于以下原因,我不确定externalIPs如何适合作为解决方案:

使用服务端口上的外部IP(作为目标IP)进入群集的流量将被路由到服务端点之一。外部IP不受Kubernetes的管理,由集群管理员负责。

但是,如果我想当然地认为externalIP解决方案正在工作,那么即使如此,您访问服务的方式也不正确!

DNS解析失败,因为您的域名错误camel.component.kafka.configuration.brokers=kafka-worker1.default:9092将其更改为此camel.component.kafka.configuration.brokers=kafka-worker1.default.svc.cluster.local:9092可能会解决它。注意:如果您的k8s集群的域与默认域不同,则将cluster.local替换为您的k8s集群域。

检查DNS调试REF

我可以想到两种解决方案:

首先创建Service without selectors和手动创建端点:

(示例代码)端点的名称用于附加到服务。因此,服务和终结点使用相同的名称,即kafka-worker

apiVersion: v1
kind: Service
metadata:
 name: kafka-worker
spec:
 type: ClusterIP
 ports:
 - port: 9092
   targetPort: 9092
---
apiVersion: v1
kind: Endpoints
metadata:
 name: kafka-worker
subsets:
 - addresses:
   - ip: 10.76.XX.XX # kafka worker 1
   - ip: 10.76.XX.XX # kafka worker 2
   - ip: 10.76.XX.XX # kafka worker 3
   ports:
   - port: 9092
     name: kafka-worker

访问此地址的方式为camel.component.kafka.configuration.brokers=kafka-worker.default.svc.cluster.local:9092

注意: -您可以向节点ip添加更多信息,例如nodeName, hostName签出此api ref -这种方法的优势是k8s会为卡夫卡工人提供均衡的负载

第二ExternalName

对于这种方法,您将需要已经定义了单个域名,该操作超出了此答案的范围,但是例如kafka-worker.abc.com是您的域名,现在您有责任附加所有您的3个kafka工作程序节点IP(可能)以循环方式发送到您的DNS服务器。 注意:这种负载平衡(通过DNS)并非总是首选,因为DNS服务器不会执行运行状况检查来确保哪些节点处于活动状态以及哪些节点已死亡

不能保证这种方法,并且可能需要根据系统网络的其他调整来解析域名。也就是说运行coredns / kube-dns的节点应该能够解析kafka-worker.abc.com,否则当k8返回CNAME时,应用程序将无法解析它!

这里是一个例子:

kind: Service
metadata:
  name: kafka-worker
spec:
  type: ExternalName
  externalName: kafka-worker.abc.com

更新: 关注问题中的更新。 查看第一个错误,看来您已经创建了3个服务,这些服务会生成3个DNS

kafka-worker3.default.svc.cluster.local
kafka-worker2.default.svc.cluster.local
kafka-worker1.default.svc.cluster.local

我建议,如果可以的话,请检查我的示例代码!您不需要创建3个服务,只需创建一个附加到端点的服务,该端点具有3个代理中的3个IP。

第二个错误: hostname不是域名,主机名通常是提供给计算机的名称(请检查difference)。为了简单起见,我建议在端点对象中仅使用IP。