apache-kafka - 如何在 Kubernetes 中向外部公开 StatefulSet 的 headless Kafka 服务

标签 apache-kafka kubernetes

使用kubernetes-kafka作为 minikube 的起点。

这使用了 StatefulSet 和 headless service用于集群内的服务发现。

目标是向外部公开各个 Kafka Brokers,其内部地址如下:

kafka-0.broker.kafka.svc.cluster.local:9092
kafka-1.broker.kafka.svc.cluster.local:9092 
kafka-2.broker.kafka.svc.cluster.local:9092

限制是该外部服务能够专门针对代理。

解决这个问题的正确(或一种可能)方法是什么?是否可以根据 kafka-x.broker.kafka.svc.cluster.local:9092 公开外部服务?

最佳答案

我们在 1.7 中通过将 headless 服务更改为 Type=NodePort 并设置 externalTrafficPolicy=Local 解决了这个问题。这会绕过服务的内部负载平衡,并且只有当 Kafka Pod 位于该节点上时,发往该节点端口上特定节点的流量才会起作用。

apiVersion: v1
kind: Service
metadata:
  name: broker
spec:
  externalTrafficPolicy: Local
  ports:
  - nodePort: 30000
    port: 30000
    protocol: TCP
    targetPort: 9092
  selector:
    app: broker
  type: NodePort

例如,我们有两个节点nodeA和nodeB,nodeB正在运行一个kafka pod。 nodeA:30000 将无法连接,但 nodeB:30000 将连接到在 nodeB 上运行的 kafka pod。

https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typenodeport

请注意,这在 1.5 和 1.6 中也作为 Beta 注释提供,可以在此处找到有关功能可用性的更多信息:https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip

另请注意,虽然这将 kafka pod 绑定(bind)到特定的外部网络身份,但它并不能保证您的存储卷将绑定(bind)到该网络身份。如果您在 StatefulSet 中使用 VolumeClaimTemplates,那么您的卷将与 pod 绑定(bind),而 kafka 希望卷与网络身份绑定(bind)。

例如,如果 kafka-0 pod 重新启动并且 kafka-0 在 NodeC 而不是 NodeA 上出现,则 kafka-0 的 PVC(如果使用 VolumeClaimTemplates)具有用于 NodeA 的数据,并且在 kafka-0 上运行的代理将启动认为是nodeA而不是nodeC而拒绝请求。

为了解决这个问题,我们期待本地持久卷,但现在我们有一个用于 kafka StatefulSet 的 PVC,并且数据存储在该 PVC 上的 $NODENAME 下,以将卷数据绑定(bind)到特定节点。

https://github.com/kubernetes/features/issues/121 https://kubernetes.io/docs/concepts/storage/volumes/#local

关于apache-kafka - 如何在 Kubernetes 中向外部公开 StatefulSet 的 headless Kafka 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46456239/

相关文章:

apache-kafka - 当存储值是 Avro SpecificRecord 时,KafkaStreamsStateStore 不工作

azure - 容器环境变量发生变化时如何强制重启pod

kubernetes - Kubernetes local/csi PV 内容是否同步到新节点?

azure - 从 Terraform 中的 map 列表中输出特定值

kubernetes - 如何在kubernetes集群中将微服务与NATS docker镜像连接

Kubernetes : configuring custom influxdb sink for heapster running in kube-system namespace on GKE

java - 如何根据主题动态应用预定的kafka消费者?

apache-kafka - 在 Kafka HA 中,为什么需要的最少代理数量是 3 而不是 2

scala - 在 Spark Streaming 中重用 kafka producer

apache-kafka - 主题分区是否应该在 Kafka 集群中的所有代理节点之间复制?