【问题标题】:Not able to connect to kafka brokers无法连接到卡夫卡经纪人
【发布时间】:2020-07-21 03:18:34
【问题描述】:

我已经在我的本地 k8s 集群上部署了 https://github.com/confluentinc/cp-helm-charts/tree/master/charts/cp-kafka。 我正在尝试使用带有 nginx 的 TCP 控制器来公开它。

我的 TCP nginx 配置图看起来像

data:
  "<zookeper-tcp-port>": <namespace>/cp-zookeeper:2181
  "<kafka-tcp-port>": <namespace>/cp-kafka:9092

我已经在我的 nginx 入口控制器中创建了相应的条目

  - name: <zookeper-tcp-port>-tcp
    port: <zookeper-tcp-port>
    protocol: TCP
    targetPort: <zookeper-tcp-port>-tcp
  - name: <kafka-tcp-port>-tcp
    port: <kafka-tcp-port>
    protocol: TCP
    targetPort: <kafka-tcp-port>-tcp

现在我正在尝试连接到我的 kafka 实例。 当我尝试使用 kafka 工具连接到 IP 和端口时,我收到错误消息

Unable to determine broker endpoints from Zookeeper.
One or more brokers have multiple endpoints for protocol PLAIN...
Please proved bootstrap.servers value in advanced settings
[<cp-broker-address-0>.cp-kafka-headless.<namespace>:<port>][<ip>]

当我进入时,我认为是正确的经纪人地址(我都试过了......)我得到了一个超时。没有来自 nginx 控制器异常的日志

[08/Apr/2020:15:51:12 +0000]TCP200000.000
[08/Apr/2020:15:51:12 +0000]TCP200000.000
[08/Apr/2020:15:51:14 +0000]TCP200000.001

从 pod kafka-zookeeper-0 我得到了很多

[2020-04-08 15:52:02,415] INFO Accepted socket connection from /<ip:port> (org.apache.zookeeper.server.NIOServerCnxnFactory)
[2020-04-08 15:52:02,415] WARN Unable to read additional data from client sessionid 0x0, likely client has closed socket (org.apache.zookeeper.server.NIOServerCnxn)
[2020-04-08 15:52:02,415] INFO Closed socket connection for client /<ip:port>  (no session established for client) (org.apache.zookeeper.server.NIOServerCnxn)

虽然我不确定这些与它有什么关系?

关于我做错了什么有什么想法吗? 提前致谢。

【问题讨论】:

  • 您是尝试从集群 LAN 连接还是暴露在网络上?如果是,请注意细节?
  • 在集群内这不是问题。在那里我可以直接连接到每个经纪人。但是对于来自外部的流量,我希望cp-kafka 服务通过cp-kafka-headless 服务将我连接到代理。还是我这样想错了?
  • 因为它是一个headless service,它更像是一个有状态 Pod 的 DNS 发现服务,它没有 IP 地址。一个解决方案是直接为 cp-kafka-0 创建一个外部服务。我会写一个例子,并在我为你准备的答案中扩展这个解释!

标签: kubernetes apache-kafka confluent-platform


【解决方案1】:

TL;DR:

  • 在部署前将cp-kafka/values.yaml 内的nodeport.enabled 值更改为true
  • 更改 TCP NGINX Configmap 和 Ingress 对象中的服务名称和端口。
  • 在您的 kafka 工具上将 bootstrap-server 设置为 &lt;Cluster_External_IP&gt;:31090

说明:

Headless Service 是与 StatefulSet 一起创建的。创建的服务将不会获得clusterIP,而是简单地包含Endpoints 的列表。 然后使用这些Endpoints 生成特定于实例的 DNS 记录,格式如下: &lt;StatefulSet&gt;-&lt;Ordinal&gt;.&lt;Service&gt;.&lt;Namespace&gt;.svc.cluster.local

它为每个 pod 创建一个 DNS 名称,例如:

[ root@curl:/ ]$ nslookup my-confluent-cp-kafka-headless
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      my-confluent-cp-kafka-headless
Address 1: 10.8.0.23 my-confluent-cp-kafka-1.my-confluent-cp-kafka-headless.default.svc.cluster.local
Address 2: 10.8.1.21 my-confluent-cp-kafka-0.my-confluent-cp-kafka-headless.default.svc.cluster.local
Address 3: 10.8.3.7 my-confluent-cp-kafka-2.my-confluent-cp-kafka-headless.default.svc.cluster.local
  • 这就是使这些服务在集群内相互连接的原因。

我经历了很多试验和错误,直到我意识到它应该如何工作。基于您的 TCP Nginx Configmap,我相信您遇到了同样的问题。

  • Nginx ConfigMap 请求:&lt;PortToExpose&gt;: "&lt;Namespace&gt;/&lt;Service&gt;:&lt;InternallyExposedPort&gt;"
  • 我意识到您不需要公开 Zookeeper,因为它是内部服务并由 kafka 代理处理。
  • 我还意识到您正试图公开 cp-kafka:9092,它是无头服务,也仅在内部使用,如上所述。
  • 为了获得外部访问权限您必须将参数nodeport.enabled 设置为true,如下所述:External Access Parameters
  • 它在图表部署期间向每个 kafka-N pod 添加一项服务。
  • 然后您将配置映射更改为映射到其中之一:
data:
"31090": default/demo-cp-kafka-0-nodeport:31090

请注意,创建的服务具有选择器 statefulset.kubernetes.io/pod-name: demo-cp-kafka-0,这是服务识别其要连接的 pod 的方式。

  • 编辑 nginx-ingress-controller:
- containerPort: 31090
  hostPort: 31090
  protocol: TCP
  • 将您的 kafka 工具设置为 &lt;Cluster_External_IP&gt;:31090

复制: - 片段编辑于cp-kafka/values.yaml:

nodeport:
  enabled: true
  servicePort: 19092
  firstListenerPort: 31090
  • 部署图表:
$ helm install demo cp-helm-charts
$ kubectl get pods
NAME                                       READY   STATUS    RESTARTS   AGE
demo-cp-control-center-6d79ddd776-ktggw    1/1     Running   3          113s
demo-cp-kafka-0                            2/2     Running   1          113s
demo-cp-kafka-1                            2/2     Running   0          94s
demo-cp-kafka-2                            2/2     Running   0          84s
demo-cp-kafka-connect-79689c5c6c-947c4     2/2     Running   2          113s
demo-cp-kafka-rest-56dfdd8d94-79kpx        2/2     Running   1          113s
demo-cp-ksql-server-c498c9755-jc6bt        2/2     Running   2          113s
demo-cp-schema-registry-5f45c498c4-dh965   2/2     Running   3          113s
demo-cp-zookeeper-0                        2/2     Running   0          112s
demo-cp-zookeeper-1                        2/2     Running   0          93s
demo-cp-zookeeper-2                        2/2     Running   0          74s

$ kubectl get svc
NAME                         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)             AGE
demo-cp-control-center       ClusterIP   10.0.13.134   <none>        9021/TCP            50m
demo-cp-kafka                ClusterIP   10.0.15.71    <none>        9092/TCP            50m
demo-cp-kafka-0-nodeport     NodePort    10.0.7.101    <none>        19092:31090/TCP     50m
demo-cp-kafka-1-nodeport     NodePort    10.0.4.234    <none>        19092:31091/TCP     50m
demo-cp-kafka-2-nodeport     NodePort    10.0.3.194    <none>        19092:31092/TCP     50m
demo-cp-kafka-connect        ClusterIP   10.0.3.217    <none>        8083/TCP            50m
demo-cp-kafka-headless       ClusterIP   None          <none>        9092/TCP            50m
demo-cp-kafka-rest           ClusterIP   10.0.14.27    <none>        8082/TCP            50m
demo-cp-ksql-server          ClusterIP   10.0.7.150    <none>        8088/TCP            50m
demo-cp-schema-registry      ClusterIP   10.0.7.84     <none>        8081/TCP            50m
demo-cp-zookeeper            ClusterIP   10.0.9.119    <none>        2181/TCP            50m
demo-cp-zookeeper-headless   ClusterIP   None          <none>        2888/TCP,3888/TCP   50m
  • 创建 TCP 配置映射:
$ cat nginx-tcp-configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: kube-system
data:
  31090: "default/demo-cp-kafka-0-nodeport:31090"

$ kubectl apply -f nginx-tcp.configmap.yaml
configmap/tcp-services created
  • 编辑 Nginx 入口控制器:
$ kubectl edit deploy nginx-ingress-controller -n kube-system

$kubectl get deploy nginx-ingress-controller -n kube-system -o yaml
{{{suppressed output}}}
        ports:
        - containerPort: 31090
          hostPort: 31090
          protocol: TCP
        - containerPort: 80
          name: http
          protocol: TCP
        - containerPort: 443
          name: https
          protocol: TCP
  • 我的入口在 IP 35.226.189.123,现在让我们尝试从集群外部连接。为此,我将连接到另一个我有 minikube 的 VM,因此我可以使用 kafka-client pod 进行测试:
user@minikube:~$ kubectl get pods
NAME           READY   STATUS    RESTARTS   AGE
kafka-client   1/1     Running   0          17h

user@minikube:~$ kubectl exec kafka-client -it -- bin/bash

root@kafka-client:/# kafka-console-consumer --bootstrap-server 35.226.189.123:31090 --topic demo-topic --from-beginning --timeout-ms 8000 --max-messages 1
Wed Apr 15 18:19:48 UTC 2020
Processed a total of 1 messages
root@kafka-client:/# 

如您所见,我能够从外部访问 kafka。

  • 如果您还需要外部访问 Zookeeper,我会为您留下一个服务模型:

zookeeper-external-0.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: cp-zookeeper
    pod: demo-cp-zookeeper-0
  name: demo-cp-zookeeper-0-nodeport
  namespace: default
spec:
  externalTrafficPolicy: Cluster
  ports:
  - name: external-broker
    nodePort: 31181
    port: 12181
    protocol: TCP
    targetPort: 31181
  selector:
    app: cp-zookeeper
    statefulset.kubernetes.io/pod-name: demo-cp-zookeeper-0
  sessionAffinity: None
  type: NodePort
  • 它将为其创建服务:
NAME                           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)             AGE
demo-cp-zookeeper-0-nodeport   NodePort    10.0.5.67     <none>        12181:31181/TCP     2s
  • 修补您的配置图:
data:
  "31090": default/demo-cp-kafka-0-nodeport:31090
  "31181": default/demo-cp-zookeeper-0-nodeport:31181
  • 添加入口规则:
        ports:
        - containerPort: 31181
          hostPort: 31181
          protocol: TCP
  • 使用您的外部 IP 进行测试:
pod/zookeeper-client created
user@minikube:~$ kubectl exec -it zookeeper-client -- /bin/bash
root@zookeeper-client:/# zookeeper-shell 35.226.189.123:31181
Connecting to 35.226.189.123:31181
Welcome to ZooKeeper!
JLine support is disabled

如果您有任何疑问,请在 cmets 中告诉我!

【讨论】:

  • 哇,谢谢!很好的答案,非常感谢。只是一件事,为什么要将 nginx 入口控制器端口设置为 demo-cp-zookeeper-0-nodeport 实际节点端口?即31090 而不是19092?我做了另一种方式,并将 nginx 控制器设置为映射到 19092 并且它可以工作。虽然当它工作时我尝试将 nodeport 服务重新设置为一个 cluter IP,但这并没有按预期工作......无论如何,巨大谢谢!
  • 我很高兴它有帮助。实际上,我是从 helm chart 生成的服务中复制的,这对我来说也没有多大意义,但它确实有效,所以我让它照原样使用,但如果将其用作 ClusterIP,你在使用 Port 时在技术上是正确的。 30000 - 32767 之间的端口范围是为NodePorts 保留的,它不适用于ClusterIP 类型。
  • 那么,通过将服务重新定义为``` 端口:19092 协议:TCP 目标端口:19092``` 我可以将其定义为 ClusterIP 并使用它而不是节点端口?
  • 是的,没错,删除nodeporte: 31090这一行。你试过了吗?
  • 不工作...在我的 nginx-ingress-controller pod 中看到 2020/04/17 16:32:23 [error] 352#352: *710385 connect() failed (111: Connection refused) while connecting to upstream, client: &lt;ip&gt;, server: 0.0.0.0:39092, upstream: "&lt;ip&gt;:19092", bytes from/to client:0/0, bytes from/to upstream:0/0... 我的 nginx 配置映射定义为 "39092": &lt;namespace&gt;/cp-kafka-0-nodeport:19092.. Can't really get it to work without the nodeport` 定义...
猜你喜欢
  • 1970-01-01
  • 2021-03-17
  • 1970-01-01
  • 1970-01-01
  • 2016-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-11
相关资源
最近更新 更多