【问题标题】:Kubernetes pod resolve external kafka hostname in coredns not as hostaliases inside podKubernetes pod 将 coredns 中的外部 kafka 主机名解析为 pod 内的 hostaliases
【发布时间】:2020-08-29 14:49:48
【问题描述】:

我有 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

它可以正常工作,但我不希望这是拥有 hostaliases 的不好做法,如果 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

【问题讨论】:

  • externalname怎么样
  • 如果 IP 发生变化,您打算如何更新 coreDNS?
  • 如何向 coredns resolve.conf 添加条目,如下所示,10.76.XX.1 kafka-worker1.abc.com 10.76.XX.2 kafka-worker2.abc.com

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


【解决方案1】:

感谢您提出问题并展示您为解决问题所做的努力。

添加hostAliases 不是一个好的做法是正确的,因为在您的 kafka 托管 IP 发生更改的事件中,您必须将新 IP 应用于部署,它会触发 pod 重新加载。

我不确定externalIPs 是否适合这里作为解决方案,因为:

在服务端口上使用外部 IP(作为目标 IP)进入集群的流量将被路由到服务端点之一。 externalIP 不由 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, 主机名结帐此api ref - 这种方法的优点是 k8s 会为你的 kafka 工作人员进行负载平衡

第二个ExternalName

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

这种方法无法保证,并且可能需要根据您的系统网络进行额外调整以解析域名。也就是说,您的 coredns/kube-dns 运行该节点的节点应该能够解析 kafka-worker.abc.com 否则当 k8s 返回 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。

【讨论】:

  • 感谢 @garlicFrancium 我尝试使用第一个解决方案 Headless Service 现在 DNS 已解析但给出“无法建立。代理可能不可用。”错误。检查问题中的更新部分。
  • 抱歉写错了名字,第一个解决方案叫做“没有选择器的服务”而不是“无头服务”。我在答案中更新了相同的内容。我也回答了你的其他问题。
  • 仍然收到同样的错误 Francium,用最新的解决方案更新问题部分。下面是 resolve.conf。 >kubectl exec -ti dnsutils -- cat /etc/resolv.conf nameserver 10.96.0.10 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:5
  • 您检查过您的 kafka 是否实际工作?像你可以从你有你的 k8s 集群的节点上curlhealthz 端点吗?你确定kafka在听9092吗?我也不认为您的入口会造成干扰,但暂时取消入口以进行调试不会有任何伤害。请注意,您必须在开发实验室而不是生产环境中执行此操作!
  • 是的 ping 正在发生,如果我添加主机别名来部署它的工作。 2020-05-19T07:07:01.029+0000 Etc/UTC docker-desktop INFO [Camel (SMP-Proactive-Camel) 线程 #1 - KafkaConsumer [recommendations-topic]] org.apache.kafka.clients.consumer.internals。 ConsumerCoordinator(:267) - [Consumer clientId=consumer-hal-tr69-streaming-1, groupId=hal-tr69-streaming] 添加新分配的分区:recommens-topic-2。我也关闭了入口来检查
猜你喜欢
  • 1970-01-01
  • 2020-02-13
  • 1970-01-01
  • 2020-03-15
  • 2019-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多