Kubernetes群集中的Kafka-如何发布/使用来自Kubernetes群集之外的消息

  1. 我已经在Kubernetes集群中部署和运行了Kafka。 我使用docker hub的这个镜像 – https://hub.docker.com/r/cloudtrackinc/kubernetes-kafka/
  2. 我在我的kubernetes集群中有3个kube-node。 我有3个卡夫卡和3个动物园pipe理员应用程序运行,我有服务zoo1,zoo2,zoo3和kafka-1,kafka-2和kafka-3运行相应的。 我能够从kubernetes集群内部发布/使用,但是我无法从kubernetes集群之外发布/使用,即从外部机器而不是kubernetes集群的一部分。
  3. 我能够从外部机器到达kube-nodes – 基本上我可以使用名称/ ip来ping它们。
  4. 我没有使用任何外部负载平衡器,但我有一个DNS,可以解决我的外部机器和Kube-节点。
  5. 在这种情况下,使用NodePort或ExternalIP公开Kafka服务不起作用。
  6. 设置Kafka RC中的KAFKA_ADVERTISED_HOST_NAME或KAFKA_ADVERTISED_LISTENERS RC YML最终在server.properties中设置了ADVERTISED_HOST_NAME / ADVERTISED_LISTENERS属性,这无助于从kubernetes集群之外访问kafka。

请build议如何从kubernetes集群之外发布/使用。 非常感谢!

我能够通过做出以下更改来解决我的问题 –

  1. 在YML中使用NodeSelector使kafka pod在kube集群的特定节点上运行。

  2. 将KAFKA_ADVERTISED_HOST_NAME设置为Kube hostName,其中此Kafka POD已configuration为运行(如步骤1中所configuration)

  3. 使用NodePort公开Kafka服务,并设置与暴露的NodePort相同的POD端口,如下所示 –

spec:ports:–name:broker-2 port: 30031 targetPort:9092 nodePort: 30031 protocol:TCP selector:app:kafka-2 broker_id:“2”type:NodePort

现在,您可以使用主机:exposedPort从kube群集外部访问Kafka代理

我使用Confluent的Kafka REST代理镜像解决了这个问题。

https://hub.docker.com/r/confluentinc/cp-kafka-rest/

REST代理的文档在这里:

http://docs.confluent.io/3.1.2/kafka-rest/docs/index.html

步骤A:使用最新的Kafka版本构buildKafka经纪人docker工人图像

我使用了基于您使用的相同图像的定制卡夫卡经纪人图像。 你基本上只需要更新cloudtrackinc的图像使用卡夫卡0.10.1.0版本,否则将无法正常工作。 只需从cloudertrackinc的映像更新Dockerfile以使用最新的wurstmeister kafka映像并重新构build泊坞窗映像即可。

- FROM wurstmeister/kafka:0.10.1.0 

我将每个Kafka经纪商的ADVERTISED_HOST_NAME设置为POD的IP,这样每个经纪人都可以获得唯一的url。

 - name: ADVERTISED_HOST_NAME valueFrom: fieldRef: fieldPath: status.podIP 

步骤B:设置cp-kafka-rest代理以使用您的Kafka代理集群

Kafka Rest代理必须与您的Kafka代理群集在同一个群集中运行。

您需要至less为cp-kafka-rest映像提供两个环境variables才能运行。 KAFKA_REST_HOST_NAME和KAFKA_REST_ZOOKEEPER_CONNECT。 您可以将KAFKA_REST_HOST_NAME设置为使用POD的IP。

 - name: KAFKA_REST_HOST_NAME valueFrom: fieldRef: fieldPath: status.podIP - name: KAFKA_REST_ZOOKEEPER_CONNECT value: "zookeeper-svc-1:2181,zookeeper-svc-2:2181,zookeeper-svc-3:2181" 

步骤C:将Kafka REST代理公开为服务

spec: type: NodePort or LoadBalancer ports: - name: kafka-rest-port port: 8082 protocol: TCP

您可以使用NodePort或LoadBalancer来使用单个或多个Kafka REST代理窗格。

使用Kafka REST代理的优缺点

优点:

  1. 您可以轻松扩展卡夫卡经纪人集群
  2. 您不必在群集外部公开Kakfa经纪人
  3. 您可以使用代理的负载均衡器。
  4. 您可以使用任何types的客户端访问Kafka集群(即curl)。 非常轻的重量。

缺点:

  1. Kakfa集群顶部的另一个组件/层。
  2. 消费者在代理窗格内创build。 这将需要由您的REST客户端跟踪。
  3. 性能不理想:REST代替原生的Kafka协议。 虽然如果你部署多个代理,这可能会有所帮助。 我不会使用这个设置高stream量。 对于低容量的消息stream量,这可能是好的。

所以,如果你能忍受上面的问题,那就试试Kafka Rest Proxy。

从AWS上的k8s集群外部访问kafka也遇到同样的问题。 我设法通过使用从版本0.10.2支持多个接口的kafka监听器function来解决这个问题。

这里是我如何configurationkafka容器。

ports: - containerPort: 9092 - containerPort: 9093 env: - name: KAFKA_ZOOKEEPER_CONNECT value: "zookeeper:2181" - name: KAFKA_LISTENER_SECURITY_PROTOCOL_MAP value: "INTERNAL_PLAINTEXT:PLAINTEXT,EXTERNAL_PLAINTEXT:PLAINTEXT" - name: KAFKA_ADVERTISED_LISTENERS value: "INTERNAL_PLAINTEXT://kafka-internal-service:9092,EXTERNAL_PLAINTEXT://123.us-east-2.elb.amazonaws.com:9093" - name: KAFKA_LISTENERS value: "INTERNAL_PLAINTEXT://0.0.0.0:9092,EXTERNAL_PLAINTEXT://0.0.0.0:9093" - name: KAFKA_INTER_BROKER_LISTENER_NAME value: "INTERNAL_PLAINTEXT"除此之外,我configuration了两个服务。 一个用于内部(无头)和一个用于外部(LoadBalancer)通信。

希望这会节省人们的时间。

这似乎目前还不可能,关于这个话题,kafka的networking架构相当差。 新的消费者使用经纪人列表,这将返回动物园pipe理员的主机,但不幸的是,这是在一个不同的networking,所以它是不可能从你的本地客户端。 卡夫卡可怜的一部分是,这是不可能的指定经纪人和动物园pipe理员服务器。 这可以防止客户从外部访问系统。

我们使用busybox来解决这个问题,在那里我们安装了与kafka交互的工具。 在我们的案例柱塞